Merge to upstream r222492.

Change-Id: I6a0a6e90d217a69531ec3bb5ca0a367f39f4a1da
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 27a26f8..f12c525 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -84,104 +84,20 @@
   )
 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++)
-  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 ()
+# Declare libc++ configuration variables.
+# They are intended for use as follows:
+# LIBCXX_CXX_FLAGS: General flags for both the compiler and linker.
+# LIBCXX_COMPILE_FLAGS: Compile only flags.
+# LIBCXX_LINK_FLAGS: Linker only flags.
+set(LIBCXX_CXX_FLAGS "")
+set(LIBCXX_COMPILE_FLAGS "")
+set(LIBCXX_LINK_FLAGS "")
 
 # Configure compiler.
 include(config-ix)
+# Configure ABI library
+include(HandleLibCXXABI)
 
 #===============================================================================
 # Setup Compiler Flags
@@ -195,8 +111,9 @@
   # headers.
 else()
   if (LIBCXX_HAS_NOSTDINCXX_FLAG)
-    list(APPEND LIBCXX_CXX_REQUIRED_FLAGS -nostdinc++)
+    list(APPEND LIBCXX_COMPILE_FLAGS -nostdinc++)
     string(REPLACE "-stdlib=libc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+    string(REPLACE "-stdlib=libstdc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
   endif()
   # If c++1y has been enabled then attempt to use it. Fail if it is no supported
   # by the compiler. Otherwise choose c++11 and ensure the compiler supports it.
@@ -214,7 +131,7 @@
     endif()
   endif()
   # LIBCXX_STD_VERSION should always be set at this point.
-  list(APPEND LIBCXX_CXX_REQUIRED_FLAGS "-std=${LIBCXX_STD_VERSION}")
+  list(APPEND LIBCXX_CXX_FLAGS "-std=${LIBCXX_STD_VERSION}")
 endif()
 
 macro(append_if list condition var)
@@ -225,23 +142,23 @@
 
 # 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)
+  append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WALL_FLAG -Wall)
+  list(APPEND LIBCXX_COMPILE_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)
+append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_W_FLAG -W)
+append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG -Wno-unused-parameter)
+append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings)
+append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WNO_LONG_LONG_FLAG -Wno-long-long)
 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)
+  append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WERROR_FLAG -Werror)
+  append_if(LIBCXX_COMPILE_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-)
+  append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WNO_ERROR_FLAG -Wno-error)
+  append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_NO_WX_FLAG -WX-)
 endif()
 if (LIBCXX_ENABLE_PEDANTIC)
-  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_PEDANTIC_FLAG -pedantic)
+  append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_PEDANTIC_FLAG -pedantic)
 endif()
 
 # Get feature flags.
@@ -249,39 +166,39 @@
 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)
+  append_if(LIBCXX_CXX_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)
+  list(APPEND LIBCXX_CXX_FLAGS -D_LIBCPP_NO_EXCEPTIONS)
+  append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_NO_EHS_FLAG -EHs-)
+  append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_NO_EHA_FLAG -EHa-)
+  append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions)
 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)
+  list(APPEND LIBCXX_CXX_FLAGS -D_LIBCPP_NO_RTTI)
+  append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_NO_GR_FLAG -GR-)
+  append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_FNO_RTTI_FLAG -fno-rtti)
 endif()
 # Assert
 string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
 if (LIBCXX_ENABLE_ASSERTIONS)
   # MSVC doesn't like _DEBUG on release builds. See PR 4379.
   if (NOT MSVC)
-    list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_DEBUG)
+    list(APPEND LIBCXX_COMPILE_FLAGS -D_DEBUG)
   endif()
   # On Release builds cmake automatically defines NDEBUG, so we
   # explicitly undefine it:
   if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
-    list(APPEND LIBCXX_CXX_FEATURE_FLAGS -UNDEBUG)
+    list(APPEND LIBCXX_COMPILE_FLAGS -UNDEBUG)
   endif()
 else()
   if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
-    list(APPEND LIBCXX_CXX_FEATURE_FLAGS -DNDEBUG)
+    list(APPEND LIBCXX_COMPILE_FLAGS -DNDEBUG)
   endif()
 endif()
 # Static library
 if (NOT LIBCXX_ENABLE_SHARED)
-  list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_BUILD_STATIC)
+  list(APPEND LIBCXX_COMPILE_FLAGS -D_LIBCPP_BUILD_STATIC)
 endif()
 
 # This is the _ONLY_ place where add_definitions is called.
@@ -295,15 +212,25 @@
   # NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC.
   # But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do.
   if (LLVM_USE_SANITIZER AND NOT MSVC)
-    append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_NO_OMIT_FRAME_POINTER_FLAG
-            "-fno-omit-frame-pointer")
+    append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_FNO_OMIT_FRAME_POINTER_FLAG
+              "-fno-omit-frame-pointer")
+    if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND
+        NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO")
+      append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_GLINE_TABLES_ONLY_FLAG
+                "-gline-tables-only")
+    endif()
     if (LLVM_USE_SANITIZER STREQUAL "Address")
-      list(APPEND LIBCXX_CXX_FEATURE_FLAGS "-fsanitize=address")
+      list(APPEND LIBCXX_CXX_FLAGS "-fsanitize=address")
     elseif (LLVM_USE_SANITIZER MATCHES "Memory(WithOrigins)?")
-      list(APPEND LIBCXX_CXX_FEATURE_FLAGS "-fsanitize=memory")
+      list(APPEND LIBCXX_CXX_FLAGS "-fsanitize=memory")
       if (LLVM_USE_SANITIZER STREQUAL "MemoryWithOrigins")
-        list(APPEND LIBCXX_CXX_FEATURE_FLAGS "-fsanitize-memory-track-origins")
+        list(APPEND LIBCXX_CXX_FLAGS "-fsanitize-memory-track-origins")
       endif()
+    elseif (LLVM_USE_SANITIZER STREQUAL "Undefined")
+      list(APPEND LIBCXX_CXX_FLAGS
+          "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover")
+    elseif (LLVM_USE_SANITIZER STREQUAL "Thread")
+      list(APPEND LIBCXX_CXX_FLAGS "-fsanitize=thread")
     else()
       message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
     endif()
@@ -312,14 +239,8 @@
   endif()
 endif()
 
-string(REPLACE ";" " " LIBCXX_CXX_REQUIRED_FLAGS "${LIBCXX_CXX_REQUIRED_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_REQUIRED_FLAGS}")
-
-string(REPLACE ";" " " LIBCXX_CXX_WARNING_FLAGS "${LIBCXX_CXX_WARNING_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_WARNING_FLAGS}")
-
-string(REPLACE ";" " " LIBCXX_CXX_FEATURE_FLAGS "${LIBCXX_CXX_FEATURE_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_FEATURE_FLAGS}")
+string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_FLAGS}")
 
 #===============================================================================
 # Setup Source Code
diff --git a/cmake/Modules/HandleLibCXXABI.cmake b/cmake/Modules/HandleLibCXXABI.cmake
new file mode 100644
index 0000000..4d2a869
--- /dev/null
+++ b/cmake/Modules/HandleLibCXXABI.cmake
@@ -0,0 +1,98 @@
+
+#===============================================================================
+# 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
+#   abilib    : The 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 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 abilib abifiles abidirs)
+  list(APPEND LIBCXX_COMPILE_FLAGS ${abidefines})
+  set(${abipathvar} "${${abipathvar}}"
+    CACHE PATH
+    "Paths to C++ ABI header directories separated by ';'." FORCE
+    )
+
+  set(LIBCXX_CXX_ABI_LIBRARY ${abilib})
+
+  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}"
+          )
+        install(FILES "${CMAKE_BINARY_DIR}/include/${fpath}"
+          DESTINATION include/c++/v1/${dstdir}
+          PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+          )
+        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")
+
+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++)
+  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 ()
\ No newline at end of file
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 2596787..428d737 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -5,7 +5,7 @@
 check_cxx_compiler_flag(-std=c++11              LIBCXX_HAS_STDCXX11_FLAG)
 check_cxx_compiler_flag(-std=c++1y              LIBCXX_HAS_STDCXX1Y_FLAG)
 check_cxx_compiler_flag(-fPIC                   LIBCXX_HAS_FPIC_FLAG)
-check_cxx_compiler_flag(-fno-omit-frame-pointer LIBCXX_HAS_NO_OMIT_FRAME_POINTER_FLAG)
+check_cxx_compiler_flag(-fno-omit-frame-pointer LIBCXX_HAS_FNO_OMIT_FRAME_POINTER_FLAG)
 check_cxx_compiler_flag(-nodefaultlibs          LIBCXX_HAS_NODEFAULTLIBS_FLAG)
 check_cxx_compiler_flag(-nostdinc++             LIBCXX_HAS_NOSTDINCXX_FLAG)
 check_cxx_compiler_flag(-Wall                   LIBCXX_HAS_WALL_FLAG)
@@ -18,6 +18,7 @@
 check_cxx_compiler_flag(-Wno-error              LIBCXX_HAS_WNO_ERROR_FLAG)
 check_cxx_compiler_flag(-fno-exceptions         LIBCXX_HAS_FNO_EXCEPTIONS_FLAG)
 check_cxx_compiler_flag(-fno-rtti               LIBCXX_HAS_FNO_RTTI_FLAG)
+check_cxx_compiler_flag(-gline-tables-only      LIBCXX_HAS_GLINE_TABLES_ONLY_FLAG)
 check_cxx_compiler_flag(/WX                     LIBCXX_HAS_WX_FLAG)
 check_cxx_compiler_flag(/WX-                    LIBCXX_HAS_NO_WX_FLAG)
 check_cxx_compiler_flag(/EHsc                   LIBCXX_HAS_EHSC_FLAG)
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index bbf7ea4..df2cd34 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -1,13 +1,22 @@
 if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
   set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE)
 endif()
-
-install(DIRECTORY .
-  DESTINATION include/c++/v1
-  FILES_MATCHING
+set(LIBCXX_HEADER_PATTERN
   PATTERN "*"
   PATTERN "CMakeLists.txt" EXCLUDE
   PATTERN ".svn" EXCLUDE
   ${LIBCXX_SUPPORT_HEADER_PATTERN}
+  )
+
+file(COPY .
+  DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1"
+  FILES_MATCHING
+  ${LIBCXX_HEADER_PATTERN}
+  )
+
+install(DIRECTORY .
+  DESTINATION include/c++/v1
+  FILES_MATCHING
+  ${LIBCXX_HEADER_PATTERN}
   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
   )
diff --git a/include/__config b/include/__config
index a441bcc..d34bb7c 100644
--- a/include/__config
+++ b/include/__config
@@ -19,6 +19,11 @@
 #define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
 #endif
 
+#if !_WIN32
+#include <unistd.h>
+#include <errno.h>  // for ELAST on FreeBSD
+#endif
+
 #define _LIBCPP_VERSION 1101
 
 #define _LIBCPP_ABI_VERSION 1
@@ -221,7 +226,8 @@
 #endif
 
 #if __cplusplus < 201103L
-#define _LIBCPP_HAS_NO_UNICODE_CHARS
+typedef __char16_t char16_t;
+typedef __char32_t char32_t;
 #endif
 
 #if !(__has_feature(cxx_exceptions))
@@ -603,7 +609,7 @@
 #endif
 
 #ifndef _LIBCPP_EXTERN_TEMPLATE
-#define _LIBCPP_EXTERN_TEMPLATE(...)
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
 #endif
 
 #ifndef _LIBCPP_EXTERN_TEMPLATE2
@@ -630,6 +636,19 @@
 #define _LIBCPP_WCTYPE_IS_MASK
 #endif
 
+#if defined(ELAST)
+#define _LIBCPP_ELAST ELAST
+#elif defined(__linux__)
+#define _LIBCPP_ELAST 4095
+#elif defined(_NEWLIB_VERSION)
+#define _LIBCPP_ELAST __ELASTERROR
+#elif defined(__APPLE__)
+// Not _LIBCPP_ELAST needed on Apple
+#else
+// Warn here so that the person doing the libcxx port has an easier time:
+#warning This platform's ELAST hasn't been ported yet
+#endif
+
 #ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
 #  define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1
 #endif
diff --git a/include/__debug b/include/__debug
index f1805ad..c151224 100644
--- a/include/__debug
+++ b/include/__debug
@@ -11,19 +11,23 @@
 #ifndef _LIBCPP_DEBUG_H
 #define _LIBCPP_DEBUG_H
 
+#include <__config>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
 
 #if _LIBCPP_DEBUG_LEVEL >= 1
-
 #   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)
 #endif
 
 #if _LIBCPP_DEBUG_LEVEL >= 2
diff --git a/include/__hash_table b/include/__hash_table
index 4c4feb0..7c954b6 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -20,11 +20,7 @@
 
 #include <__undef_min_max>
 
-#ifdef _LIBCPP_DEBUG
-#   include <__debug>
-#else
-#   define _LIBCPP_ASSERT(x, m) ((void)0)
-#endif
+#include <__debug>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
diff --git a/include/__mutex_base b/include/__mutex_base
index 293fead..d5ece7c 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -22,6 +22,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 class _LIBCPP_TYPE_VIS mutex
 {
     pthread_mutex_t __m_;
@@ -315,6 +317,7 @@
     void __do_timed_wait(unique_lock<mutex>& __lk,
        chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
 };
+#endif // !_LIBCPP_HAS_NO_THREADS
 
 template <class _To, class _Rep, class _Period>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -332,6 +335,7 @@
     return __r;
 }
 
+#ifndef _LIBCPP_HAS_NO_THREADS
 template <class _Predicate>
 void
 condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
@@ -396,6 +400,8 @@
                       _VSTD::move(__pred));
 }
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP___MUTEX_BASE
diff --git a/include/__tuple b/include/__tuple
index ee5b916..bffb95c 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -245,19 +245,30 @@
 
 // __tuple_convertible
 
-template <bool, class _Tp, class _Up>
+template <class, class>
 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...> >
+struct __tuple_convertible_imp<__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> {};
+                               __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
 
 template <>
-struct __tuple_convertible_imp<true, __tuple_types<>, __tuple_types<> >
+struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> >
     : public true_type {};
 
+template <bool, class, class>
+struct __tuple_convertible_apply : public false_type {};
+
+template <class _Tp, class _Up>
+struct __tuple_convertible_apply<true, _Tp, _Up>
+  : public __tuple_convertible_imp<
+      typename __make_tuple_types<_Tp>::type
+    , typename __make_tuple_types<_Up>::type
+    >
+{};
+
 template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
                                 bool = __tuple_like<_Up>::value>
 struct __tuple_convertible
@@ -265,26 +276,36 @@
 
 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_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value ==
+                                     tuple_size<_Up>::value, _Tp, _Up>
 {};
 
 // __tuple_constructible
 
-template <bool, class _Tp, class _Up>
+template <class, class>
 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...> >
+struct __tuple_constructible_imp<__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> {};
+                               __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
 
 template <>
-struct __tuple_constructible_imp<true, __tuple_types<>, __tuple_types<> >
+struct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> >
     : public true_type {};
 
+template <bool _SameSize, class, class>
+struct __tuple_constructible_apply : public false_type {};
+
+template <class _Tp, class _Up>
+struct __tuple_constructible_apply<true, _Tp, _Up>
+  : public __tuple_constructible_imp<
+      typename __make_tuple_types<_Tp>::type
+    , typename __make_tuple_types<_Up>::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 +313,36 @@
 
 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_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value ==
+                                     tuple_size<_Up>::value, _Tp, _Up>
 {};
 
 // __tuple_assignable
 
-template <bool, class _Tp, class _Up>
+template <class, class>
 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...> >
+struct __tuple_assignable_imp<__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> {};
+                               __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
 
 template <>
-struct __tuple_assignable_imp<true, __tuple_types<>, __tuple_types<> >
+struct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> >
     : public true_type {};
 
+template <bool, class, class>
+struct __tuple_assignable_apply : public false_type {};
+
+template <class _Tp, class _Up>
+struct __tuple_assignable_apply<true, _Tp, _Up>
+  : __tuple_assignable_imp<
+      typename __make_tuple_types<_Tp>::type
+    , typename __make_tuple_types<_Up>::type
+    >
+{};
+
 template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
                                 bool = __tuple_like<_Up>::value>
 struct __tuple_assignable
@@ -319,9 +350,8 @@
 
 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_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value ==
+                                    tuple_size<_Up>::value, _Tp, _Up>
 {};
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/include/algorithm b/include/algorithm
index 1fed6e9..02cbc81 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -638,6 +638,8 @@
 
 #include <__undef_min_max>
 
+#include <__debug>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -975,7 +977,7 @@
 }
 
 template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-_RandomAccessIterator1
+_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)
@@ -1041,8 +1043,8 @@
 // find_first_of
 
 template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
-_ForwardIterator1
-find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1
+__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
               _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
 {
     for (; __first1 != __last1; ++__first1)
@@ -1052,6 +1054,16 @@
     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
@@ -1060,7 +1072,7 @@
 {
     typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
     typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
-    return _VSTD::find_first_of(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+    return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
 }
 
 // adjacent_find
@@ -1128,7 +1140,7 @@
 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
          _InputIterator2 __first2, _BinaryPredicate __pred)
 {
-    for (; __first1 != __last1; ++__first1, ++__first2)
+    for (; __first1 != __last1; ++__first1, (void) ++__first2)
         if (!__pred(*__first1, *__first2))
             break;
     return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
@@ -1152,7 +1164,7 @@
          _InputIterator2 __first2, _InputIterator2 __last2,
          _BinaryPredicate __pred)
 {
-    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)
         if (!__pred(*__first1, *__first2))
             break;
     return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
@@ -1177,7 +1189,7 @@
 bool
 equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred)
 {
-    for (; __first1 != __last1; ++__first1, ++__first2)
+    for (; __first1 != __last1; ++__first1, (void) ++__first2)
         if (!__pred(*__first1, *__first2))
             return false;
     return true;
@@ -1201,7 +1213,7 @@
         _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred,
         input_iterator_tag, input_iterator_tag )
 {
-    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)
         if (!__pred(*__first1, *__first2))
             return false;
     return __first1 == __last1 && __first2 == __last2;
@@ -1255,7 +1267,7 @@
                _ForwardIterator2 __first2, _BinaryPredicate __pred)
 {
     // shorten sequences as much as possible by lopping of any equal parts
-    for (; __first1 != __last1; ++__first1, ++__first2)
+    for (; __first1 != __last1; ++__first1, (void) ++__first2)
         if (!__pred(*__first1, *__first2))
             goto __not_done;
     return true;
@@ -1315,7 +1327,7 @@
                  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)
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void) ++__first2)
         if (!__pred(*__first1, *__first2))
             goto __not_done;
     return __first1 == __last1 && __first2 == __last2;
@@ -1440,7 +1452,7 @@
 }
 
 template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
-_RandomAccessIterator1
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1
 __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
            _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
            random_access_iterator_tag, random_access_iterator_tag)
@@ -1733,7 +1745,7 @@
 _OutputIterator
 __copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
-    for (; __first != __last; ++__first, ++__result)
+    for (; __first != __last; ++__first, (void) ++__result)
         *__result = *__first;
     return __result;
 }
@@ -1862,7 +1874,7 @@
 _OutputIterator
 __move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
 {
-    for (; __first != __last; ++__first, ++__result)
+    for (; __first != __last; ++__first, (void) ++__result)
         *__result = _VSTD::move(*__first);
     return __result;
 }
@@ -1938,7 +1950,7 @@
 _OutputIterator
 transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
 {
-    for (; __first != __last; ++__first, ++__result)
+    for (; __first != __last; ++__first, (void) ++__result)
         *__result = __op(*__first);
     return __result;
 }
@@ -1949,7 +1961,7 @@
 transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
           _OutputIterator __result, _BinaryOperation __binary_op)
 {
-    for (; __first1 != __last1; ++__first1, ++__first2, ++__result)
+    for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result)
         *__result = __binary_op(*__first1, *__first2);
     return __result;
 }
@@ -1986,7 +1998,7 @@
 replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
              const _Tp& __old_value, const _Tp& __new_value)
 {
-    for (; __first != __last; ++__first, ++__result)
+    for (; __first != __last; ++__first, (void) ++__result)
         if (*__first == __old_value)
             *__result = __new_value;
         else
@@ -2002,7 +2014,7 @@
 replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
                 _Predicate __pred, const _Tp& __new_value)
 {
-    for (; __first != __last; ++__first, ++__result)
+    for (; __first != __last; ++__first, (void) ++__result)
         if (__pred(*__first))
             *__result = __new_value;
         else
@@ -2017,7 +2029,7 @@
 _OutputIterator
 __fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
 {
-    for (; __n > 0; ++__first, --__n)
+    for (; __n > 0; ++__first, (void) --__n)
         *__first = __value_;
     return __first;
 }
@@ -2091,7 +2103,7 @@
 _OutputIterator
 generate_n(_OutputIterator __first, _Size __n, _Generator __gen)
 {
-    for (; __n > 0; ++__first, --__n)
+    for (; __n > 0; ++__first, (void) --__n)
         *__first = __gen();
     return __first;
 }
@@ -4360,7 +4372,7 @@
     if (__len1 <= __len2)
     {
         value_type* __p = __buff;
-        for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), ++__i, ++__p)
+        for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p)
             ::new(__p) value_type(_VSTD::move(*__i));
         __merge<_Compare>(move_iterator<value_type*>(__buff),
                           move_iterator<value_type*>(__p),
@@ -4371,7 +4383,7 @@
     else
     {
         value_type* __p = __buff;
-        for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), ++__i, ++__p)
+        for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), (void) ++__i, ++__p)
             ::new(__p) value_type(_VSTD::move(*__i));
         typedef reverse_iterator<_BidirectionalIterator> _RBi;
         typedef reverse_iterator<value_type*> _Rv;
@@ -4396,7 +4408,7 @@
         if (__len2 == 0)
             return;
         // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
-        for (; true; ++__first, --__len1)
+        for (; true; ++__first, (void) --__len1)
         {
             if (__len1 == 0)
                 return;
@@ -5055,7 +5067,7 @@
     _RandomAccessIterator __r = __result_first;
     if (__r != __result_last)
     {
-        for (; __first != __last && __r != __result_last; ++__first, ++__r)
+        for (; __first != __last && __r != __result_last; (void) ++__first, ++__r)
             *__r = *__first;
         __make_heap<_Compare>(__result_first, __r, __comp);
         typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
@@ -5577,7 +5589,7 @@
 __lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
                           _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
 {
-    for (; __first2 != __last2; ++__first1, ++__first2)
+    for (; __first2 != __last2; ++__first1, (void) ++__first2)
     {
         if (__first1 == __last1 || __comp(*__first1, *__first2))
             return true;
diff --git a/include/atomic b/include/atomic
index 91f1829..b01a59f 100644
--- a/include/atomic
+++ b/include/atomic
@@ -533,6 +533,10 @@
 #pragma GCC system_header
 #endif
 
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error <atomic> is not supported on this single threaded system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if !__has_feature(cxx_atomic) && _GNUC_VER < 407
@@ -1779,4 +1783,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif  // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_ATOMIC
diff --git a/include/chrono b/include/chrono
index 2c65eee..9229234 100644
--- a/include/chrono
+++ b/include/chrono
@@ -926,6 +926,7 @@
     static time_point from_time_t(time_t __t) _NOEXCEPT;
 };
 
+#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
 class _LIBCPP_TYPE_VIS steady_clock
 {
 public:
@@ -939,6 +940,9 @@
 };
 
 typedef steady_clock high_resolution_clock;
+#else
+typedef system_clock high_resolution_clock;
+#endif
 
 } // chrono
 
diff --git a/include/cmath b/include/cmath
index 964c672..d3aa4be 100644
--- a/include/cmath
+++ b/include/cmath
@@ -316,9 +316,9 @@
 template <class _A1>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_signbit(_A1 __x) _NOEXCEPT
+__libcpp_signbit(_A1 __lcpp_x) _NOEXCEPT
 {
-    return signbit(__x);
+    return signbit(__lcpp_x);
 }
 
 #undef signbit
@@ -326,9 +326,9 @@
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-signbit(_A1 __x) _NOEXCEPT
+signbit(_A1 __lcpp_x) _NOEXCEPT
 {
-    return __libcpp_signbit((typename std::__promote<_A1>::type)__x);
+    return __libcpp_signbit((typename std::__promote<_A1>::type)__lcpp_x);
 }
 
 #endif  // signbit
@@ -340,9 +340,9 @@
 template <class _A1>
 _LIBCPP_ALWAYS_INLINE
 int
-__libcpp_fpclassify(_A1 __x) _NOEXCEPT
+__libcpp_fpclassify(_A1 __lcpp_x) _NOEXCEPT
 {
-    return fpclassify(__x);
+    return fpclassify(__lcpp_x);
 }
 
 #undef fpclassify
@@ -350,9 +350,9 @@
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename std::enable_if<std::is_arithmetic<_A1>::value, int>::type
-fpclassify(_A1 __x) _NOEXCEPT
+fpclassify(_A1 __lcpp_x) _NOEXCEPT
 {
-    return __libcpp_fpclassify((typename std::__promote<_A1>::type)__x);
+    return __libcpp_fpclassify((typename std::__promote<_A1>::type)__lcpp_x);
 }
 
 #endif  // fpclassify
@@ -364,9 +364,9 @@
 template <class _A1>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isfinite(_A1 __x) _NOEXCEPT
+__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT
 {
-    return isfinite(__x);
+    return isfinite(__lcpp_x);
 }
 
 #undef isfinite
@@ -374,9 +374,9 @@
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isfinite(_A1 __x) _NOEXCEPT
+isfinite(_A1 __lcpp_x) _NOEXCEPT
 {
-    return __libcpp_isfinite((typename std::__promote<_A1>::type)__x);
+    return __libcpp_isfinite((typename std::__promote<_A1>::type)__lcpp_x);
 }
 
 #endif  // isfinite
@@ -388,9 +388,9 @@
 template <class _A1>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isinf(_A1 __x) _NOEXCEPT
+__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT
 {
-    return isinf(__x);
+    return isinf(__lcpp_x);
 }
 
 #undef isinf
@@ -398,9 +398,9 @@
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isinf(_A1 __x) _NOEXCEPT
+isinf(_A1 __lcpp_x) _NOEXCEPT
 {
-    return __libcpp_isinf((typename std::__promote<_A1>::type)__x);
+    return __libcpp_isinf((typename std::__promote<_A1>::type)__lcpp_x);
 }
 
 #endif  // isinf
@@ -412,9 +412,9 @@
 template <class _A1>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isnan(_A1 __x) _NOEXCEPT
+__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT
 {
-    return isnan(__x);
+    return isnan(__lcpp_x);
 }
 
 #undef isnan
@@ -422,9 +422,9 @@
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isnan(_A1 __x) _NOEXCEPT
+isnan(_A1 __lcpp_x) _NOEXCEPT
 {
-    return __libcpp_isnan((typename std::__promote<_A1>::type)__x);
+    return __libcpp_isnan((typename std::__promote<_A1>::type)__lcpp_x);
 }
 
 #endif  // isnan
@@ -436,9 +436,9 @@
 template <class _A1>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isnormal(_A1 __x) _NOEXCEPT
+__libcpp_isnormal(_A1 __lcpp_x) _NOEXCEPT
 {
-    return isnormal(__x);
+    return isnormal(__lcpp_x);
 }
 
 #undef isnormal
@@ -446,9 +446,9 @@
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
-isnormal(_A1 __x) _NOEXCEPT
+isnormal(_A1 __lcpp_x) _NOEXCEPT
 {
-    return __libcpp_isnormal((typename std::__promote<_A1>::type)__x);
+    return __libcpp_isnormal((typename std::__promote<_A1>::type)__lcpp_x);
 }
 
 #endif  // isnormal
@@ -460,9 +460,9 @@
 template <class _A1, class _A2>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isgreater(_A1 __x, _A2 __y) _NOEXCEPT
+__libcpp_isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
-    return isgreater(__x, __y);
+    return isgreater(__lcpp_x, __lcpp_y);
 }
 
 #undef isgreater
@@ -475,10 +475,10 @@
     std::is_arithmetic<_A2>::value,
     bool
 >::type
-isgreater(_A1 __x, _A2 __y) _NOEXCEPT
+isgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isgreater((type)__x, (type)__y);
+    return __libcpp_isgreater((type)__lcpp_x, (type)__lcpp_y);
 }
 
 #endif  // isgreater
@@ -490,9 +490,9 @@
 template <class _A1, class _A2>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT
+__libcpp_isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
-    return isgreaterequal(__x, __y);
+    return isgreaterequal(__lcpp_x, __lcpp_y);
 }
 
 #undef isgreaterequal
@@ -505,10 +505,10 @@
     std::is_arithmetic<_A2>::value,
     bool
 >::type
-isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT
+isgreaterequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isgreaterequal((type)__x, (type)__y);
+    return __libcpp_isgreaterequal((type)__lcpp_x, (type)__lcpp_y);
 }
 
 #endif  // isgreaterequal
@@ -520,9 +520,9 @@
 template <class _A1, class _A2>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isless(_A1 __x, _A2 __y) _NOEXCEPT
+__libcpp_isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
-    return isless(__x, __y);
+    return isless(__lcpp_x, __lcpp_y);
 }
 
 #undef isless
@@ -535,10 +535,10 @@
     std::is_arithmetic<_A2>::value,
     bool
 >::type
-isless(_A1 __x, _A2 __y) _NOEXCEPT
+isless(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isless((type)__x, (type)__y);
+    return __libcpp_isless((type)__lcpp_x, (type)__lcpp_y);
 }
 
 #endif  // isless
@@ -550,9 +550,9 @@
 template <class _A1, class _A2>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_islessequal(_A1 __x, _A2 __y) _NOEXCEPT
+__libcpp_islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
-    return islessequal(__x, __y);
+    return islessequal(__lcpp_x, __lcpp_y);
 }
 
 #undef islessequal
@@ -565,10 +565,10 @@
     std::is_arithmetic<_A2>::value,
     bool
 >::type
-islessequal(_A1 __x, _A2 __y) _NOEXCEPT
+islessequal(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_islessequal((type)__x, (type)__y);
+    return __libcpp_islessequal((type)__lcpp_x, (type)__lcpp_y);
 }
 
 #endif  // islessequal
@@ -580,9 +580,9 @@
 template <class _A1, class _A2>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_islessgreater(_A1 __x, _A2 __y) _NOEXCEPT
+__libcpp_islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
-    return islessgreater(__x, __y);
+    return islessgreater(__lcpp_x, __lcpp_y);
 }
 
 #undef islessgreater
@@ -595,10 +595,10 @@
     std::is_arithmetic<_A2>::value,
     bool
 >::type
-islessgreater(_A1 __x, _A2 __y) _NOEXCEPT
+islessgreater(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_islessgreater((type)__x, (type)__y);
+    return __libcpp_islessgreater((type)__lcpp_x, (type)__lcpp_y);
 }
 
 #endif  // islessgreater
@@ -610,9 +610,9 @@
 template <class _A1, class _A2>
 _LIBCPP_ALWAYS_INLINE
 bool
-__libcpp_isunordered(_A1 __x, _A2 __y) _NOEXCEPT
+__libcpp_isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
-    return isunordered(__x, __y);
+    return isunordered(__lcpp_x, __lcpp_y);
 }
 
 #undef isunordered
@@ -625,10 +625,10 @@
     std::is_arithmetic<_A2>::value,
     bool
 >::type
-isunordered(_A1 __x, _A2 __y) _NOEXCEPT
+isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename std::__promote<_A1, _A2>::type type;
-    return __libcpp_isunordered((type)__x, (type)__y);
+    return __libcpp_isunordered((type)__lcpp_x, (type)__lcpp_y);
 }
 
 #endif  // isunordered
@@ -657,15 +657,15 @@
 #if !defined(_AIX)
 inline _LIBCPP_INLINE_VISIBILITY
 float
-abs(float __x) _NOEXCEPT {return fabsf(__x);}
+abs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);}
 
 inline _LIBCPP_INLINE_VISIBILITY
 double
-abs(double __x) _NOEXCEPT {return fabs(__x);}
+abs(double __lcpp_x) _NOEXCEPT {return fabs(__lcpp_x);}
 
 inline _LIBCPP_INLINE_VISIBILITY
 long double
-abs(long double __x) _NOEXCEPT {return fabsl(__x);}
+abs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}
 #endif // !defined(_AIX)
 
 #ifndef __sun__
@@ -676,14 +676,14 @@
 using ::acosf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       acos(float __x) _NOEXCEPT       {return acosf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __x) _NOEXCEPT {return acosl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       acos(float __lcpp_x) _NOEXCEPT       {return acosf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __lcpp_x) _NOEXCEPT {return acosl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-acos(_A1 __x) _NOEXCEPT {return acos((double)__x);}
+acos(_A1 __lcpp_x) _NOEXCEPT {return acos((double)__lcpp_x);}
 
 // asin
 
@@ -691,14 +691,14 @@
 using ::asinf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       asin(float __x) _NOEXCEPT       {return asinf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __x) _NOEXCEPT {return asinl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       asin(float __lcpp_x) _NOEXCEPT       {return asinf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __lcpp_x) _NOEXCEPT {return asinl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-asin(_A1 __x) _NOEXCEPT {return asin((double)__x);}
+asin(_A1 __lcpp_x) _NOEXCEPT {return asin((double)__lcpp_x);}
 
 // atan
 
@@ -706,14 +706,14 @@
 using ::atanf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       atan(float __x) _NOEXCEPT       {return atanf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __x) _NOEXCEPT {return atanl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       atan(float __lcpp_x) _NOEXCEPT       {return atanf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __lcpp_x) _NOEXCEPT {return atanl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-atan(_A1 __x) _NOEXCEPT {return atan((double)__x);}
+atan(_A1 __lcpp_x) _NOEXCEPT {return atan((double)__lcpp_x);}
 
 // atan2
 
@@ -721,24 +721,24 @@
 using ::atan2f;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       atan2(float __y, float __x) _NOEXCEPT             {return atan2f(__y, __x);}
-inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __y, long double __x) _NOEXCEPT {return atan2l(__y, __x);}
+inline _LIBCPP_INLINE_VISIBILITY float       atan2(float __lcpp_y, float __lcpp_x) _NOEXCEPT             {return atan2f(__lcpp_y, __lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long double __lcpp_x) _NOEXCEPT {return atan2l(__lcpp_y, __lcpp_x);}
 #endif
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-atan2(_A1 __y, _A2 __x) _NOEXCEPT
+atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return atan2((__result_type)__y, (__result_type)__x);
+    return atan2((__result_type)__lcpp_y, (__result_type)__lcpp_x);
 }
 
 // ceil
@@ -747,14 +747,14 @@
 using ::ceilf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       ceil(float __x) _NOEXCEPT       {return ceilf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __x) _NOEXCEPT {return ceill(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       ceil(float __lcpp_x) _NOEXCEPT       {return ceilf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __lcpp_x) _NOEXCEPT {return ceill(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-ceil(_A1 __x) _NOEXCEPT {return ceil((double)__x);}
+ceil(_A1 __lcpp_x) _NOEXCEPT {return ceil((double)__lcpp_x);}
 
 // cos
 
@@ -762,14 +762,14 @@
 using ::cosf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       cos(float __x) _NOEXCEPT       {return cosf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __x) _NOEXCEPT {return cosl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       cos(float __lcpp_x) _NOEXCEPT       {return cosf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __lcpp_x) _NOEXCEPT {return cosl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-cos(_A1 __x) _NOEXCEPT {return cos((double)__x);}
+cos(_A1 __lcpp_x) _NOEXCEPT {return cos((double)__lcpp_x);}
 
 // cosh
 
@@ -777,14 +777,14 @@
 using ::coshf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       cosh(float __x) _NOEXCEPT       {return coshf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __x) _NOEXCEPT {return coshl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       cosh(float __lcpp_x) _NOEXCEPT       {return coshf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __lcpp_x) _NOEXCEPT {return coshl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-cosh(_A1 __x) _NOEXCEPT {return cosh((double)__x);}
+cosh(_A1 __lcpp_x) _NOEXCEPT {return cosh((double)__lcpp_x);}
 
 #endif // __sun__
 // exp
@@ -795,15 +795,15 @@
 #ifndef __sun__
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       exp(float __x) _NOEXCEPT       {return expf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __x) _NOEXCEPT {return expl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       exp(float __lcpp_x) _NOEXCEPT       {return expf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __lcpp_x) _NOEXCEPT {return expl(__lcpp_x);}
 #endif
 
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-exp(_A1 __x) _NOEXCEPT {return exp((double)__x);}
+exp(_A1 __lcpp_x) _NOEXCEPT {return exp((double)__lcpp_x);}
 
 // fabs
 
@@ -811,14 +811,14 @@
 using ::fabsf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       fabs(float __x) _NOEXCEPT       {return fabsf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __x) _NOEXCEPT {return fabsl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       fabs(float __lcpp_x) _NOEXCEPT       {return fabsf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-fabs(_A1 __x) _NOEXCEPT {return fabs((double)__x);}
+fabs(_A1 __lcpp_x) _NOEXCEPT {return fabs((double)__lcpp_x);}
 
 // floor
 
@@ -826,14 +826,14 @@
 using ::floorf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       floor(float __x) _NOEXCEPT       {return floorf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __x) _NOEXCEPT {return floorl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       floor(float __lcpp_x) _NOEXCEPT       {return floorf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __lcpp_x) _NOEXCEPT {return floorl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-floor(_A1 __x) _NOEXCEPT {return floor((double)__x);}
+floor(_A1 __lcpp_x) _NOEXCEPT {return floor((double)__lcpp_x);}
 
 // fmod
 
@@ -843,24 +843,24 @@
 #ifndef __sun__
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       fmod(float __x, float __y) _NOEXCEPT             {return fmodf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __x, long double __y) _NOEXCEPT {return fmodl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       fmod(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmodf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmodl(__lcpp_x, __lcpp_y);}
 #endif
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-fmod(_A1 __x, _A2 __y) _NOEXCEPT
+fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return fmod((__result_type)__x, (__result_type)__y);
+    return fmod((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 
@@ -870,14 +870,14 @@
 using ::frexpf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       frexp(float __x, int* __e) _NOEXCEPT       {return frexpf(__x, __e);}
-inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __x, int* __e) _NOEXCEPT {return frexpl(__x, __e);}
+inline _LIBCPP_INLINE_VISIBILITY float       frexp(float __lcpp_x, int* __lcpp_e) _NOEXCEPT       {return frexpf(__lcpp_x, __lcpp_e);}
+inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpl(__lcpp_x, __lcpp_e);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-frexp(_A1 __x, int* __e) _NOEXCEPT {return frexp((double)__x, __e);}
+frexp(_A1 __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexp((double)__lcpp_x, __lcpp_e);}
 
 // ldexp
 
@@ -885,14 +885,14 @@
 using ::ldexpf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       ldexp(float __x, int __e) _NOEXCEPT       {return ldexpf(__x, __e);}
-inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __x, int __e) _NOEXCEPT {return ldexpl(__x, __e);}
+inline _LIBCPP_INLINE_VISIBILITY float       ldexp(float __lcpp_x, int __lcpp_e) _NOEXCEPT       {return ldexpf(__lcpp_x, __lcpp_e);}
+inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpl(__lcpp_x, __lcpp_e);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-ldexp(_A1 __x, int __e) _NOEXCEPT {return ldexp((double)__x, __e);}
+ldexp(_A1 __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexp((double)__lcpp_x, __lcpp_e);}
 
 // log
 
@@ -902,14 +902,14 @@
 #ifndef __sun__
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       log(float __x) _NOEXCEPT       {return logf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log(long double __x) _NOEXCEPT {return logl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       log(float __lcpp_x) _NOEXCEPT       {return logf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log(long double __lcpp_x) _NOEXCEPT {return logl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-log(_A1 __x) _NOEXCEPT {return log((double)__x);}
+log(_A1 __lcpp_x) _NOEXCEPT {return log((double)__lcpp_x);}
 
 
 // log10
@@ -918,14 +918,14 @@
 using ::log10f;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       log10(float __x) _NOEXCEPT       {return log10f(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __x) _NOEXCEPT {return log10l(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       log10(float __lcpp_x) _NOEXCEPT       {return log10f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __lcpp_x) _NOEXCEPT {return log10l(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-log10(_A1 __x) _NOEXCEPT {return log10((double)__x);}
+log10(_A1 __lcpp_x) _NOEXCEPT {return log10((double)__lcpp_x);}
 
 // modf
 
@@ -933,8 +933,8 @@
 using ::modff;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       modf(float __x, float* __y) _NOEXCEPT             {return modff(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __x, long double* __y) _NOEXCEPT {return modfl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       modf(float __lcpp_x, float* __lcpp_y) _NOEXCEPT             {return modff(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __lcpp_x, long double* __lcpp_y) _NOEXCEPT {return modfl(__lcpp_x, __lcpp_y);}
 #endif
 
 // pow
@@ -946,24 +946,24 @@
 #ifndef __sun__
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       pow(float __x, float __y) _NOEXCEPT             {return powf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __x, long double __y) _NOEXCEPT {return powl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       pow(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return powf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return powl(__lcpp_x, __lcpp_y);}
 #endif
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-pow(_A1 __x, _A2 __y) _NOEXCEPT
+pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return pow((__result_type)__x, (__result_type)__y);
+    return pow((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 // sin
@@ -972,14 +972,14 @@
 using ::sinf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       sin(float __x) _NOEXCEPT       {return sinf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __x) _NOEXCEPT {return sinl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       sin(float __lcpp_x) _NOEXCEPT       {return sinf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __lcpp_x) _NOEXCEPT {return sinl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-sin(_A1 __x) _NOEXCEPT {return sin((double)__x);}
+sin(_A1 __lcpp_x) _NOEXCEPT {return sin((double)__lcpp_x);}
 
 // sinh
 
@@ -987,14 +987,14 @@
 using ::sinhf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       sinh(float __x) _NOEXCEPT       {return sinhf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __x) _NOEXCEPT {return sinhl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       sinh(float __lcpp_x) _NOEXCEPT       {return sinhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __lcpp_x) _NOEXCEPT {return sinhl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-sinh(_A1 __x) _NOEXCEPT {return sinh((double)__x);}
+sinh(_A1 __lcpp_x) _NOEXCEPT {return sinh((double)__lcpp_x);}
 
 // sqrt
 
@@ -1004,14 +1004,14 @@
 
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(__sun__) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       sqrt(float __x) _NOEXCEPT       {return sqrtf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __x) _NOEXCEPT {return sqrtl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       sqrt(float __lcpp_x) _NOEXCEPT       {return sqrtf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __lcpp_x) _NOEXCEPT {return sqrtl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-sqrt(_A1 __x) _NOEXCEPT {return sqrt((double)__x);}
+sqrt(_A1 __lcpp_x) _NOEXCEPT {return sqrt((double)__lcpp_x);}
 
 // tan
 
@@ -1020,14 +1020,14 @@
 #ifndef __sun__
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       tan(float __x) _NOEXCEPT       {return tanf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __x) _NOEXCEPT {return tanl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       tan(float __lcpp_x) _NOEXCEPT       {return tanf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __lcpp_x) _NOEXCEPT {return tanl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-tan(_A1 __x) _NOEXCEPT {return tan((double)__x);}
+tan(_A1 __lcpp_x) _NOEXCEPT {return tan((double)__lcpp_x);}
 
 // tanh
 
@@ -1035,14 +1035,14 @@
 using ::tanhf;
 
 #if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
-inline _LIBCPP_INLINE_VISIBILITY float       tanh(float __x) _NOEXCEPT       {return tanhf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __x) _NOEXCEPT {return tanhl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       tanh(float __lcpp_x) _NOEXCEPT       {return tanhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __lcpp_x) _NOEXCEPT {return tanhl(__lcpp_x);}
 #endif
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-tanh(_A1 __x) _NOEXCEPT {return tanh((double)__x);}
+tanh(_A1 __lcpp_x) _NOEXCEPT {return tanh((double)__lcpp_x);}
 
 // acosh
 
@@ -1050,13 +1050,13 @@
 using ::acosh;
 using ::acoshf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       acosh(float __x) _NOEXCEPT       {return acoshf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __x) _NOEXCEPT {return acoshl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       acosh(float __lcpp_x) _NOEXCEPT       {return acoshf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __lcpp_x) _NOEXCEPT {return acoshl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-acosh(_A1 __x) _NOEXCEPT {return acosh((double)__x);}
+acosh(_A1 __lcpp_x) _NOEXCEPT {return acosh((double)__lcpp_x);}
 #endif
 
 // asinh
@@ -1065,13 +1065,13 @@
 using ::asinh;
 using ::asinhf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       asinh(float __x) _NOEXCEPT       {return asinhf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __x) _NOEXCEPT {return asinhl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       asinh(float __lcpp_x) _NOEXCEPT       {return asinhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __lcpp_x) _NOEXCEPT {return asinhl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-asinh(_A1 __x) _NOEXCEPT {return asinh((double)__x);}
+asinh(_A1 __lcpp_x) _NOEXCEPT {return asinh((double)__lcpp_x);}
 #endif
 
 // atanh
@@ -1080,13 +1080,13 @@
 using ::atanh;
 using ::atanhf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       atanh(float __x) _NOEXCEPT       {return atanhf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __x) _NOEXCEPT {return atanhl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       atanh(float __lcpp_x) _NOEXCEPT       {return atanhf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __lcpp_x) _NOEXCEPT {return atanhl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-atanh(_A1 __x) _NOEXCEPT {return atanh((double)__x);}
+atanh(_A1 __lcpp_x) _NOEXCEPT {return atanh((double)__lcpp_x);}
 #endif
 
 // cbrt
@@ -1095,13 +1095,13 @@
 using ::cbrt;
 using ::cbrtf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       cbrt(float __x) _NOEXCEPT       {return cbrtf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __x) _NOEXCEPT {return cbrtl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       cbrt(float __lcpp_x) _NOEXCEPT       {return cbrtf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __lcpp_x) _NOEXCEPT {return cbrtl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-cbrt(_A1 __x) _NOEXCEPT {return cbrt((double)__x);}
+cbrt(_A1 __lcpp_x) _NOEXCEPT {return cbrt((double)__lcpp_x);}
 #endif
 
 // copysign
@@ -1109,23 +1109,23 @@
 using ::copysign;
 using ::copysignf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       copysign(float __x, float __y) _NOEXCEPT             {return copysignf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double copysign(long double __x, long double __y) _NOEXCEPT {return copysignl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       copysign(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return copysignf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double copysign(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return copysignl(__lcpp_x, __lcpp_y);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-copysign(_A1 __x, _A2 __y) _NOEXCEPT
+copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return copysign((__result_type)__x, (__result_type)__y);
+    return copysign((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 #ifndef _LIBCPP_MSVCRT
@@ -1135,75 +1135,75 @@
 using ::erf;
 using ::erff;
 
-inline _LIBCPP_INLINE_VISIBILITY float       erf(float __x) _NOEXCEPT       {return erff(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double erf(long double __x) _NOEXCEPT {return erfl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       erf(float __lcpp_x) _NOEXCEPT       {return erff(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double erf(long double __lcpp_x) _NOEXCEPT {return erfl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-erf(_A1 __x) _NOEXCEPT {return erf((double)__x);}
+erf(_A1 __lcpp_x) _NOEXCEPT {return erf((double)__lcpp_x);}
 
 // erfc
 
 using ::erfc;
 using ::erfcf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       erfc(float __x) _NOEXCEPT       {return erfcf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double erfc(long double __x) _NOEXCEPT {return erfcl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       erfc(float __lcpp_x) _NOEXCEPT       {return erfcf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double erfc(long double __lcpp_x) _NOEXCEPT {return erfcl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-erfc(_A1 __x) _NOEXCEPT {return erfc((double)__x);}
+erfc(_A1 __lcpp_x) _NOEXCEPT {return erfc((double)__lcpp_x);}
 
 // exp2
 
 using ::exp2;
 using ::exp2f;
 
-inline _LIBCPP_INLINE_VISIBILITY float       exp2(float __x) _NOEXCEPT       {return exp2f(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double exp2(long double __x) _NOEXCEPT {return exp2l(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       exp2(float __lcpp_x) _NOEXCEPT       {return exp2f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double exp2(long double __lcpp_x) _NOEXCEPT {return exp2l(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-exp2(_A1 __x) _NOEXCEPT {return exp2((double)__x);}
+exp2(_A1 __lcpp_x) _NOEXCEPT {return exp2((double)__lcpp_x);}
 
 // expm1
 
 using ::expm1;
 using ::expm1f;
 
-inline _LIBCPP_INLINE_VISIBILITY float       expm1(float __x) _NOEXCEPT       {return expm1f(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double expm1(long double __x) _NOEXCEPT {return expm1l(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       expm1(float __lcpp_x) _NOEXCEPT       {return expm1f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double expm1(long double __lcpp_x) _NOEXCEPT {return expm1l(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-expm1(_A1 __x) _NOEXCEPT {return expm1((double)__x);}
+expm1(_A1 __lcpp_x) _NOEXCEPT {return expm1((double)__lcpp_x);}
 
 // fdim
 
 using ::fdim;
 using ::fdimf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       fdim(float __x, float __y) _NOEXCEPT             {return fdimf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __x, long double __y) _NOEXCEPT {return fdiml(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       fdim(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fdimf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fdiml(__lcpp_x, __lcpp_y);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-fdim(_A1 __x, _A2 __y) _NOEXCEPT
+fdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return fdim((__result_type)__x, (__result_type)__y);
+    return fdim((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 // fma
@@ -1211,25 +1211,25 @@
 using ::fmaf;
 using ::fma;
 
-inline _LIBCPP_INLINE_VISIBILITY float       fma(float __x, float __y, float __z) _NOEXCEPT                   {return fmaf(__x, __y, __z);}
-inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __x, long double __y, long double __z) _NOEXCEPT {return fmal(__x, __y, __z);}
+inline _LIBCPP_INLINE_VISIBILITY float       fma(float __lcpp_x, float __lcpp_y, float __lcpp_z) _NOEXCEPT                   {return fmaf(__lcpp_x, __lcpp_y, __lcpp_z);}
+inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long double __lcpp_y, long double __lcpp_z) _NOEXCEPT {return fmal(__lcpp_x, __lcpp_y, __lcpp_z);}
 
 template <class _A1, class _A2, class _A3>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value &&
     is_arithmetic<_A3>::value,
-    typename __promote<_A1, _A2, _A3>::type
+    __promote<_A1, _A2, _A3>
 >::type
-fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT
+fma(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2, _A3>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value &&
                       is_same<_A3, __result_type>::value)), "");
-    return fma((__result_type)__x, (__result_type)__y, (__result_type)__z);
+    return fma((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z);
 }
 
 // fmax
@@ -1237,23 +1237,23 @@
 using ::fmax;
 using ::fmaxf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       fmax(float __x, float __y) _NOEXCEPT             {return fmaxf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __x, long double __y) _NOEXCEPT {return fmaxl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       fmax(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fmaxf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmaxl(__lcpp_x, __lcpp_y);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-fmax(_A1 __x, _A2 __y) _NOEXCEPT
+fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return fmax((__result_type)__x, (__result_type)__y);
+    return fmax((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 // fmin
@@ -1261,23 +1261,23 @@
 using ::fmin;
 using ::fminf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       fmin(float __x, float __y) _NOEXCEPT             {return fminf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __x, long double __y) _NOEXCEPT {return fminl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       fmin(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return fminf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fminl(__lcpp_x, __lcpp_y);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-fmin(_A1 __x, _A2 __y) _NOEXCEPT
+fmin(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return fmin((__result_type)__x, (__result_type)__y);
+    return fmin((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 // hypot
@@ -1285,23 +1285,23 @@
 using ::hypot;
 using ::hypotf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       hypot(float __x, float __y) _NOEXCEPT             {return hypotf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __x, long double __y) _NOEXCEPT {return hypotl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       hypot(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return hypotf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return hypotl(__lcpp_x, __lcpp_y);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-hypot(_A1 __x, _A2 __y) _NOEXCEPT
+hypot(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return hypot((__result_type)__x, (__result_type)__y);
+    return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 // ilogb
@@ -1309,27 +1309,27 @@
 using ::ilogb;
 using ::ilogbf;
 
-inline _LIBCPP_INLINE_VISIBILITY int ilogb(float __x) _NOEXCEPT       {return ilogbf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY int ilogb(long double __x) _NOEXCEPT {return ilogbl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY int ilogb(float __lcpp_x) _NOEXCEPT       {return ilogbf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY int ilogb(long double __lcpp_x) _NOEXCEPT {return ilogbl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, int>::type
-ilogb(_A1 __x) _NOEXCEPT {return ilogb((double)__x);}
+ilogb(_A1 __lcpp_x) _NOEXCEPT {return ilogb((double)__lcpp_x);}
 
 // lgamma
 
 using ::lgamma;
 using ::lgammaf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       lgamma(float __x) _NOEXCEPT       {return lgammaf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double lgamma(long double __x) _NOEXCEPT {return lgammal(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       lgamma(float __lcpp_x) _NOEXCEPT       {return lgammaf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double lgamma(long double __lcpp_x) _NOEXCEPT {return lgammal(__lcpp_x);}
 
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-lgamma(_A1 __x) _NOEXCEPT {return lgamma((double)__x);}
+lgamma(_A1 __lcpp_x) _NOEXCEPT {return lgamma((double)__lcpp_x);}
 
 
 // llrint
@@ -1337,91 +1337,91 @@
 using ::llrint;
 using ::llrintf;
 
-inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __x) _NOEXCEPT       {return llrintf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __x) _NOEXCEPT {return llrintl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __lcpp_x) _NOEXCEPT       {return llrintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __lcpp_x) _NOEXCEPT {return llrintl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, long long>::type
-llrint(_A1 __x) _NOEXCEPT {return llrint((double)__x);}
+llrint(_A1 __lcpp_x) _NOEXCEPT {return llrint((double)__lcpp_x);}
 
 // llround
 
 using ::llround;
 using ::llroundf;
 
-inline _LIBCPP_INLINE_VISIBILITY long long llround(float __x) _NOEXCEPT       {return llroundf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __x) _NOEXCEPT {return llroundl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llround(float __lcpp_x) _NOEXCEPT       {return llroundf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __lcpp_x) _NOEXCEPT {return llroundl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, long long>::type
-llround(_A1 __x) _NOEXCEPT {return llround((double)__x);}
+llround(_A1 __lcpp_x) _NOEXCEPT {return llround((double)__lcpp_x);}
 
 // log1p
 
 using ::log1p;
 using ::log1pf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       log1p(float __x) _NOEXCEPT       {return log1pf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log1p(long double __x) _NOEXCEPT {return log1pl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       log1p(float __lcpp_x) _NOEXCEPT       {return log1pf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log1p(long double __lcpp_x) _NOEXCEPT {return log1pl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-log1p(_A1 __x) _NOEXCEPT {return log1p((double)__x);}
+log1p(_A1 __lcpp_x) _NOEXCEPT {return log1p((double)__lcpp_x);}
 
 // log2
 
 using ::log2;
 using ::log2f;
 
-inline _LIBCPP_INLINE_VISIBILITY float       log2(float __x) _NOEXCEPT       {return log2f(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return log2l(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       log2(float __lcpp_x) _NOEXCEPT       {return log2f(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __lcpp_x) _NOEXCEPT {return log2l(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-log2(_A1 __x) _NOEXCEPT {return log2((double)__x);}
+log2(_A1 __lcpp_x) _NOEXCEPT {return log2((double)__lcpp_x);}
 
 // logb
 
 using ::logb;
 using ::logbf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       logb(float __x) _NOEXCEPT       {return logbf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return logbl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       logb(float __lcpp_x) _NOEXCEPT       {return logbf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __lcpp_x) _NOEXCEPT {return logbl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-logb(_A1 __x) _NOEXCEPT {return logb((double)__x);}
+logb(_A1 __lcpp_x) _NOEXCEPT {return logb((double)__lcpp_x);}
 
 // lrint
 
 using ::lrint;
 using ::lrintf;
 
-inline _LIBCPP_INLINE_VISIBILITY long lrint(float __x) _NOEXCEPT       {return lrintf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __x) _NOEXCEPT {return lrintl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long lrint(float __lcpp_x) _NOEXCEPT       {return lrintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __lcpp_x) _NOEXCEPT {return lrintl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, long>::type
-lrint(_A1 __x) _NOEXCEPT {return lrint((double)__x);}
+lrint(_A1 __lcpp_x) _NOEXCEPT {return lrint((double)__lcpp_x);}
 
 // lround
 
 using ::lround;
 using ::lroundf;
 
-inline _LIBCPP_INLINE_VISIBILITY long lround(float __x) _NOEXCEPT       {return lroundf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long lround(long double __x) _NOEXCEPT {return lroundl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long lround(float __lcpp_x) _NOEXCEPT       {return lroundf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long lround(long double __lcpp_x) _NOEXCEPT {return lroundl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, long>::type
-lround(_A1 __x) _NOEXCEPT {return lround((double)__x);}
+lround(_A1 __lcpp_x) _NOEXCEPT {return lround((double)__lcpp_x);}
 
 #endif // _LIBCPP_MSVCRT
 #endif // __sun__
@@ -1441,36 +1441,36 @@
 using ::nearbyint;
 using ::nearbyintf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       nearbyint(float __x) _NOEXCEPT       {return nearbyintf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double nearbyint(long double __x) _NOEXCEPT {return nearbyintl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       nearbyint(float __lcpp_x) _NOEXCEPT       {return nearbyintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double nearbyint(long double __lcpp_x) _NOEXCEPT {return nearbyintl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-nearbyint(_A1 __x) _NOEXCEPT {return nearbyint((double)__x);}
+nearbyint(_A1 __lcpp_x) _NOEXCEPT {return nearbyint((double)__lcpp_x);}
 
 // nextafter
 
 using ::nextafter;
 using ::nextafterf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       nextafter(float __x, float __y) _NOEXCEPT             {return nextafterf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __x, long double __y) _NOEXCEPT {return nextafterl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       nextafter(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return nextafterf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nextafterl(__lcpp_x, __lcpp_y);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-nextafter(_A1 __x, _A2 __y) _NOEXCEPT
+nextafter(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return nextafter((__result_type)__x, (__result_type)__y);
+    return nextafter((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 // nexttoward
@@ -1478,36 +1478,36 @@
 using ::nexttoward;
 using ::nexttowardf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       nexttoward(float __x, long double __y) _NOEXCEPT       {return nexttowardf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __x, long double __y) _NOEXCEPT {return nexttowardl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       nexttoward(float __lcpp_x, long double __lcpp_y) _NOEXCEPT       {return nexttowardf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttowardl(__lcpp_x, __lcpp_y);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-nexttoward(_A1 __x, long double __y) _NOEXCEPT {return nexttoward((double)__x, __y);}
+nexttoward(_A1 __lcpp_x, long double __lcpp_y) _NOEXCEPT {return nexttoward((double)__lcpp_x, __lcpp_y);}
 
 // remainder
 
 using ::remainder;
 using ::remainderf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       remainder(float __x, float __y) _NOEXCEPT             {return remainderf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __x, long double __y) _NOEXCEPT {return remainderl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       remainder(float __lcpp_x, float __lcpp_y) _NOEXCEPT             {return remainderf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return remainderl(__lcpp_x, __lcpp_y);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-remainder(_A1 __x, _A2 __y) _NOEXCEPT
+remainder(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return remainder((__result_type)__x, (__result_type)__y);
+    return remainder((__result_type)__lcpp_x, (__result_type)__lcpp_y);
 }
 
 // remquo
@@ -1515,23 +1515,23 @@
 using ::remquo;
 using ::remquof;
 
-inline _LIBCPP_INLINE_VISIBILITY float       remquo(float __x, float __y, int* __z) _NOEXCEPT             {return remquof(__x, __y, __z);}
-inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __x, long double __y, int* __z) _NOEXCEPT {return remquol(__x, __y, __z);}
+inline _LIBCPP_INLINE_VISIBILITY float       remquo(float __lcpp_x, float __lcpp_y, int* __lcpp_z) _NOEXCEPT             {return remquof(__lcpp_x, __lcpp_y, __lcpp_z);}
+inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __lcpp_x, long double __lcpp_y, int* __lcpp_z) _NOEXCEPT {return remquol(__lcpp_x, __lcpp_y, __lcpp_z);}
 
 template <class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
+typename __lazy_enable_if
 <
     is_arithmetic<_A1>::value &&
     is_arithmetic<_A2>::value,
-    typename __promote<_A1, _A2>::type
+    __promote<_A1, _A2>
 >::type
-remquo(_A1 __x, _A2 __y, int* __z) _NOEXCEPT
+remquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT
 {
     typedef typename __promote<_A1, _A2>::type __result_type;
     static_assert((!(is_same<_A1, __result_type>::value &&
                       is_same<_A2, __result_type>::value)), "");
-    return remquo((__result_type)__x, (__result_type)__y, __z);
+    return remquo((__result_type)__lcpp_x, (__result_type)__lcpp_y, __lcpp_z);
 }
 
 // rint
@@ -1539,78 +1539,78 @@
 using ::rint;
 using ::rintf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       rint(float __x) _NOEXCEPT       {return rintf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __x) _NOEXCEPT {return rintl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       rint(float __lcpp_x) _NOEXCEPT       {return rintf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __lcpp_x) _NOEXCEPT {return rintl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-rint(_A1 __x) _NOEXCEPT {return rint((double)__x);}
+rint(_A1 __lcpp_x) _NOEXCEPT {return rint((double)__lcpp_x);}
 
 // round
 
 using ::round;
 using ::roundf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       round(float __x) _NOEXCEPT       {return roundf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double round(long double __x) _NOEXCEPT {return roundl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       round(float __lcpp_x) _NOEXCEPT       {return roundf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double round(long double __lcpp_x) _NOEXCEPT {return roundl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-round(_A1 __x) _NOEXCEPT {return round((double)__x);}
+round(_A1 __lcpp_x) _NOEXCEPT {return round((double)__lcpp_x);}
 
 // scalbln
 
 using ::scalbln;
 using ::scalblnf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       scalbln(float __x, long __y) _NOEXCEPT       {return scalblnf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double scalbln(long double __x, long __y) _NOEXCEPT {return scalblnl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       scalbln(float __lcpp_x, long __lcpp_y) _NOEXCEPT       {return scalblnf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double scalbln(long double __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalblnl(__lcpp_x, __lcpp_y);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-scalbln(_A1 __x, long __y) _NOEXCEPT {return scalbln((double)__x, __y);}
+scalbln(_A1 __lcpp_x, long __lcpp_y) _NOEXCEPT {return scalbln((double)__lcpp_x, __lcpp_y);}
 
 // scalbn
 
 using ::scalbn;
 using ::scalbnf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       scalbn(float __x, int __y) _NOEXCEPT       {return scalbnf(__x, __y);}
-inline _LIBCPP_INLINE_VISIBILITY long double scalbn(long double __x, int __y) _NOEXCEPT {return scalbnl(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY float       scalbn(float __lcpp_x, int __lcpp_y) _NOEXCEPT       {return scalbnf(__lcpp_x, __lcpp_y);}
+inline _LIBCPP_INLINE_VISIBILITY long double scalbn(long double __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbnl(__lcpp_x, __lcpp_y);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-scalbn(_A1 __x, int __y) _NOEXCEPT {return scalbn((double)__x, __y);}
+scalbn(_A1 __lcpp_x, int __lcpp_y) _NOEXCEPT {return scalbn((double)__lcpp_x, __lcpp_y);}
 
 // tgamma
 
 using ::tgamma;
 using ::tgammaf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       tgamma(float __x) _NOEXCEPT       {return tgammaf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double tgamma(long double __x) _NOEXCEPT {return tgammal(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       tgamma(float __lcpp_x) _NOEXCEPT       {return tgammaf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tgamma(long double __lcpp_x) _NOEXCEPT {return tgammal(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-tgamma(_A1 __x) _NOEXCEPT {return tgamma((double)__x);}
+tgamma(_A1 __lcpp_x) _NOEXCEPT {return tgamma((double)__lcpp_x);}
 
 // trunc
 
 using ::trunc;
 using ::truncf;
 
-inline _LIBCPP_INLINE_VISIBILITY float       trunc(float __x) _NOEXCEPT       {return truncf(__x);}
-inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __x) _NOEXCEPT {return truncl(__x);}
+inline _LIBCPP_INLINE_VISIBILITY float       trunc(float __lcpp_x) _NOEXCEPT       {return truncf(__lcpp_x);}
+inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __lcpp_x) _NOEXCEPT {return truncl(__lcpp_x);}
 
 template <class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
-trunc(_A1 __x) _NOEXCEPT {return trunc((double)__x);}
+trunc(_A1 __lcpp_x) _NOEXCEPT {return trunc((double)__lcpp_x);}
 
 #endif // !_LIBCPP_MSVCRT
 
diff --git a/include/condition_variable b/include/condition_variable
index dc67266..1af2484 100644
--- a/include/condition_variable
+++ b/include/condition_variable
@@ -115,6 +115,8 @@
 #pragma GCC system_header
 #endif
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 class _LIBCPP_TYPE_VIS condition_variable_any
@@ -253,4 +255,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_CONDITION_VARIABLE
diff --git a/include/deque b/include/deque
index 9b256b7..5602d4a 100644
--- a/include/deque
+++ b/include/deque
@@ -1588,7 +1588,7 @@
 {
     iterator __i = __base::begin();
     iterator __e = __base::end();
-    for (; __f != __l && __i != __e; ++__f, ++__i)
+    for (; __f != __l && __i != __e; ++__f, (void) ++__i)
         *__i = *__f;
     if (__f != __l)
         __append(__f, __l);
@@ -2160,7 +2160,7 @@
         if (__n > __de)
         {
             __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
-            for (_BiIter __j = __m; __j != __l; ++__i, ++__j, ++__base::size())
+            for (_BiIter __j = __m; __j != __l; ++__i, (void) ++__j, ++__base::size())
                 __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
             __n = __de;
         }
@@ -2200,7 +2200,7 @@
     if (__n > __back_capacity)
         __add_back_capacity(__n - __back_capacity);
     // __n <= __back_capacity
-    for (iterator __i = __base::end(); __f != __l; ++__i, ++__f, ++__base::size())
+    for (iterator __i = __base::end(); __f != __l; ++__i, (void) ++__f, ++__base::size())
         __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__f);
 }
 
diff --git a/include/experimental/__config b/include/experimental/__config
new file mode 100644
index 0000000..684a3b4
--- /dev/null
+++ b/include/experimental/__config
@@ -0,0 +1,24 @@
+// -*- C++ -*-
+//===--------------------------- __config ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_CONFIG
+#define _LIBCPP_EXPERIMENTAL_CONFIG
+
+#include <__config>
+
+#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace std { namespace experimental {
+#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL  } }
+#define _VSTD_EXPERIMENTAL std::experimental
+
+#define _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v1 {
+#define _LIBCPP_END_NAMESPACE_LFTS  } } }
+#define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1
+
+#endif
diff --git a/include/experimental/optional b/include/experimental/optional
index 3848da8..2f0df35 100644
--- a/include/experimental/optional
+++ b/include/experimental/optional
@@ -151,11 +151,7 @@
 
 #include <__undef_min_max>
 
-#ifdef _LIBCPP_DEBUG
-#   include <__debug>
-#else
-#   define _LIBCPP_ASSERT(x, m) ((void)0)
-#endif
+#include <__debug>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -696,4 +692,4 @@
 
 #endif  // _LIBCPP_STD_VER > 11
 
-#endif  // _LIBCPP_ARRAY
+#endif  // _LIBCPP_OPTIONAL
diff --git a/include/experimental/string_view b/include/experimental/string_view
new file mode 100644
index 0000000..d423f39
--- /dev/null
+++ b/include/experimental/string_view
@@ -0,0 +1,815 @@
+// -*- C++ -*-
+//===------------------------ string_view ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_LFTS_STRING_VIEW
+#define _LIBCPP_LFTS_STRING_VIEW
+
+/*
+string_view synopsis
+
+namespace std {
+ namespace experimental {
+  inline namespace library_fundamentals_v1 {
+
+    // 7.2, Class template basic_string_view
+    template<class charT, class traits = char_traits<charT>>
+        class basic_string_view;
+
+    // 7.9, basic_string_view non-member comparison functions
+    template<class charT, class traits>
+    constexpr bool operator==(basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator!=(basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator< (basic_string_view<charT, traits> x,
+                                 basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator> (basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator<=(basic_string_view<charT, traits> x,
+                                 basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator>=(basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    // see below, sufficient additional overloads of comparison functions
+
+    // 7.10, Inserters and extractors
+    template<class charT, class traits>
+      basic_ostream<charT, traits>&
+        operator<<(basic_ostream<charT, traits>& os,
+                   basic_string_view<charT, traits> str);
+
+    // basic_string_view typedef names
+    typedef basic_string_view<char> string_view;
+    typedef basic_string_view<char16_t> u16string_view;
+    typedef basic_string_view<char32_t> u32string_view;
+    typedef basic_string_view<wchar_t> wstring_view;
+
+    template<class charT, class traits = char_traits<charT>>
+    class basic_string_view {
+      public:
+      // types
+      typedef traits traits_type;
+      typedef charT value_type;
+      typedef charT* pointer;
+      typedef const charT* const_pointer;
+      typedef charT& reference;
+      typedef const charT& const_reference;
+      typedef implementation-defined const_iterator;
+      typedef const_iterator iterator;
+      typedef reverse_iterator<const_iterator> const_reverse_iterator;
+      typedef const_reverse_iterator reverse_iterator;
+      typedef size_t size_type;
+      typedef ptrdiff_t difference_type;
+      static constexpr size_type npos = size_type(-1);
+
+      // 7.3, basic_string_view constructors and assignment operators
+      constexpr basic_string_view() noexcept;
+      constexpr basic_string_view(const basic_string_view&) noexcept = default;
+      basic_string_view& operator=(const basic_string_view&) noexcept = default;
+      template<class Allocator>
+      basic_string_view(const basic_string<charT, traits, Allocator>& str) noexcept;
+      constexpr basic_string_view(const charT* str);
+      constexpr basic_string_view(const charT* str, size_type len);
+
+      // 7.4, basic_string_view iterator support
+      constexpr const_iterator begin() const noexcept;
+      constexpr const_iterator end() const noexcept;
+      constexpr const_iterator cbegin() const noexcept;
+      constexpr const_iterator cend() const noexcept;
+      const_reverse_iterator rbegin() const noexcept;
+      const_reverse_iterator rend() const noexcept;
+      const_reverse_iterator crbegin() const noexcept;
+      const_reverse_iterator crend() const noexcept;
+
+      // 7.5, basic_string_view capacity
+      constexpr size_type size() const noexcept;
+      constexpr size_type length() const noexcept;
+      constexpr size_type max_size() const noexcept;
+      constexpr bool empty() const noexcept;
+
+      // 7.6, basic_string_view element access
+      constexpr const_reference operator[](size_type pos) const;
+      constexpr const_reference at(size_type pos) const;
+      constexpr const_reference front() const;
+      constexpr const_reference back() const;
+      constexpr const_pointer data() const noexcept;
+
+      // 7.7, basic_string_view modifiers
+      constexpr void clear() noexcept;
+      constexpr void remove_prefix(size_type n);
+      constexpr void remove_suffix(size_type n);
+      constexpr void swap(basic_string_view& s) noexcept;
+
+      // 7.8, basic_string_view string operations
+      template<class Allocator>
+      explicit operator basic_string<charT, traits, Allocator>() const;
+      template<class Allocator = allocator<charT>>
+      basic_string<charT, traits, Allocator> to_string(
+        const Allocator& a = Allocator()) const;
+
+      size_type copy(charT* s, size_type n, size_type pos = 0) const;
+
+      constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
+      constexpr int compare(basic_string_view s) const noexcept;
+      constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
+      constexpr int compare(size_type pos1, size_type n1,
+                            basic_string_view s, size_type pos2, size_type n2) const;
+      constexpr int compare(const charT* s) const;
+      constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
+      constexpr int compare(size_type pos1, size_type n1,
+                            const charT* s, size_type n2) const;
+      constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
+      constexpr size_type find(charT c, size_type pos = 0) const noexcept;
+      constexpr size_type find(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find(const charT* s, size_type pos = 0) const;
+      constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
+      constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
+      constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type rfind(const charT* s, size_type pos = npos) const;
+      constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
+      constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
+      constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
+      constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
+
+     private:
+      const_pointer data_;  // exposition only
+      size_type     size_;  // exposition only
+    };
+
+  }  // namespace fundamentals_v1
+ }  // namespace experimental
+
+  // 7.11, Hash support
+  template <class T> struct hash;
+  template <> struct hash<experimental::string_view>;
+  template <> struct hash<experimental::u16string_view>;
+  template <> struct hash<experimental::u32string_view>;
+  template <> struct hash<experimental::wstring_view>;
+
+}  // namespace std
+
+
+*/
+
+#include <experimental/__config>
+
+#include <string>
+#include <algorithm>
+#include <iterator>
+#include <ostream>
+#include <iomanip>
+
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+    template<class _CharT, class _Traits = _VSTD::char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_string_view {
+    public:
+        // types
+        typedef _Traits                                    traits_type;
+        typedef _CharT                                     value_type;
+        typedef const _CharT*                              pointer;
+        typedef const _CharT*                              const_pointer;
+        typedef const _CharT&                              reference;
+        typedef const _CharT&                              const_reference;
+        typedef const_pointer                              const_iterator; // See [string.view.iterators]
+        typedef const_iterator                             iterator;
+        typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;
+        typedef const_reverse_iterator                     reverse_iterator;
+        typedef size_t                                     size_type;
+        typedef ptrdiff_t                                  difference_type;
+        static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
+
+        // [string.view.cons], construct/copy
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const basic_string_view&) _NOEXCEPT = default;
+
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
+
+        template<class _Allocator>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) _NOEXCEPT
+            : __data (__str.data()), __size(__str.size()) {}
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const _CharT* __s, size_type __len)
+            : __data(__s), __size(__len)
+        {
+//             _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): recieved nullptr");
+        }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const _CharT* __s)
+            : __data(__s), __size(_Traits::length(__s)) {}
+
+        // [string.view.iterators], iterators
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator begin()  const _NOEXCEPT { return cbegin(); }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator end()    const _NOEXCEPT { return cend(); }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator cbegin() const _NOEXCEPT { return __data; }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator cend()   const _NOEXCEPT { return __data + __size; }
+
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
+
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
+
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
+
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
+
+        // [string.view.capacity], capacity
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        size_type size()     const _NOEXCEPT { return __size; }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        size_type length()   const _NOEXCEPT { return __size; }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        size_type max_size() const _NOEXCEPT { return _VSTD::numeric_limits<size_type>::max(); }
+
+        _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY
+        empty()         const _NOEXCEPT { return __size == 0; }
+
+        // [string.view.access], element access
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference operator[](size_type __pos) const { return __data[__pos]; }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference at(size_type __pos) const
+        {
+            return __pos >= size()
+                ? throw out_of_range("string_view::at")
+                : __data[__pos];
+//             if (__pos >= size())
+//                 throw out_of_range("string_view::at");
+//             return __data[__pos]; 
+        }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference front() const
+        {
+            return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
+        }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference back() const
+        {
+            return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
+        }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_pointer data() const _NOEXCEPT { return __data; }
+
+        // [string.view.modifiers], modifiers:
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void clear() _NOEXCEPT
+        {
+            __data = nullptr;
+            __size = 0;
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void remove_prefix(size_type __n) _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(n <= size(), "remove_prefix() can't remove more than size()");
+            __data += __n;
+            __size -= __n;
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void remove_suffix(size_type __n) _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(n <= size(), "remove_suffix() can't remove more than size()");
+            __size -= __n;
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void swap(basic_string_view& __other) _NOEXCEPT
+        {
+            const value_type *__p = __data;
+            __data = __other.__data;
+            __other.__data = __p;
+
+            size_type __sz = __size;
+            __size = __other.__size;
+            __other.__size = __sz;
+//             _VSTD::swap( __data, __other.__data );
+//             _VSTD::swap( __size, __other.__size );
+        }
+
+        // [string.view.ops], string operations:
+        template<class _Allocator>
+        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const
+        { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); }
+
+        template<class _Allocator = allocator<_CharT> >
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string<_CharT, _Traits, _Allocator>
+        to_string( const _Allocator& __a = _Allocator()) const
+        { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); }
+
+        size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
+        {
+            if ( __pos > size())
+                throw out_of_range("string_view::copy");
+            size_type __rlen = _VSTD::min( __n, size() - __pos );
+            _VSTD::copy_n(begin() + __pos, __rlen, __s );
+            return __rlen;
+        }
+
+        _LIBCPP_CONSTEXPR
+        basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
+        {
+//             if (__pos > size())
+//                 throw out_of_range("string_view::substr");
+//             size_type __rlen = _VSTD::min( __n, size() - __pos );
+//             return basic_string_view(data() + __pos, __rlen);
+            return __pos > size()
+                ? throw out_of_range("string_view::substr")
+                : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
+        {
+            size_type __rlen = _VSTD::min( size(), __sv.size());
+            int __retval = _Traits::compare(data(), __sv.data(), __rlen);
+            if ( __retval == 0 ) // first __rlen chars matched
+                __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
+            return __retval;
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
+        {
+            return substr(__pos1, __n1).compare(__sv);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(                       size_type __pos1, size_type __n1, 
+                    basic_string_view _sv, size_type __pos2, size_type __n2) const
+        {
+            return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(const _CharT* __s) const
+        {
+            return compare(basic_string_view(__s));
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
+        {
+            return substr(__pos1, __n1).compare(basic_string_view(__s));
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
+        {
+            return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
+        }
+
+        // find
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
+        {
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(const _CharT* __s, size_type __pos = 0) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // rfind
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
+        {
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): recieved nullptr");
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(const _CharT* __s, size_type __pos=npos) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): recieved nullptr");
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // find_first_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): recieved nullptr");
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
+        { return find(__c, __pos); }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): recieved nullptr");
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(const _CharT* __s, size_type __pos=0) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): recieved nullptr");
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // find_last_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): recieved nullptr");
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
+        { return rfind(__c, __pos); }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): recieved nullptr");
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): recieved nullptr");
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // find_first_not_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): recieved nullptr");
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
+        {
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): recieved nullptr");
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): recieved nullptr");
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // find_last_not_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): recieved nullptr");
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
+        {
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): recieved nullptr");
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): recieved nullptr");
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+    private:
+        const   value_type* __data;
+        size_type           __size;
+    };
+
+
+    // [string.view.comparison]
+    // operator ==
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator==(basic_string_view<_CharT, _Traits> __lhs,
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size()) return false;
+        return __lhs.compare(__rhs) == 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator==(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size()) return false;
+        return __lhs.compare(__rhs) == 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator==(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size()) return false;
+        return __lhs.compare(__rhs) == 0;
+    }
+
+
+    // operator !=
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size())
+            return true;
+        return __lhs.compare(__rhs) != 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size())
+            return true;
+        return __lhs.compare(__rhs) != 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size())
+            return true;
+        return __lhs.compare(__rhs) != 0;
+    }
+
+
+    // operator <
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) < 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) < 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) < 0;
+    }
+
+
+    // operator >
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) > 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) > 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) > 0;
+    }
+
+
+    // operator <=
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) <= 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) <= 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) <= 0;
+    }
+
+
+    // operator >=
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) >= 0;
+    }
+
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) >= 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) >= 0;
+    }
+
+
+    // [string.view.io]
+    template<class _CharT, class _Traits>
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)
+    {
+        return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size());
+    }
+
+  typedef basic_string_view<char>     string_view;
+  typedef basic_string_view<char16_t> u16string_view;
+  typedef basic_string_view<char32_t> u32string_view;
+  typedef basic_string_view<wchar_t>  wstring_view;
+
+_LIBCPP_END_NAMESPACE_LFTS
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// [string.view.hash]
+// Shamelessly stolen from <string>
+template<class _CharT, class _Traits>
+struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::basic_string_view<_CharT, _Traits> >
+    : public unary_function<std::experimental::basic_string_view<_CharT, _Traits>, size_t>
+{
+    size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT;
+};
+
+template<class _CharT, class _Traits>
+size_t
+hash<std::experimental::basic_string_view<_CharT, _Traits> >::operator()(
+        const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT
+{
+    return __do_string_hash(__val.data(), __val.data() + __val.size());
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _CharT, class _Traits>
+__quoted_output_proxy<_CharT, const _CharT *, _Traits>
+quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv,
+             _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+    return __quoted_output_proxy<_CharT, const _CharT *, _Traits> 
+         ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape );
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_LFTS_STRING_VIEW
diff --git a/include/experimental/utility b/include/experimental/utility
new file mode 100644
index 0000000..84e461a
--- /dev/null
+++ b/include/experimental/utility
@@ -0,0 +1,44 @@
+// -*- C++ -*-
+//===-------------------------- utility ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_UTILITY
+#define _LIBCPP_EXPERIMENTAL_UTILITY
+
+/*
+    experimental/utility synopsis
+
+// C++1y
+
+#include <utility>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+
+  3.1.2, erased-type placeholder
+  struct erased_type { };
+
+} // namespace fundamentals_v1
+} // namespace experimental
+} // namespace std
+
+ */
+
+# include <experimental/__config>
+
+# include <utility>
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+  struct _LIBCPP_TYPE_VIS_ONLY erased_type { };
+
+_LIBCPP_END_NAMESPACE_LFTS
+
+#endif /* _LIBCPP_EXPERIMENTAL_UTILITY */
diff --git a/include/forward_list b/include/forward_list
index a83b195..651452f 100644
--- a/include/forward_list
+++ b/include/forward_list
@@ -991,7 +991,7 @@
     iterator __i = before_begin();
     iterator __j = _VSTD::next(__i);
     iterator __e = end();
-    for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
+    for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f)
         *__j = *__f;
     if (__j == __e)
         insert_after(__i, __f, __l);
@@ -1201,7 +1201,7 @@
         try
         {
 #endif  // _LIBCPP_NO_EXCEPTIONS
-            for (++__f; __f != __l; ++__f, __last = __last->__next_)
+            for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_)))
             {
                 __h.reset(__node_traits::allocate(__a, 1));
                 __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
@@ -1430,7 +1430,7 @@
             iterator __j = _VSTD::next(__i, 2);
             for (; __j != __e && *__j == __v; ++__j)
                 ;
-			__deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
+            __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j);
             if (__j == __e)
                 break;
             __i = __j;
diff --git a/include/future b/include/future
index de00f25..6fe6f8d 100644
--- a/include/future
+++ b/include/future
@@ -374,6 +374,10 @@
 #pragma GCC system_header
 #endif
 
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error <future> is not supported on this single threaded system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 //enum class future_errc
@@ -779,9 +783,12 @@
 {
     if (this->__state_ & base::__constructed)
         reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
-    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _A;
+    typedef allocator_traits<_A> _ATraits;
+    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+    _A __a(__alloc_);
     this->~__assoc_state_alloc();
-    __a.deallocate(this, 1);
+    __a.deallocate(_PTraits::pointer_to(*this), 1);
 }
 
 template <class _Rp, class _Alloc>
@@ -802,9 +809,12 @@
 void
 __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
 {
-    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+    typedef typename __allocator_traits_rebind<_Alloc, __assoc_state_alloc>::type _A;
+    typedef allocator_traits<_A> _ATraits;
+    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+    _A __a(__alloc_);
     this->~__assoc_state_alloc();
-    __a.deallocate(this, 1);
+    __a.deallocate(_PTraits::pointer_to(*this), 1);
 }
 
 template <class _Alloc>
@@ -825,9 +835,12 @@
 void
 __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
 {
-    typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
+    typedef typename __allocator_traits_rebind<_Alloc, __assoc_sub_state_alloc>::type _A;
+    typedef allocator_traits<_A> _ATraits;
+    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+    _A __a(__alloc_);
     this->~__assoc_sub_state_alloc();
-    __a.deallocate(this, 1);
+    __a.deallocate(_PTraits::pointer_to(*this), 1);
 }
 
 template <class _Rp, class _Fp>
@@ -1410,12 +1423,13 @@
 template <class _Alloc>
 promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
 {
-    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
+    typedef __assoc_state_alloc<_Rp, _Alloc> _State;
+    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
     typedef __allocator_destructor<_A2> _D2;
     _A2 __a(__a0);
-    unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
-    ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
-    __state_ = __hold.release();
+    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
+    __state_ = _VSTD::addressof(*__hold.release());
 }
 
 template <class _Rp>
@@ -1583,12 +1597,13 @@
 template <class _Alloc>
 promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
 {
-    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
+    typedef __assoc_state_alloc<_Rp&, _Alloc> _State;
+    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
     typedef __allocator_destructor<_A2> _D2;
     _A2 __a(__a0);
-    unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
-    ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
-    __state_ = __hold.release();
+    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
+    __state_ = _VSTD::addressof(*__hold.release());
 }
 
 template <class _Rp>
@@ -1719,12 +1734,13 @@
 template <class _Alloc>
 promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
 {
-    typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
+    typedef __assoc_sub_state_alloc<_Alloc> _State;
+    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
     typedef __allocator_destructor<_A2> _D2;
     _A2 __a(__a0);
-    unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
-    ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
-    __state_ = __hold.release();
+    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold.get()))) _State(__a0);
+    __state_ = _VSTD::addressof(*__hold.release());
 }
 
 template <class _Rp>
@@ -1804,10 +1820,12 @@
 void
 __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
 {
-    typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
+    typedef typename __allocator_traits_rebind<_Alloc, __packaged_task_func>::type _Ap;
+    typedef allocator_traits<_Ap> _ATraits;
+    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
     _Ap __a(__f_.second());
     __f_.~__compressed_pair<_Fp, _Alloc>();
-    __a.deallocate(this, 1);
+    __a.deallocate(_PTraits::pointer_to(*this), 1);
 }
 
 template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
@@ -1896,7 +1914,6 @@
                                   allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
     : __f_(nullptr)
 {
-    typedef allocator_traits<_Alloc> __alloc_traits;
     typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
     typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
     if (sizeof(_FF) <= sizeof(__buf_))
@@ -1906,18 +1923,13 @@
     }
     else
     {
-        typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind_alloc<_FF>
-#else
-            rebind_alloc<_FF>::other
-#endif
-                                                     _Ap;
+        typedef typename __allocator_traits_rebind<_Alloc, _FF>::type _Ap;
         _Ap __a(__a0);
         typedef __allocator_destructor<_Ap> _Dp;
         unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
-        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
-        __f_ = __hold.release();
+        ::new (static_cast<void*>(_VSTD::addressof(*__hold.get())))
+            _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
+        __f_ = _VSTD::addressof(*__hold.release());
     }
 }
 
@@ -2612,4 +2624,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_FUTURE
diff --git a/include/ios b/include/ios
index d95f18a..ff79998 100644
--- a/include/ios
+++ b/include/ios
@@ -216,7 +216,7 @@
 #include <__locale>
 #include <system_error>
 
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
 #include <atomic>     // for __xindex_
 #endif
 
@@ -367,7 +367,7 @@
     int*            __index_;
     size_t          __event_size_;
     size_t          __event_cap_;
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
     static atomic<int> __xindex_;
 #else
     static int      __xindex_;
diff --git a/include/istream b/include/istream
index 14fa466..168a4d0 100644
--- a/include/istream
+++ b/include/istream
@@ -82,6 +82,13 @@
     pos_type tellg();
     basic_istream& seekg(pos_type);
     basic_istream& seekg(off_type, ios_base::seekdir);
+protected:
+    basic_istream(const basic_istream& rhs) = delete;
+    basic_istream(basic_istream&& rhs);
+    // 27.7.2.1.2 Assign/swap:
+    basic_istream& operator=(const basic_istream& rhs) = delete;
+    basic_istream& operator=(basic_istream&& rhs);
+    void swap(basic_istream& rhs);
 };
 
 // 27.7.1.2.3 character extraction templates:
@@ -184,13 +191,22 @@
     _LIBCPP_INLINE_VISIBILITY
     basic_istream(basic_istream&& __rhs);
 #endif
-
     // 27.7.1.1.2 Assign/swap:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
     basic_istream& operator=(basic_istream&& __rhs);
 #endif
     void swap(basic_istream& __rhs);
+
+#if _LIBCPP_STD_VER > 11
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    basic_istream           (const basic_istream& __rhs) = delete;
+    basic_istream& operator=(const basic_istream& __rhs) = delete;
+#else
+    basic_istream           (const basic_istream& __rhs); // not defined
+    basic_istream& operator=(const basic_istream& __rhs); // not defined
+#endif
+#endif
 public:
 
     // 27.7.1.1.3 Prefix/suffix:
diff --git a/include/iterator b/include/iterator
index f338e01..bcf142a 100644
--- a/include/iterator
+++ b/include/iterator
@@ -324,6 +324,17 @@
 template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
 template <class C> auto crend(const C& c) -> decltype(std::rend(c));          // C++14
 
+// 24.8, container access:
+template <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
+template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
+template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
+template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
+template <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
+template <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
+template <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
+template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
+template <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
+
 }  // std
 
 */
@@ -338,11 +349,7 @@
 #include <Availability.h>
 #endif
 
-#ifdef _LIBCPP_DEBUG
-#   include <__debug>
-#else
-#   define _LIBCPP_ASSERT(x, m) ((void)0)
-#endif
+#include <__debug>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -1572,6 +1579,36 @@
 
 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
 
+#if _LIBCPP_STD_VER > 14
+template <class _C>
+constexpr auto size(const _C& __c) -> decltype(__c.size()) { return __c.size(); }
+
+template <class _Tp, size_t _N>
+constexpr size_t size(const _Tp (&__array)[_N]) noexcept { return _N; }
+
+template <class _C>
+constexpr auto empty(const _C& __c) -> decltype(__c.empty()) { return __c.empty(); }
+
+template <class _Tp, size_t _N>
+constexpr bool empty(const _Tp (&__array)[_N]) noexcept { return false; }
+
+template <class _Ep>
+constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; }
+
+template <class _C> constexpr
+auto data(_C& __c) -> decltype(__c.data()) { return __c.data(); }
+
+template <class _C> constexpr
+auto data(const _C& __c) -> decltype(__c.data()) { return __c.data(); }
+
+template <class _Tp, size_t _N>
+constexpr _Tp* data(_Tp (&__array)[_N]) noexcept { return __array; }
+
+template <class _Ep>
+constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); }
+#endif
+
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_ITERATOR
diff --git a/include/list b/include/list
index c36786d..13f8a53 100644
--- a/include/list
+++ b/include/list
@@ -179,11 +179,7 @@
 
 #include <__undef_min_max>
 
-#ifdef _LIBCPP_DEBUG
-#   include <__debug>
-#else
-#   define _LIBCPP_ASSERT(x, m) ((void)0)
-#endif
+#include <__debug>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
diff --git a/include/locale b/include/locale
index fcff402..0d01002 100644
--- a/include/locale
+++ b/include/locale
@@ -193,6 +193,11 @@
 #include <ctime>
 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
 #include <support/win32/locale_win32.h>
+#elif defined(_NEWLIB_VERSION)
+// FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an
+// include of <sys/cdefs.h> once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html
+// has had a chance to bake for a bit
+#include <support/newlib/xlocale.h>
 #elif !defined(__ANDROID__)
 #include <nl_types.h>
 #endif
@@ -229,7 +234,8 @@
 // OSX has nice foo_l() functions that let you turn off use of the global
 // locale.  Linux, not so much.  The following functions avoid the locale when
 // that's possible and otherwise do the wrong thing.  FIXME.
-#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX)
+#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \
+    defined(_NEWLIB_VERSION)
 
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
@@ -450,7 +456,7 @@
     size_t __n_does_match = 0;       // but none of them definitely do
     // Initialize all statuses to __might_match, except for "" keywords are __does_match
     unsigned char* __st = __status;
-    for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
+    for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
     {
         if (!__ky->empty())
             *__st = __might_match;
@@ -476,7 +482,7 @@
         // If the keyword doesn't match this character, then change the keyword
         //    to doesn't match
         __st = __status;
-        for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
+        for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
         {
             if (*__st == __might_match)
             {
@@ -510,7 +516,7 @@
             if (__n_might_match + __n_does_match > 1)
             {
                 __st = __status;
-                for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
+                for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, (void) ++__st)
                 {
                     if (*__st == __does_match && __ky->size() != __indx+1)
                     {
@@ -525,7 +531,7 @@
     if (__b == __e)
         __err |= ios_base::eofbit;
     // Return the first matching result
-    for (__st = __status; __kb != __ke; ++__kb, ++__st)
+    for (__st = __status; __kb != __ke; ++__kb, (void) ++__st)
         if (*__st == __does_match)
             break;
     if (__kb == __ke)
@@ -1851,7 +1857,7 @@
         return 0;
     }
     int __r = __ct.narrow(__c, 0) - '0';
-    for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n)
+    for (++__b, (void) --__n; __b != __e && __n > 0; ++__b, (void) --__n)
     {
         // get next digit
         __c = *__b;
@@ -2964,6 +2970,8 @@
     size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
     size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
                        2 * __cur_cap : numeric_limits<size_t>::max();
+    if (__new_cap == 0)
+        __new_cap = sizeof(_Tp);
     size_t __n_off = static_cast<size_t>(__n - __b.get());
     _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
     if (__t == 0)
@@ -3673,7 +3681,7 @@
 typename messages<_CharT>::catalog
 messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
 {
-#if defined(_WIN32) || defined(__ANDROID__)
+#if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION)
     return -1;
 #else // _WIN32 || __ANDROID__
     catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
@@ -3688,7 +3696,7 @@
 messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
                          const string_type& __dflt) const
 {
-#if defined(_WIN32) || defined(__ANDROID__)
+#if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION)
     return __dflt;
 #else // _WIN32
     string __ndflt;
@@ -3710,7 +3718,7 @@
 void
 messages<_CharT>::do_close(catalog __c) const
 {
-#if !defined(_WIN32) && !defined(__ANDROID__)
+#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION)
     if (__c != -1)
         __c <<= 1;
     nl_catd __cat = (nl_catd)__c;
diff --git a/include/memory b/include/memory
index dc9aeba..662faa0 100644
--- a/include/memory
+++ b/include/memory
@@ -610,7 +610,7 @@
     #include <cassert>
 #endif
 
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
 #  include <atomic>
 #endif
 
@@ -1450,7 +1450,7 @@
     template <class _Tp, class... _Args>
         _LIBCPP_INLINE_VISIBILITY
         static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)
-            {__construct(__has_construct<allocator_type, pointer, _Args...>(),
+            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
                          __a, __p, _VSTD::forward<_Args>(__args)...);}
 #else  // _LIBCPP_HAS_NO_VARIADICS
     template <class _Tp>
@@ -3660,7 +3660,7 @@
 const void*
 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
 {
-    return __t == typeid(_Dp) ? &__data_.first().second() : 0;
+    return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : 0;
 }
 
 #endif  // _LIBCPP_NO_RTTI
@@ -3677,9 +3677,13 @@
 void
 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
 {
-    typename _Alloc::template rebind<__shared_ptr_pointer>::other __a(__data_.second());
+    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _A;
+    typedef allocator_traits<_A> _ATraits;
+    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+
+    _A __a(__data_.second());
     __data_.second().~_Alloc();
-    __a.deallocate(this, 1);
+    __a.deallocate(_PTraits::pointer_to(*this), 1);
 }
 
 template <class _Tp, class _Alloc>
@@ -3742,9 +3746,12 @@
 void
 __shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
 {
-    typename _Alloc::template rebind<__shared_ptr_emplace>::other __a(__data_.first());
+    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type _A;
+    typedef allocator_traits<_A> _ATraits;
+    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
+    _A __a(__data_.first());
     __data_.first().~_Alloc();
-    __a.deallocate(this, 1);
+    __a.deallocate(_PTraits::pointer_to(*this), 1);
 }
 
 template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this;
@@ -4090,12 +4097,13 @@
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
         typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
-        typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+        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(__hold2.get()) _CntrlBlk(__p, __d, __a);
-        __cntrl_ = __hold2.release();
+        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+            _CntrlBlk(__p, __d, __a);
+        __cntrl_ = _VSTD::addressof(*__hold2.release());
         __enable_weak_this(__p);
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }
@@ -4117,12 +4125,13 @@
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
         typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
-        typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+        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(__hold2.get()) _CntrlBlk(__p, __d, __a);
-        __cntrl_ = __hold2.release();
+        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+            _CntrlBlk(__p, __d, __a);
+        __cntrl_ = _VSTD::addressof(*__hold2.release());
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }
     catch (...)
@@ -4282,14 +4291,15 @@
 shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args)
 {
     typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
-    typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+    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(__hold2.get()) _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
     shared_ptr<_Tp> __r;
     __r.__ptr_ = __hold2.get()->get();
-    __r.__cntrl_ = __hold2.release();
+    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
     __r.__enable_weak_this(__r.__ptr_);
     return __r;
 }
@@ -4373,14 +4383,15 @@
 shared_ptr<_Tp>::allocate_shared(const _Alloc& __a)
 {
     typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
-    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
     typedef __allocator_destructor<_Alloc2> _D2;
     _Alloc2 __alloc2(__a);
     unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
-    ::new(__hold2.get()) _CntrlBlk(__a);
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+        _CntrlBlk(__a);
     shared_ptr<_Tp> __r;
     __r.__ptr_ = __hold2.get()->get();
-    __r.__cntrl_ = __hold2.release();
+    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
     __r.__enable_weak_this(__r.__ptr_);
     return __r;
 }
@@ -4391,14 +4402,15 @@
 shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0)
 {
     typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
-    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
     typedef __allocator_destructor<_Alloc2> _D2;
     _Alloc2 __alloc2(__a);
     unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
-    ::new(__hold2.get()) _CntrlBlk(__a, __a0);
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+        _CntrlBlk(__a, __a0);
     shared_ptr<_Tp> __r;
     __r.__ptr_ = __hold2.get()->get();
-    __r.__cntrl_ = __hold2.release();
+    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
     __r.__enable_weak_this(__r.__ptr_);
     return __r;
 }
@@ -4409,14 +4421,15 @@
 shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)
 {
     typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
-    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
     typedef __allocator_destructor<_Alloc2> _D2;
     _Alloc2 __alloc2(__a);
     unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
-    ::new(__hold2.get()) _CntrlBlk(__a, __a0, __a1);
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+        _CntrlBlk(__a, __a0, __a1);
     shared_ptr<_Tp> __r;
     __r.__ptr_ = __hold2.get()->get();
-    __r.__cntrl_ = __hold2.release();
+    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
     __r.__enable_weak_this(__r.__ptr_);
     return __r;
 }
@@ -4427,14 +4440,15 @@
 shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)
 {
     typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
-    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
     typedef __allocator_destructor<_Alloc2> _D2;
     _Alloc2 __alloc2(__a);
     unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
-    ::new(__hold2.get()) _CntrlBlk(__a, __a0, __a1, __a2);
+    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
+        _CntrlBlk(__a, __a0, __a1, __a2);
     shared_ptr<_Tp> __r;
     __r.__ptr_ = __hold2.get()->get();
-    __r.__cntrl_ = __hold2.release();
+    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
     __r.__enable_weak_this(__r.__ptr_);
     return __r;
 }
@@ -5262,7 +5276,7 @@
 basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
 
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 class _LIBCPP_TYPE_VIS __sp_mut
 {
@@ -5388,7 +5402,7 @@
     return atomic_compare_exchange_weak(__p, __v, __w);
 }
 
-#endif  // __has_feature(cxx_atomic)
+#endif  // __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 //enum class
 struct _LIBCPP_TYPE_VIS pointer_safety
diff --git a/include/module.modulemap b/include/module.modulemap
index a0f4254..6aeb23f 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -16,6 +16,7 @@
   module atomic {
     header "atomic"
     export *
+    requires cplusplus11
   }
   module bitset {
     header "bitset"
diff --git a/include/mutex b/include/mutex
index 5dfba63..9c26356 100644
--- a/include/mutex
+++ b/include/mutex
@@ -187,6 +187,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 class _LIBCPP_TYPE_VIS recursive_mutex
 {
     pthread_mutex_t __m_;
@@ -425,6 +427,8 @@
 
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 struct _LIBCPP_TYPE_VIS_ONLY once_flag;
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
diff --git a/include/numeric b/include/numeric
index e520c8e..21c3781 100644
--- a/include/numeric
+++ b/include/numeric
@@ -91,7 +91,7 @@
 _Tp
 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
 {
-    for (; __first1 != __last1; ++__first1, ++__first2)
+    for (; __first1 != __last1; ++__first1, (void) ++__first2)
         __init = __init + *__first1 * *__first2;
     return __init;
 }
@@ -102,7 +102,7 @@
 inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
               _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
 {
-    for (; __first1 != __last1; ++__first1, ++__first2)
+    for (; __first1 != __last1; ++__first1, (void) ++__first2)
         __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
     return __init;
 }
@@ -116,7 +116,7 @@
     {
         typename iterator_traits<_InputIterator>::value_type __t(*__first);
         *__result = __t;
-        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
             __t = __t + *__first;
             *__result = __t;
@@ -135,7 +135,7 @@
     {
         typename iterator_traits<_InputIterator>::value_type __t(*__first);
         *__result = __t;
-        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
             __t = __binary_op(__t, *__first);
             *__result = __t;
@@ -153,7 +153,7 @@
     {
         typename iterator_traits<_InputIterator>::value_type __t1(*__first);
         *__result = __t1;
-        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
             typename iterator_traits<_InputIterator>::value_type __t2(*__first);
             *__result = __t2 - __t1;
@@ -173,7 +173,7 @@
     {
         typename iterator_traits<_InputIterator>::value_type __t1(*__first);
         *__result = __t1;
-        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result)
         {
             typename iterator_traits<_InputIterator>::value_type __t2(*__first);
             *__result = __binary_op(__t2, __t1);
@@ -188,7 +188,7 @@
 void
 iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
 {
-    for (; __first != __last; ++__first, ++__value_)
+    for (; __first != __last; ++__first, (void) ++__value_)
         *__first = __value_;
 }
 
diff --git a/include/ostream b/include/ostream
index 9d96fd8..a7af299 100644
--- a/include/ostream
+++ b/include/ostream
@@ -67,6 +67,13 @@
     pos_type tellp();
     basic_ostream& seekp(pos_type);
     basic_ostream& seekp(off_type, ios_base::seekdir);
+protected:
+    basic_ostream(const basic_ostream& rhs) = delete;
+    basic_ostream(basic_ostream&& rhs);
+    // 27.7.3.3 Assign/swap
+    basic_ostream& operator=(basic_ostream& rhs) = delete;
+    basic_ostream& operator=(const basic_ostream&& rhs);
+    void swap(basic_ostream& rhs);
 };
 
 // 27.7.2.6.4 character inserters
@@ -162,14 +169,19 @@
 #endif
 
     // 27.7.2.3 Assign/swap
-#if _LIBCPP_STD_VER > 11
-    basic_ostream& operator=(const basic_ostream&) = delete;
-#endif
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
     basic_ostream& operator=(basic_ostream&& __rhs);
 #endif
     void swap(basic_ostream& __rhs);
+
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    basic_ostream           (const basic_ostream& __rhs) = delete;
+    basic_ostream& operator=(const basic_ostream& __rhs) = delete;
+#else
+    basic_ostream           (const basic_ostream& __rhs); // not defined
+    basic_ostream& operator=(const basic_ostream& __rhs); // not defined
+#endif
 public:
 
     // 27.7.2.4 Prefix/suffix:
diff --git a/include/random b/include/random
index c0db1ab..e7053ce 100644
--- a/include/random
+++ b/include/random
@@ -4009,6 +4009,8 @@
     }
 }
 
+// Reference: Kemp, C.D. (1986). `A modal method for generating binomial
+//           variables', Commun. Statist. - Theor. Meth. 15(3), 805-813.
 template<class _IntType>
 template<class _URNG>
 _IntType
@@ -4035,7 +4037,8 @@
             if (__u < 0)
                 return __rd - 1;
         }
-        --__rd;
+        if ( __rd != 0 )
+            --__rd;
         ++__ru;
         if (__ru <= __pr.__t_)
         {
diff --git a/include/shared_mutex b/include/shared_mutex
index 00f816d..9b7f0bf 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -112,6 +112,10 @@
 #pragma GCC system_header
 #endif
 
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error <shared_mutex> is not supported on this single threaded system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 class _LIBCPP_TYPE_VIS shared_timed_mutex
@@ -414,6 +418,8 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif  // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_STD_VER > 11
 
 #endif  // _LIBCPP_SHARED_MUTEX
diff --git a/include/sstream b/include/sstream
index f90d446..27ae78f 100644
--- a/include/sstream
+++ b/include/sstream
@@ -325,11 +325,16 @@
     __p = const_cast<char_type*>(__str_.data());
     if (__binp != -1)
         this->setg(__p + __binp, __p + __ninp, __p + __einp);
+    else
+        this->setg(nullptr, nullptr, nullptr);
     if (__bout != -1)
     {
         this->setp(__p + __bout, __p + __eout);
         this->pbump(__nout);
     }
+    else
+        this->setp(nullptr, nullptr);
+
     __hm_ = __hm == -1 ? nullptr : __p + __hm;
     __mode_ = __rhs.__mode_;
     __p = const_cast<char_type*>(__rhs.__str_.data());
diff --git a/include/string b/include/string
index cb30d04..fe42bbf 100644
--- a/include/string
+++ b/include/string
@@ -453,6 +453,8 @@
 
 #include <__undef_min_max>
 
+#include <__debug>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -507,14 +509,11 @@
     typedef streampos pos_type;
     typedef mbstate_t state_type;
 
-    _LIBCPP_INLINE_VISIBILITY
-    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
         {__c1 = __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
     static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
@@ -524,20 +523,15 @@
     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
     static char_type*       assign(char_type* __s, size_t __n, char_type __a);
 
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
         {return int_type(EOF);}
 };
 
@@ -634,51 +628,37 @@
     typedef streampos pos_type;
     typedef mbstate_t state_type;
 
-    _LIBCPP_INLINE_VISIBILITY
-    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
         {__c1 = __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
             {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return (unsigned char)__c1 < (unsigned char)__c2;}
 
-    _LIBCPP_INLINE_VISIBILITY
-    static int compare(const char_type* __s1, const char_type* __s2, size_t __n)
+    static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n)
         {return memcmp(__s1, __s2, __n);}
-    _LIBCPP_INLINE_VISIBILITY
-    static size_t length(const char_type* __s) {return strlen(__s);}
-    _LIBCPP_INLINE_VISIBILITY
-    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
+    static inline size_t length(const char_type* __s) {return strlen(__s);}
+    static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
         {return (const char_type*)memchr(__s, to_int_type(__a), __n);}
-    _LIBCPP_INLINE_VISIBILITY
-    static char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
+    static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
         {return (char_type*)memmove(__s1, __s2, __n);}
-    _LIBCPP_INLINE_VISIBILITY
-    static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
+    static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
         {
             _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
             return (char_type*)memcpy(__s1, __s2, __n);
         }
-    _LIBCPP_INLINE_VISIBILITY
-    static char_type* assign(char_type* __s, size_t __n, char_type __a)
+    static inline char_type* assign(char_type* __s, size_t __n, char_type __a)
         {return (char_type*)memset(__s, to_int_type(__a), __n);}
 
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type((unsigned char)__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
         {return int_type(EOF);}
 };
 
@@ -693,52 +673,38 @@
     typedef streampos pos_type;
     typedef mbstate_t state_type;
 
-    _LIBCPP_INLINE_VISIBILITY
-    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
         {__c1 = __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
-    _LIBCPP_INLINE_VISIBILITY
-    static int compare(const char_type* __s1, const char_type* __s2, size_t __n)
+    static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n)
         {return wmemcmp(__s1, __s2, __n);}
-    _LIBCPP_INLINE_VISIBILITY
-    static size_t length(const char_type* __s)
+    static inline size_t length(const char_type* __s)
         {return wcslen(__s);}
-    _LIBCPP_INLINE_VISIBILITY
-    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
+    static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
         {return (const char_type*)wmemchr(__s, __a, __n);}
-    _LIBCPP_INLINE_VISIBILITY
-    static char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
+    static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
         {return (char_type*)wmemmove(__s1, __s2, __n);}
-    _LIBCPP_INLINE_VISIBILITY
-    static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
+    static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
         {
             _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
             return (char_type*)wmemcpy(__s1, __s2, __n);
         }
-    _LIBCPP_INLINE_VISIBILITY
-    static char_type* assign(char_type* __s, size_t __n, char_type __a)
+    static inline char_type* assign(char_type* __s, size_t __n, char_type __a)
         {return (char_type*)wmemset(__s, __a, __n);}
 
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
         {return int_type(WEOF);}
 };
 
@@ -753,14 +719,11 @@
     typedef u16streampos   pos_type;
     typedef mbstate_t      state_type;
 
-    _LIBCPP_INLINE_VISIBILITY
-    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
         {__c1 = __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
     static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
@@ -770,20 +733,15 @@
     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
     static char_type*       assign(char_type* __s, size_t __n, char_type __a);
 
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
         {return int_type(0xDFFF);}
 };
 
@@ -874,14 +832,11 @@
     typedef u32streampos   pos_type;
     typedef mbstate_t      state_type;
 
-    _LIBCPP_INLINE_VISIBILITY
-    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+    static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
         {__c1 = __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
         {return __c1 < __c2;}
 
     static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
@@ -891,20 +846,15 @@
     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
     static char_type*       assign(char_type* __s, size_t __n, char_type __a);
 
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
         {return char_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
         {return int_type(__c);}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
         {return __c1 == __c2;}
-    _LIBCPP_INLINE_VISIBILITY
-    static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+    static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
         {return int_type(0xFFFFFFFF);}
 };
 
@@ -990,10 +940,10 @@
 
 // helper fns for basic_string
 
-// __find
+// __str_find
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__find(const _CharT *__p, _SizeT __sz, 
+__str_find(const _CharT *__p, _SizeT __sz, 
              _CharT __c, _SizeT __pos) _NOEXCEPT
 {
     if (__pos >= __sz)
@@ -1006,28 +956,28 @@
 
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__find(const _CharT *__p, _SizeT __sz, 
+__str_find(const _CharT *__p, _SizeT __sz, 
        const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
 {
     if (__pos > __sz || __sz - __pos < __n)
         return __npos;
     if (__n == 0)
         return __pos;
-//     if (__n == 1)
-//     	return _VSTD::__find<_CharT, _SizeT, _Traits, __npos>(__p, __sz, *__s, __pos);
     const _CharT* __r = 
-            _VSTD::search(__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq);
+        _VSTD::__search(__p + __pos, __p + __sz,
+                        __s, __s + __n, _Traits::eq,
+                        random_access_iterator_tag(), random_access_iterator_tag());
     if (__r == __p + __sz)
         return __npos;
     return static_cast<_SizeT>(__r - __p);
 }
 
 
-// __rfind
+// __str_rfind
 
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__rfind(const _CharT *__p, _SizeT __sz, 
+__str_rfind(const _CharT *__p, _SizeT __sz, 
               _CharT __c, _SizeT __pos) _NOEXCEPT
 {
     if (__sz < 1)
@@ -1046,7 +996,7 @@
 
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__rfind(const _CharT *__p, _SizeT __sz, 
+__str_rfind(const _CharT *__p, _SizeT __sz, 
         const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
 {
     __pos = _VSTD::min(__pos, __sz);
@@ -1054,21 +1004,23 @@
         __pos += __n;
     else
         __pos = __sz;
-    const _CharT* __r = _VSTD::find_end(__p, __p + __pos, __s, __s + __n, _Traits::eq);
+    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);
 }
 
-// __find_first_of
+// __str_find_first_of
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__find_first_of(const _CharT *__p, _SizeT __sz,
+__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
+    const _CharT* __r = _VSTD::__find_first_of_ce
         (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
     if (__r == __p + __sz)
         return __npos;
@@ -1076,10 +1028,10 @@
 }
 
 
-// __find_last_of
+// __str_find_last_of
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 
-__find_last_of(const _CharT *__p, _SizeT __sz,
+__str_find_last_of(const _CharT *__p, _SizeT __sz,
                const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
     {
     if (__n != 0)
@@ -1099,10 +1051,10 @@
 }
 
 
-// __find_first_not_of
+// __str_find_first_not_of
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__find_first_not_of(const _CharT *__p, _SizeT __sz,
+__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
                     const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
 {
     if (__pos < __sz)
@@ -1118,7 +1070,7 @@
 
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__find_first_not_of(const _CharT *__p, _SizeT __sz,
+__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
                           _CharT __c, _SizeT __pos) _NOEXCEPT
 {
     if (__pos < __sz)
@@ -1132,10 +1084,10 @@
 }
 
 
-// __find_last_not_of
+// __str_find_last_not_of
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__find_last_not_of(const _CharT *__p, _SizeT __sz,
+__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
                    const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
 {
     if (__pos < __sz)
@@ -1151,7 +1103,7 @@
 
 template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
 _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
-__find_last_not_of(const _CharT *__p, _SizeT __sz,
+__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
                          _CharT __c, _SizeT __pos) _NOEXCEPT
 {
     if (__pos < __sz)
@@ -2263,7 +2215,7 @@
         __set_long_cap(__cap+1);
         __set_long_size(__sz);
     }
-    for (; __first != __last; ++__first, ++__p)
+    for (; __first != __last; ++__first, (void) ++__p)
         traits_type::assign(*__p, *__first);
     traits_type::assign(*__p, value_type());
 }
@@ -3429,7 +3381,7 @@
                                                 size_type __n) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
-    return _VSTD::__find<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
 
@@ -3439,7 +3391,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
                                                 size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
         (data(), size(), __str.data(), __pos, __str.size());
 }
 
@@ -3450,7 +3402,7 @@
                                                 size_type __pos) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
-    return _VSTD::__find<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
 
@@ -3459,7 +3411,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
                                                 size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
         (data(), size(), __c, __pos);
 }
 
@@ -3472,7 +3424,7 @@
                                                  size_type __n) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
-    return _VSTD::__rfind<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
 
@@ -3482,7 +3434,7 @@
 basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
                                                  size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__rfind<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
         (data(), size(), __str.data(), __pos, __str.size());
 }
 
@@ -3493,7 +3445,7 @@
                                                  size_type __pos) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
-    return _VSTD::__rfind<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
 
@@ -3502,7 +3454,7 @@
 basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
                                                  size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__rfind<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
         (data(), size(), __c, __pos);
 }
 
@@ -3515,7 +3467,7 @@
                                                          size_type __n) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
-    return _VSTD::__find_first_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
 
@@ -3525,7 +3477,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
                                                          size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find_first_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
         (data(), size(), __str.data(), __pos, __str.size());
 }
 
@@ -3536,7 +3488,7 @@
                                                          size_type __pos) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
-    return _VSTD::__find_first_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
 
@@ -3558,7 +3510,7 @@
                                                         size_type __n) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
-    return _VSTD::__find_last_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
 
@@ -3568,7 +3520,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
                                                         size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find_last_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
         (data(), size(), __str.data(), __pos, __str.size());
 }
 
@@ -3579,7 +3531,7 @@
                                                         size_type __pos) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
-    return _VSTD::__find_last_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
 
@@ -3601,7 +3553,7 @@
                                                              size_type __n) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
-    return _VSTD::__find_first_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
 
@@ -3611,7 +3563,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
                                                              size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find_first_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __str.data(), __pos, __str.size());
 }
 
@@ -3622,7 +3574,7 @@
                                                              size_type __pos) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
-    return _VSTD::__find_first_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
 
@@ -3632,7 +3584,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
                                                              size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find_first_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __c, __pos);
 }
 
@@ -3645,7 +3597,7 @@
                                                             size_type __n) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
-    return _VSTD::__find_last_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, __n);
 }
 
@@ -3655,7 +3607,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
                                                             size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find_last_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __str.data(), __pos, __str.size());
 }
 
@@ -3666,7 +3618,7 @@
                                                             size_type __pos) const _NOEXCEPT
 {
     _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
-    return _VSTD::__find_last_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __s, __pos, traits_type::length(__s));
 }
 
@@ -3676,7 +3628,7 @@
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
                                                             size_type __pos) const _NOEXCEPT
 {
-    return _VSTD::__find_last_not_of<value_type, size_type, traits_type, npos>
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
         (data(), size(), __c, __pos);
 }
 
diff --git a/include/support/android/locale_bionic.h b/include/support/android/locale_bionic.h
index 354fcfe..3a020da 100644
--- a/include/support/android/locale_bionic.h
+++ b/include/support/android/locale_bionic.h
@@ -20,173 +20,12 @@
 #include <stdlib.h>
 #include <xlocale.h>
 
-static inline int isalnum_l(int c, locale_t) {
-  return isalnum(c);
-}
-
-static inline int isalpha_l(int c, locale_t) {
-  return isalpha(c);
-}
-
-static inline int isblank_l(int c, locale_t) {
-  return isblank(c);
-}
-
-static inline int iscntrl_l(int c, locale_t) {
-  return iscntrl(c);
-}
-
-static inline int isdigit_l(int c, locale_t) {
-  return isdigit(c);
-}
-
-static inline int isgraph_l(int c, locale_t) {
-  return isgraph(c);
-}
-
-static inline int islower_l(int c, locale_t) {
-  return islower(c);
-}
-
-static inline int isprint_l(int c, locale_t) {
-  return isprint(c);
-}
-
-static inline int ispunct_l(int c, locale_t) {
-  return ispunct(c);
-}
-
-static inline int isspace_l(int c, locale_t) {
-  return isspace(c);
-}
-
-static inline int isupper_l(int c, locale_t) {
-  return isupper(c);
-}
-
-static inline int isxdigit_l(int c, locale_t) {
-  return isxdigit(c);
-}
-
-static inline int iswalnum_l(wint_t c, locale_t) {
-  return iswalnum(c);
-}
-
-static inline int iswalpha_l(wint_t c, locale_t) {
-  return iswalpha(c);
-}
-
-static inline int iswblank_l(wint_t c, locale_t) {
-  return iswblank(c);
-}
-
-static inline int iswcntrl_l(wint_t c, locale_t) {
-  return iswcntrl(c);
-}
-
-static inline int iswdigit_l(wint_t c, locale_t) {
-  return iswdigit(c);
-}
-
-static inline int iswgraph_l(wint_t c, locale_t) {
-  return iswgraph(c);
-}
-
-static inline int iswlower_l(wint_t c, locale_t) {
-  return iswlower(c);
-}
-
-static inline int iswprint_l(wint_t c, locale_t) {
-  return iswprint(c);
-}
-
-static inline int iswpunct_l(wint_t c, locale_t) {
-  return iswpunct(c);
-}
-
-static inline int iswspace_l(wint_t c, locale_t) {
-  return iswspace(c);
-}
-
-static inline int iswupper_l(wint_t c, locale_t) {
-  return iswupper(c);
-}
-
-static inline int iswxdigit_l(wint_t c, locale_t) {
-  return iswxdigit(c);
-}
-
-static inline int toupper_l(int c, locale_t) {
-  return toupper(c);
-}
-
-static inline int tolower_l(int c, locale_t) {
-  return tolower(c);
-}
-
-static inline int towupper_l(int c, locale_t) {
-  return towupper(c);
-}
-
-static inline int towlower_l(int c, locale_t) {
-  return towlower(c);
-}
-
-static inline int strcoll_l(const char *s1, const char *s2, locale_t) {
-  return strcoll(s1, s2);
-}
-
-static inline size_t strxfrm_l(char *dest, const char *src, size_t n,
-                               locale_t) {
-  return strxfrm(dest, src, n);
-}
-
-static inline size_t strftime_l(char *s, size_t max, const char *format,
-                                const struct tm *tm, locale_t) {
-  return strftime(s, max, format, tm);
-}
-
-static inline int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {
-  return wcscoll(ws1, ws2);
-}
-
-static inline size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n,
-                               locale_t) {
-  return wcsxfrm(dest, src, n);
-}
-
-static inline long double strtold_l(const char *nptr, char **endptr, locale_t) {
-  return strtold(nptr, endptr);
-}
-
-static inline long long strtoll_l(const char *nptr, char **endptr, size_t base,
-                                  locale_t) {
-  return strtoll(nptr, endptr, base);
-}
-
-static inline unsigned long long strtoull_l(const char *nptr, char **endptr,
-                                            size_t base, locale_t) {
-  return strtoull(nptr, endptr, base);
-}
-
-static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr,
-                                  size_t base, locale_t) {
-  return wcstoll(nptr, endptr, base);
-}
-
-static inline unsigned long long wcstoull_l(const wchar_t *nptr,
-                                            wchar_t **endptr, size_t 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
+
+// Share implementation with Newlib
+#include <support/xlocale/xlocale.h>
+
 #endif // defined(__ANDROID__)
 #endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
diff --git a/include/support/newlib/xlocale.h b/include/support/newlib/xlocale.h
new file mode 100644
index 0000000..d067cf8
--- /dev/null
+++ b/include/support/newlib/xlocale.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#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>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Patch over newlib's lack of extended locale support
+typedef void *locale_t;
+static inline locale_t duplocale(locale_t) {
+  return NULL;
+}
+
+static inline void freelocale(locale_t) {
+}
+
+static inline locale_t newlocale(int, const char *, locale_t) {
+  return NULL;
+}
+
+static inline locale_t uselocale(locale_t) {
+  return NULL;
+}
+
+#define LC_COLLATE_MASK  (1 << LC_COLLATE)
+#define LC_CTYPE_MASK    (1 << LC_CTYPE)
+#define LC_MESSAGES_MASK (1 << LC_MESSAGES)
+#define LC_MONETARY_MASK (1 << LC_MONETARY)
+#define LC_NUMERIC_MASK  (1 << LC_NUMERIC)
+#define LC_TIME_MASK     (1 << LC_TIME)
+#define LC_ALL_MASK (LC_COLLATE_MASK|\
+                     LC_CTYPE_MASK|\
+                     LC_MONETARY_MASK|\
+                     LC_NUMERIC_MASK|\
+                     LC_TIME_MASK|\
+                     LC_MESSAGES_MASK)
+
+// Share implementation with Android's Bionic
+#include <support/xlocale/xlocale.h>
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _NEWLIB_VERSION
+
+#endif
diff --git a/include/support/xlocale/xlocale.h b/include/support/xlocale/xlocale.h
new file mode 100644
index 0000000..99f710e
--- /dev/null
+++ b/include/support/xlocale/xlocale.h
@@ -0,0 +1,194 @@
+// -*- C++ -*-
+//===------------------- support/xlocale/xlocale.h ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This is a shared implementation of a shim to provide extended locale support
+// on top of libc's that don't support it (like Android's bionic, and Newlib).
+//
+// The 'illusion' only works when the specified locale is "C" or "POSIX", but
+// that's about as good as we can do without implementing full xlocale support
+// in the underlying libc.
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H
+#define _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int isalnum_l(int c, locale_t) {
+  return isalnum(c);
+}
+
+static inline int isalpha_l(int c, locale_t) {
+  return isalpha(c);
+}
+
+static inline int isblank_l(int c, locale_t) {
+  return isblank(c);
+}
+
+static inline int iscntrl_l(int c, locale_t) {
+  return iscntrl(c);
+}
+
+static inline int isdigit_l(int c, locale_t) {
+  return isdigit(c);
+}
+
+static inline int isgraph_l(int c, locale_t) {
+  return isgraph(c);
+}
+
+static inline int islower_l(int c, locale_t) {
+  return islower(c);
+}
+
+static inline int isprint_l(int c, locale_t) {
+  return isprint(c);
+}
+
+static inline int ispunct_l(int c, locale_t) {
+  return ispunct(c);
+}
+
+static inline int isspace_l(int c, locale_t) {
+  return isspace(c);
+}
+
+static inline int isupper_l(int c, locale_t) {
+  return isupper(c);
+}
+
+static inline int isxdigit_l(int c, locale_t) {
+  return isxdigit(c);
+}
+
+static inline int iswalnum_l(wint_t c, locale_t) {
+  return iswalnum(c);
+}
+
+static inline int iswalpha_l(wint_t c, locale_t) {
+  return iswalpha(c);
+}
+
+static inline int iswblank_l(wint_t c, locale_t) {
+  return iswblank(c);
+}
+
+static inline int iswcntrl_l(wint_t c, locale_t) {
+  return iswcntrl(c);
+}
+
+static inline int iswdigit_l(wint_t c, locale_t) {
+  return iswdigit(c);
+}
+
+static inline int iswgraph_l(wint_t c, locale_t) {
+  return iswgraph(c);
+}
+
+static inline int iswlower_l(wint_t c, locale_t) {
+  return iswlower(c);
+}
+
+static inline int iswprint_l(wint_t c, locale_t) {
+  return iswprint(c);
+}
+
+static inline int iswpunct_l(wint_t c, locale_t) {
+  return iswpunct(c);
+}
+
+static inline int iswspace_l(wint_t c, locale_t) {
+  return iswspace(c);
+}
+
+static inline int iswupper_l(wint_t c, locale_t) {
+  return iswupper(c);
+}
+
+static inline int iswxdigit_l(wint_t c, locale_t) {
+  return iswxdigit(c);
+}
+
+static inline int toupper_l(int c, locale_t) {
+  return toupper(c);
+}
+
+static inline int tolower_l(int c, locale_t) {
+  return tolower(c);
+}
+
+static inline int towupper_l(int c, locale_t) {
+  return towupper(c);
+}
+
+static inline int towlower_l(int c, locale_t) {
+  return towlower(c);
+}
+
+static inline int strcoll_l(const char *s1, const char *s2, locale_t) {
+  return strcoll(s1, s2);
+}
+
+static inline size_t strxfrm_l(char *dest, const char *src, size_t n,
+                               locale_t) {
+  return strxfrm(dest, src, n);
+}
+
+static inline size_t strftime_l(char *s, size_t max, const char *format,
+                                const struct tm *tm, locale_t) {
+  return strftime(s, max, format, tm);
+}
+
+static inline int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {
+  return wcscoll(ws1, ws2);
+}
+
+static inline size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n,
+                               locale_t) {
+  return wcsxfrm(dest, src, n);
+}
+
+static inline long double strtold_l(const char *nptr, char **endptr, locale_t) {
+  return strtold(nptr, endptr);
+}
+
+static inline long long strtoll_l(const char *nptr, char **endptr, int base,
+                                  locale_t) {
+  return strtoll(nptr, endptr, base);
+}
+
+static inline unsigned long long strtoull_l(const char *nptr, char **endptr,
+                                            int base, locale_t) {
+  return strtoull(nptr, endptr, base);
+}
+
+static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr,
+                                  int base, locale_t) {
+  return wcstoll(nptr, endptr, base);
+}
+
+static inline unsigned long long wcstoull_l(const wchar_t *nptr,
+                                            wchar_t **endptr, int base,
+                                            locale_t) {
+  return wcstoull(nptr, endptr, base);
+}
+
+static inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr,
+                                    locale_t) {
+  return wcstold(nptr, endptr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H
diff --git a/include/thread b/include/thread
index 1f1e4a2..808d76b 100644
--- a/include/thread
+++ b/include/thread
@@ -106,6 +106,10 @@
 
 #define __STDCPP_THREADS__ __cplusplus
 
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error <thread> is not supported on this single threaded system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
@@ -455,4 +459,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_THREAD
diff --git a/include/tuple b/include/tuple
index c3fdd40..aa7185c 100644
--- a/include/tuple
+++ b/include/tuple
@@ -376,19 +376,18 @@
 _LIBCPP_INLINE_VISIBILITY
 void __swallow(_Tp&&...) _NOEXCEPT {}
 
-template <bool ...> struct __all;
+template <bool ..._B>
+struct __all
+    : is_same<__all<_B...>, __all<(_B, true)...>>
+{ };
 
-template <>
-struct __all<>
-{
-    static const bool value = true;
-};
+template <class _Tp>
+struct __all_default_constructible;
 
-template <bool _B0, bool ... _Bp>
-struct __all<_B0, _Bp...>
-{
-    static const bool value = _B0 && __all<_Bp...>::value;
-};
+template <class ..._Tp>
+struct __all_default_constructible<__tuple_types<_Tp...>>
+    : __all<is_default_constructible<_Tp>::value...>
+{ };
 
 // __tuple_impl
 
@@ -512,6 +511,9 @@
         typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
 public:
 
+    template <bool _Dummy = true, class _Up = typename enable_if<
+        __all<(_Dummy && is_default_constructible<_Tp>::value)...>::value
+    >::type>
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR tuple()
         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
@@ -547,6 +549,12 @@
                                      sizeof...(_Up) < sizeof...(_Tp) ?
                                         sizeof...(_Up) :
                                         sizeof...(_Tp)>::type
+                         >::value &&
+                         __all_default_constructible<
+                            typename __make_tuple_types<tuple, sizeof...(_Tp),
+                                sizeof...(_Up) < sizeof...(_Tp) ?
+                                    sizeof...(_Up) :
+                                    sizeof...(_Tp)>::type
                          >::value,
                          bool
                       >::type = false
@@ -554,7 +562,7 @@
         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         tuple(_Up&&... __u)
             _NOEXCEPT_((
-                is_nothrow_constructible<
+                is_nothrow_constructible<base,
                     typename __make_tuple_indices<sizeof...(_Up)>::type,
                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
@@ -587,6 +595,12 @@
                                      sizeof...(_Up) < sizeof...(_Tp) ?
                                         sizeof...(_Up) :
                                         sizeof...(_Tp)>::type
+                         >::value &&
+                         __all_default_constructible<
+                            typename __make_tuple_types<tuple, sizeof...(_Tp),
+                                sizeof...(_Up) < sizeof...(_Tp) ?
+                                    sizeof...(_Up) :
+                                    sizeof...(_Tp)>::type
                          >::value,
                          bool
                       >::type =false
@@ -595,7 +609,7 @@
         explicit
         tuple(_Up&&... __u)
             _NOEXCEPT_((
-                is_nothrow_constructible<
+                is_nothrow_constructible<base,
                     typename __make_tuple_indices<sizeof...(_Up)>::type,
                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
@@ -620,6 +634,12 @@
                                      sizeof...(_Up) < sizeof...(_Tp) ?
                                         sizeof...(_Up) :
                                         sizeof...(_Tp)>::type
+                         >::value &&
+                         __all_default_constructible<
+                            typename __make_tuple_types<tuple, sizeof...(_Tp),
+                                sizeof...(_Up) < sizeof...(_Tp) ?
+                                    sizeof...(_Up) :
+                                    sizeof...(_Tp)>::type
                          >::value
                       >::type
              >
diff --git a/include/type_traits b/include/type_traits
index c0e1a6d..f467735 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -197,7 +197,9 @@
     template <class F, class... ArgTypes>
       using result_of_t       = typename result_of<F(ArgTypes...)>::type;  // C++14
 
-}  // std
+    template <class...>
+      using void_t = void;
+}  // C++17
 
 */
 #include <__config>
@@ -209,6 +211,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+template <class...> 
+struct __void_t { typedef void type; };
+#endif
+
 template <bool _Bp, class _If, class _Then>
     struct _LIBCPP_TYPE_VIS_ONLY conditional {typedef _If type;};
 template <class _If, class _Then>
@@ -218,6 +225,9 @@
 template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
 #endif
 
+template <bool, class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if<true, _Tp> {typedef typename _Tp::type type;};
+
 template <bool, class _Tp = void> struct _LIBCPP_TYPE_VIS_ONLY enable_if {};
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY enable_if<true, _Tp> {typedef _Tp type;};
 
@@ -1208,43 +1218,46 @@
           bool = __numeric_type<_A1>::value &&
                  __numeric_type<_A2>::value &&
                  __numeric_type<_A3>::value>
-class __promote
+class __promote_imp
 {
+public:
     static const bool value = false;
 };
 
 template <class _A1, class _A2, class _A3>
-class __promote<_A1, _A2, _A3, true>
+class __promote_imp<_A1, _A2, _A3, true>
 {
 private:
-    typedef typename __promote<_A1>::type __type1;
-    typedef typename __promote<_A2>::type __type2;
-    typedef typename __promote<_A3>::type __type3;
+    typedef typename __promote_imp<_A1>::type __type1;
+    typedef typename __promote_imp<_A2>::type __type2;
+    typedef typename __promote_imp<_A3>::type __type3;
 public:
     typedef decltype(__type1() + __type2() + __type3()) type;
     static const bool value = true;
 };
 
 template <class _A1, class _A2>
-class __promote<_A1, _A2, void, true>
+class __promote_imp<_A1, _A2, void, true>
 {
 private:
-    typedef typename __promote<_A1>::type __type1;
-    typedef typename __promote<_A2>::type __type2;
+    typedef typename __promote_imp<_A1>::type __type1;
+    typedef typename __promote_imp<_A2>::type __type2;
 public:
     typedef decltype(__type1() + __type2()) type;
     static const bool value = true;
 };
 
 template <class _A1>
-class __promote<_A1, void, void, true>
+class __promote_imp<_A1, void, void, true>
 {
 public:
     typedef typename __numeric_type<_A1>::type type;
     static const bool value = true;
-    static const bool __does_not_throw = _NOEXCEPT_OR_FALSE(static_cast<type>(declval<_A1>()));
 };
 
+template <class _A1, class _A2 = void, class _A3 = void>
+class __promote : public __promote_imp<_A1, _A2, _A3> {};
+
 #ifdef _LIBCPP_STORE_AS_OPTIMIZATION
 
 // __transform
@@ -1523,7 +1536,7 @@
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_copy_assignable
     : public is_assignable<typename add_lvalue_reference<_Tp>::type,
-                     const typename add_lvalue_reference<_Tp>::type> {};
+                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
 // is_move_assignable
 
@@ -1537,11 +1550,11 @@
 
 // is_destructible
 
-//	if it's a reference, return true
-//	if it's a function, return false
-//	if it's   void,     return false
-//	if it's an array of unknown bound, return false
-//	Otherwise, return "std::declval<_Up&>().~_Up()" is well-formed
+//  if it's a reference, return true
+//  if it's a function, return false
+//  if it's   void,     return false
+//  if it's an array of unknown bound, return false
+//  Otherwise, return "std::declval<_Up&>().~_Up()" is well-formed
 //    where _Up is remove_all_extents<_Tp>::type
 
 template <class>
@@ -1549,15 +1562,15 @@
 
 template <typename _Tp>
 struct __is_destructor_wellformed {
-	template <typename _Tp1>
-	static char  __test (
+    template <typename _Tp1>
+    static char  __test (
         typename __is_destructible_apply<decltype(_VSTD::declval<_Tp1&>().~_Tp1())>::type
     );
 
-	template <typename _Tp1>
-	static __two __test (...);
-	
-	static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
+    template <typename _Tp1>
+    static __two __test (...);
+    
+    static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
 };
 
 template <class _Tp, bool>
@@ -2637,8 +2650,8 @@
 
 template <class _Tp>
 struct _LIBCPP_TYPE_VIS_ONLY is_copy_constructible
-    : public is_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
-    {};
+    : public is_constructible<_Tp, 
+                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
 // is_move_constructible
 
@@ -2842,8 +2855,7 @@
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_assignable
     : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
-                               const typename add_lvalue_reference<_Tp>::type>
-    {};
+                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
 // is_trivially_move_assignable
 
@@ -2861,7 +2873,7 @@
 #if __has_feature(has_trivial_destructor) || (_GNUC_VER >= 403)
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible
-    : public integral_constant<bool, __has_trivial_destructor(_Tp)> {};
+    : public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {};
 
 #else
 
@@ -2889,29 +2901,38 @@
 
 #if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
 
-template <bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
+template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
 
 template <class _Tp, class... _Args>
-struct __libcpp_is_nothrow_constructible<true, _Tp, _Args...>
+struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...>
     : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
 {
 };
 
-template <class _Tp, class... _Args>
-struct __libcpp_is_nothrow_constructible<false, _Tp, _Args...>
+template <class _Tp>
+void __implicit_conversion_to(_Tp) noexcept { }
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg>
+    : public integral_constant<bool, noexcept(__implicit_conversion_to<_Tp>(declval<_Arg>()))>
+{
+};
+
+template <class _Tp, bool _IsReference, class... _Args>
+struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...>
     : public false_type
 {
 };
 
 template <class _Tp, class... _Args>
 struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
-    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, _Tp, _Args...>
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...>
 {
 };
 
 template <class _Tp, size_t _Ns>
 struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]>
-    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, _Tp>
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp>
 {
 };
 
@@ -3034,8 +3055,8 @@
 // is_nothrow_copy_constructible
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_constructible
-    : public is_nothrow_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
-    {};
+    : public is_nothrow_constructible<_Tp,
+                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
 // is_nothrow_move_constructible
 
@@ -3119,8 +3140,7 @@
 
 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_assignable
     : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
-                               const typename add_lvalue_reference<_Tp>::type>
-    {};
+                  typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {};
 
 // is_nothrow_move_assignable
 
@@ -3629,24 +3649,41 @@
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
 
 template <class _Tp>
-struct __has_operator_addressof_imp
+struct __has_operator_addressof_member_imp
 {
-    template <class>
-        static auto __test(__any) -> false_type;
     template <class _Up>
-        static auto __test(_Up* __u)
-            -> typename __select_2nd<decltype(__u->operator&()), true_type>::type;
+        static auto __test(int)
+            -> typename __select_2nd<decltype(_VSTD::declval<_Up>().operator&()), true_type>::type;
+    template <class>
+        static auto __test(long) -> false_type;
 
-    static const bool value = decltype(__test<_Tp>(nullptr))::value;
+    static const bool value = decltype(__test<_Tp>(0))::value;
+};
+
+template <class _Tp>
+struct __has_operator_addressof_free_imp
+{
+    template <class _Up>
+        static auto __test(int)
+            -> typename __select_2nd<decltype(operator&(_VSTD::declval<_Up>())), true_type>::type;
+    template <class>
+        static auto __test(long) -> false_type;
+
+    static const bool value = decltype(__test<_Tp>(0))::value;
 };
 
 template <class _Tp>
 struct __has_operator_addressof
-    : public integral_constant<bool, __has_operator_addressof_imp<_Tp>::value>
+    : public integral_constant<bool, __has_operator_addressof_member_imp<_Tp>::value
+                                  || __has_operator_addressof_free_imp<_Tp>::value>
 {};
 
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
 
+#if _LIBCPP_STD_VER > 14
+template <class...> using void_t = void;
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_TYPE_TRAITS
diff --git a/include/unordered_map b/include/unordered_map
index 4e2298b..0fa87d1 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -351,6 +351,8 @@
 #include <functional>
 #include <stdexcept>
 
+#include <__debug>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
diff --git a/include/unordered_set b/include/unordered_set
index fd378fa..d06629f 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -325,6 +325,8 @@
 #include <__hash_table>
 #include <functional>
 
+#include <__debug>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
diff --git a/include/utility b/include/utility
index 4eafda4..6f324db 100644
--- a/include/utility
+++ b/include/utility
@@ -207,7 +207,7 @@
 _ForwardIterator2
 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2)
 {
-    for(; __first1 != __last1; ++__first1, ++__first2)
+    for(; __first1 != __last1; ++__first1, (void) ++__first2)
         swap(*__first1, *__first2);
     return __first2;
 }
diff --git a/include/vector b/include/vector
index 5d41bd1..22a6343 100644
--- a/include/vector
+++ b/include/vector
@@ -276,11 +276,7 @@
 
 #include <__undef_min_max>
 
-#ifdef _LIBCPP_DEBUG
-#   include <__debug>
-#else
-#   define _LIBCPP_ASSERT(x, m) ((void)0)
-#endif
+#include <__debug>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -788,7 +784,6 @@
             void
         >::type
         __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
-    void __move_construct_at_end(pointer __first, pointer __last);
     void __append(size_type __n);
     void __append(size_type __n, const_reference __x);
     _LIBCPP_INLINE_VISIBILITY
@@ -840,7 +835,7 @@
     // may not meet the AddressSanitizer alignment constraints.
     // See the documentation for __sanitizer_annotate_contiguous_container for more details.
     void __annotate_contiguous_container
-    (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid)
+    (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid) const
     {
 #ifndef _LIBCPP_HAS_NO_ASAN
       if (__beg && is_same<allocator_type, __default_allocator_type>::value)
@@ -848,26 +843,50 @@
 #endif
     }
 
-    void __annotate_new(size_type __current_size)
+    void __annotate_new(size_type __current_size) const
     {
       __annotate_contiguous_container(data(), data() + capacity(),
                                       data() + capacity(), data() + __current_size);
     }
-    void __annotate_delete()
+    void __annotate_delete() const
     {
       __annotate_contiguous_container(data(), data() + capacity(),
                                       data() + size(), data() + capacity());
     }
-    void __annotate_increase(size_type __n)
+    void __annotate_increase(size_type __n) const
     {
       __annotate_contiguous_container(data(), data() + capacity(),
                                       data() + size(), data() + size() + __n);
     }
-    void __annotate_shrink(size_type __old_size)
+    void __annotate_shrink(size_type __old_size) const
     {
       __annotate_contiguous_container(data(), data() + capacity(),
                                       data() + __old_size, data() + size());
     }
+#ifndef _LIBCPP_HAS_NO_ASAN
+    // The annotation for size increase should happen before the actual increase,
+    // but if an exception is thrown after that the annotation has to be undone.
+    struct __RAII_IncreaseAnnotator {
+      __RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1)
+        : __commit(false), __v(__v), __n(__n) {
+        __v.__annotate_increase(__n);
+      }
+      void __done() { __commit = true; }
+      ~__RAII_IncreaseAnnotator() {
+        if (__commit) return;
+        __v.__annotate_shrink(__v.size() + __n);
+      }
+      bool __commit;
+      size_type __n;
+      const vector &__v;
+    };
+#else
+    struct __RAII_IncreaseAnnotator {
+      inline __RAII_IncreaseAnnotator(const vector &, size_type __n = 1) {}
+      inline void __done() {}
+    };
+#endif
+
 };
 
 template <class _Tp, class _Allocator>
@@ -963,12 +982,13 @@
 vector<_Tp, _Allocator>::__construct_at_end(size_type __n)
 {
     allocator_type& __a = this->__alloc();
-    __annotate_increase(__n);
     do
     {
+        __RAII_IncreaseAnnotator __annotator(*this);
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
         ++this->__end_;
         --__n;
+        __annotator.__done();
     } while (__n > 0);
 }
 
@@ -984,12 +1004,13 @@
 vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
 {
     allocator_type& __a = this->__alloc();
-    __annotate_increase(__n);
     do
     {
+        __RAII_IncreaseAnnotator __annotator(*this);
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
         ++this->__end_;
         --__n;
+        __annotator.__done();
     } while (__n > 0);
 }
 
@@ -1005,22 +1026,9 @@
     allocator_type& __a = this->__alloc();
     for (; __first != __last; ++__first)
     {
-        __annotate_increase(1);
+        __RAII_IncreaseAnnotator __annotator(*this);
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
-        ++this->__end_;
-    }
-}
-
-template <class _Tp, class _Allocator>
-void
-vector<_Tp, _Allocator>::__move_construct_at_end(pointer __first, pointer __last)
-{
-    allocator_type& __a = this->__alloc();
-    for (; __first != __last; ++__first)
-    {
-        __annotate_increase(1);
-        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
-                                  _VSTD::move(*__first));
+        __annotator.__done();
         ++this->__end_;
     }
 }
@@ -1582,9 +1590,10 @@
 {
     if (this->__end_ != this->__end_cap())
     {
-        __annotate_increase(1);
+        __RAII_IncreaseAnnotator __annotator(*this);
         __alloc_traits::construct(this->__alloc(),
                                   _VSTD::__to_raw_pointer(this->__end_), __x);
+        __annotator.__done();
         ++this->__end_;
     }
     else
@@ -1600,10 +1609,11 @@
 {
     if (this->__end_ < this->__end_cap())
     {
-        __annotate_increase(1);
+        __RAII_IncreaseAnnotator __annotator(*this);
         __alloc_traits::construct(this->__alloc(),
                                   _VSTD::__to_raw_pointer(this->__end_),
                                   _VSTD::move(__x));
+        __annotator.__done();
         ++this->__end_;
     }
     else
@@ -1633,10 +1643,11 @@
 {
     if (this->__end_ < this->__end_cap())
     {
-        __annotate_increase(1);
+        __RAII_IncreaseAnnotator __annotator(*this);
         __alloc_traits::construct(this->__alloc(),
                                   _VSTD::__to_raw_pointer(this->__end_),
                                   _VSTD::forward<_Args>(__args)...);
+        __annotator.__done();
         ++this->__end_;
     }
     else
@@ -1716,7 +1727,7 @@
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
-        __annotate_increase(1);
+        __RAII_IncreaseAnnotator __annotator(*this);
         if (__p == this->__end_)
         {
             __alloc_traits::construct(this->__alloc(),
@@ -1731,6 +1742,7 @@
                 ++__xr;
             *__p = *__xr;
         }
+        __annotator.__done();
     }
     else
     {
@@ -1756,7 +1768,7 @@
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
-        __annotate_increase(1);
+        __RAII_IncreaseAnnotator __annotator(*this);
         if (__p == this->__end_)
         {
             __alloc_traits::construct(this->__alloc(),
@@ -1769,6 +1781,7 @@
             __move_range(__p, this->__end_, __p + 1);
             *__p = _VSTD::move(__x);
         }
+        __annotator.__done();
     }
     else
     {
@@ -1795,7 +1808,7 @@
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
-        __annotate_increase(1);
+        __RAII_IncreaseAnnotator __annotator(*this);
         if (__p == this->__end_)
         {
             __alloc_traits::construct(this->__alloc(),
@@ -1809,6 +1822,7 @@
             __move_range(__p, this->__end_, __p + 1);
             *__p = _VSTD::move(__tmp);
         }
+        __annotator.__done();
     }
     else
     {
@@ -1847,8 +1861,9 @@
             }
             if (__n > 0)
             {
-                __annotate_increase(__n);
+                __RAII_IncreaseAnnotator __annotator(*this, __n);
                 __move_range(__p, __old_last, __p + __old_n);
+                __annotator.__done();
                 const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
                 if (__p <= __xr && __xr < this->__end_)
                     __xr += __old_n;
@@ -1958,8 +1973,9 @@
             }
             if (__n > 0)
             {
-                __annotate_increase(__n);
+                __RAII_IncreaseAnnotator __annotator(*this, __n);
                 __move_range(__p, __old_last, __p + __old_n);
+                __annotator.__done();
                 _VSTD::copy(__first, __m, __p);
             }
         }
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index d56ade4..318c4ce 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -36,23 +36,27 @@
 endif()
 
 # Generate library list.
-set(libraries ${LIBCXX_CXX_ABI_LIBRARIES})
+set(libraries ${LIBCXX_CXX_ABI_LIBRARY})
 append_if(libraries LIBCXX_HAS_PTHREAD_LIB pthread)
 append_if(libraries LIBCXX_HAS_C_LIB c)
 append_if(libraries LIBCXX_HAS_M_LIB m)
 append_if(libraries LIBCXX_HAS_RT_LIB rt)
 append_if(libraries LIBCXX_HAS_GCC_S_LIB gcc_s)
 
+#if LIBCXX_CXX_ABI_LIBRARY_PATH is defined we want to add it to the search path.
+if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH)
+  target_link_libraries(cxx "-L${LIBCXX_CXX_ABI_LIBRARY_PATH}")
+endif()
 target_link_libraries(cxx ${libraries})
 
 # Setup flags.
-append_if(compile_flags LIBCXX_HAS_FPIC_FLAG -fPIC)
-append_if(link_flags LIBCXX_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
+append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_FPIC_FLAG -fPIC)
+append_if(LIBCXX_LINK_FLAGS LIBCXX_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
 
 if ( APPLE )
   if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6" )
-    list(APPEND compile_flags "-U__STRICT_ANSI__")
-    list(APPEND link_flags
+    list(APPEND LIBCXX_COMPILE_FLAGS "-U__STRICT_ANSI__")
+    list(APPEND LIBCXX_LINK_FLAGS
       "-compatibility_version 1"
       "-current_version 1"
       "-install_name /usr/lib/libc++.1.dylib"
@@ -74,7 +78,7 @@
       set (OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
     endif()
 
-    list(APPEND link_flags
+    list(APPEND LIBCXX_LINK_FLAGS
       "-compatibility_version 1"
       "-install_name /usr/lib/libc++.1.dylib"
       "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
@@ -84,13 +88,13 @@
   endif()
 endif()
 
-string(REPLACE ";" " " compile_flags "${compile_flags}")
-string(REPLACE ";" " " link_flags "${link_flags}")
+string(REPLACE ";" " " LIBCXX_COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}")
+string(REPLACE ";" " " LIBCXX_LINK_FLAGS "${LIBCXX_LINK_FLAGS}")
 
 set_target_properties(cxx
   PROPERTIES
-    COMPILE_FLAGS "${compile_flags}"
-    LINK_FLAGS    "${link_flags}"
+    COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
+    LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
     OUTPUT_NAME   "c++"
     VERSION       "1.0"
     SOVERSION     "1"
diff --git a/src/algorithm.cpp b/src/algorithm.cpp
index 10c4c33..e548856 100644
--- a/src/algorithm.cpp
+++ b/src/algorithm.cpp
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
 #include "algorithm"
 #include "random"
 #include "mutex"
@@ -48,12 +47,16 @@
 
 template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
 
+#ifndef _LIBCPP_HAS_NO_THREADS
 static pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER;
+#endif
 unsigned __rs_default::__c_ = 0;
 
 __rs_default::__rs_default()
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     pthread_mutex_lock(&__rs_mut);
+#endif
     __c_ = 1;
 }
 
@@ -64,8 +67,12 @@
 
 __rs_default::~__rs_default()
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     if (--__c_ == 0)
         pthread_mutex_unlock(&__rs_mut);
+#else
+    --__c_;
+#endif
 }
 
 __rs_default::result_type
diff --git a/src/chrono.cpp b/src/chrono.cpp
index 15a6f46..4569411 100644
--- a/src/chrono.cpp
+++ b/src/chrono.cpp
@@ -46,6 +46,7 @@
     return system_clock::time_point(seconds(t));
 }
 
+#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
 // steady_clock
 
 const bool steady_clock::is_steady;
@@ -108,10 +109,8 @@
 }
 
 #else  // __APPLE__
-// FIXME: We assume that clock_gettime(CLOCK_MONOTONIC) works on
-// non-apple systems.  Instead, we should check _POSIX_TIMERS and
-// _POSIX_MONOTONIC_CLOCK and fall back to something else if those
-// don't exist.
+// FIXME: if _LIBCPP_HAS_NO_MONOTONIC_CLOCK, then clock_gettime isn't going to
+// work. It may be possible to fall back on something else, depending on the system.
 
 // Warning:  If this is not truly steady, then it is non-conforming.  It is
 //  better for it to not exist and have the rest of libc++ use system_clock
@@ -127,6 +126,8 @@
 }
 #endif  // __APPLE__
 
+#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK
+
 }
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/src/condition_variable.cpp b/src/condition_variable.cpp
index 061d138..5fd5fc8 100644
--- a/src/condition_variable.cpp
+++ b/src/condition_variable.cpp
@@ -7,6 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #include "condition_variable"
 #include "thread"
 #include "system_error"
@@ -79,3 +83,5 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
diff --git a/src/debug.cpp b/src/debug.cpp
index d0e8679..60694a3 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -35,6 +35,7 @@
 namespace
 {
 
+#ifndef _LIBCPP_HAS_NO_THREADS
 typedef mutex mutex_type;
 typedef lock_guard<mutex_type> WLock;
 typedef lock_guard<mutex_type> RLock;
@@ -45,6 +46,7 @@
     static mutex_type m;
     return m;
 }
+#endif // !_LIBCPP_HAS_NO_THREADS
 
 }  // unnamed namespace
 
@@ -108,7 +110,9 @@
 void*
 __libcpp_db::__find_c_from_i(void* __i) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
     return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
@@ -117,7 +121,9 @@
 void
 __libcpp_db::__insert_ic(void* __i, const void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__cbeg_ == __cend_)
         return;
     size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -138,7 +144,9 @@
 __c_node*
 __libcpp_db::__insert_c(void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
     {
         size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
@@ -184,7 +192,9 @@
 void
 __libcpp_db::__erase_i(void* __i)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__ibeg_ != __iend_)
     {
         size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
@@ -215,7 +225,9 @@
 void
 __libcpp_db::__invalidate_all(void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__cend_ != __cbeg_)
     {
         size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -239,17 +251,23 @@
 __c_node*
 __libcpp_db::__find_c_and_lock(void* __c) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     mut().lock();
+#endif
     if (__cend_ == __cbeg_)
     {
+#ifndef _LIBCPP_HAS_NO_THREADS
         mut().unlock();
+#endif
         return nullptr;
     }
     size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
     __c_node* p = __cbeg_[hc];
     if (p == nullptr)
     {
+#ifndef _LIBCPP_HAS_NO_THREADS
         mut().unlock();
+#endif
         return nullptr;
     }
     while (p->__c_ != __c)
@@ -257,7 +275,9 @@
         p = p->__next_;
         if (p == nullptr)
         {
+#ifndef _LIBCPP_HAS_NO_THREADS
             mut().unlock();
+#endif
             return nullptr;
         }
     }
@@ -281,13 +301,17 @@
 void
 __libcpp_db::unlock() const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     mut().unlock();
+#endif
 }
 
 void
 __libcpp_db::__erase_c(void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__cend_ != __cbeg_)
     {
         size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -322,7 +346,9 @@
 void
 __libcpp_db::__iterator_copy(void* __i, const void* __i0)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     __i_node* i0 = __find_iterator(__i0);
     __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
@@ -348,7 +374,9 @@
 bool
 __libcpp_db::__dereferenceable(const void* __i) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
 }
@@ -356,7 +384,9 @@
 bool
 __libcpp_db::__decrementable(const void* __i) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
 }
@@ -364,7 +394,9 @@
 bool
 __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
 }
@@ -372,7 +404,9 @@
 bool
 __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
 }
@@ -380,7 +414,9 @@
 bool
 __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     __i_node* j = __find_iterator(__j);
     __c_node* ci = i != nullptr ? i->__c_ : nullptr;
@@ -391,7 +427,9 @@
 void
 __libcpp_db::swap(void* c1, void* c2)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
     __c_node* p1 = __cbeg_[hc];
     _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
@@ -420,7 +458,9 @@
 void
 __libcpp_db::__insert_i(void* __i)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     __insert_iterator(__i);
 }
 
diff --git a/src/exception.cpp b/src/exception.cpp
index 3ce6f2e..b5c46c0 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -16,7 +16,7 @@
 #define __has_include(inc) 0
 #endif
 
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined(LIBCXXRT)
   #include <cxxabi.h>
 
   using namespace __cxxabiv1;
diff --git a/src/future.cpp b/src/future.cpp
index c67dc58..0c5c2c4 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -7,6 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #include "future"
 #include "string"
 
@@ -298,3 +302,5 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
diff --git a/src/ios.cpp b/src/ios.cpp
index e241394..d879beb 100644
--- a/src/ios.cpp
+++ b/src/ios.cpp
@@ -7,8 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-
+#include "__config"
 #include "ios"
 #include "streambuf"
 #include "istream"
@@ -54,11 +53,9 @@
 __iostream_category::message(int ev) const
 {
     if (ev != static_cast<int>(io_errc::stream)
-#ifdef ELAST
-        && ev <= ELAST
-#elif defined(__linux__)
-        && ev <= 4095
-#endif  // ELAST
+#ifdef _LIBCPP_ELAST
+        && ev <= _LIBCPP_ELAST
+#endif  // _LIBCPP_ELAST
         )
         return __do_message::message(ev);
     return string("unspecified iostream_category error");
@@ -151,12 +148,22 @@
 }
 
 // xalloc
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
 atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0);
 #else
 int ios_base::__xindex_ = 0;
 #endif
 
+template <typename _Tp>
+static size_t __ios_new_cap(size_t __req_size, size_t __current_cap)
+{ // Precondition: __req_size > __current_cap
+	const size_t mx = std::numeric_limits<size_t>::max() / sizeof(_Tp);
+	if (__req_size < mx/2)
+		return _VSTD::max(2 * __current_cap, __req_size);
+	else
+		return mx;
+}
+
 int
 ios_base::xalloc()
 {
@@ -169,14 +176,8 @@
     size_t req_size = static_cast<size_t>(index)+1;
     if (req_size > __iarray_cap_)
     {
-        size_t newcap;
-        const size_t mx = std::numeric_limits<size_t>::max();
-        if (req_size < mx/2)
-            newcap = _VSTD::max(2 * __iarray_cap_, req_size);
-        else
-            newcap = mx;
-        size_t newsize = newcap * sizeof(long);
-        long* iarray = static_cast<long*>(realloc(__iarray_, newsize));
+        size_t newcap = __ios_new_cap<long>(req_size, __iarray_cap_);
+        long* iarray = static_cast<long*>(realloc(__iarray_, newcap * sizeof(long)));
         if (iarray == 0)
         {
             setstate(badbit);
@@ -185,8 +186,9 @@
             return error;
         }
         __iarray_ = iarray;
-        for (long* p = __iarray_ + __iarray_size_; __iarray_cap_ < newcap; ++__iarray_cap_, ++p)
+        for (long* p = __iarray_ + __iarray_size_; p < __iarray_ + newcap; ++p)
             *p = 0;
+        __iarray_cap_ = newcap;
     }
     __iarray_size_ = max<size_t>(__iarray_size_, req_size);
     return __iarray_[index];
@@ -198,14 +200,8 @@
     size_t req_size = static_cast<size_t>(index)+1;
     if (req_size > __parray_cap_)
     {
-        size_t newcap;
-        const size_t mx = std::numeric_limits<size_t>::max();
-        if (req_size < mx/2)
-            newcap = _VSTD::max(2 * __parray_cap_, req_size);
-        else
-            newcap = mx;
-        size_t newsize = newcap * sizeof(void*);
-        void** parray = static_cast<void**>(realloc(__parray_, newsize));
+        size_t newcap = __ios_new_cap<void *>(req_size, __iarray_cap_);
+        void** parray = static_cast<void**>(realloc(__parray_, newcap * sizeof(void *)));
         if (parray == 0)
         {
             setstate(badbit);
@@ -214,8 +210,9 @@
             return error;
         }
         __parray_ = parray;
-        for (void** p = __parray_ + __parray_size_; __parray_cap_ < newcap; ++__parray_cap_, ++p)
+        for (void** p = __parray_ + __parray_size_; p < __parray_ + newcap; ++p)
             *p = 0;
+        __parray_cap_ = newcap;
     }
     __parray_size_ = max<size_t>(__parray_size_, req_size);
     return __parray_[index];
@@ -229,22 +226,16 @@
     size_t req_size = __event_size_ + 1;
     if (req_size > __event_cap_)
     {
-        size_t newcap;
-        const size_t mx = std::numeric_limits<size_t>::max();
-        if (req_size < mx/2)
-            newcap = _VSTD::max(2 * __event_cap_, req_size);
-        else
-            newcap = mx;
-        size_t newesize = newcap * sizeof(event_callback);
-        event_callback* fns = static_cast<event_callback*>(realloc(__fn_, newesize));
+        size_t newcap = __ios_new_cap<event_callback>(req_size, __event_cap_);
+        event_callback* fns = static_cast<event_callback*>(realloc(__fn_, newcap * sizeof(event_callback)));
         if (fns == 0)
             setstate(badbit);
         __fn_ = fns;
-        size_t newisize = newcap * sizeof(int);
-        int* indxs = static_cast<int *>(realloc(__index_, newisize));
+        int* indxs = static_cast<int *>(realloc(__index_, newcap * sizeof(int)));
         if (indxs == 0)
             setstate(badbit);
         __index_ = indxs;
+        __event_cap_ = newcap;
     }
     __fn_[__event_size_] = fn;
     __index_[__event_size_] = index;
diff --git a/src/locale.cpp b/src/locale.cpp
index e626528..f21e35d 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -7,8 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-
 // On Solaris, we need to define something to make the C99 parts of localeconv
 // visible.
 #ifdef __sun__
diff --git a/src/memory.cpp b/src/memory.cpp
index 02f6bf9..c56d031 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -9,8 +9,10 @@
 
 #define _LIBCPP_BUILDING_MEMORY
 #include "memory"
+#ifndef _LIBCPP_HAS_NO_THREADS
 #include "mutex"
 #include "thread"
+#endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -109,7 +111,7 @@
     return 0;
 }
 
-#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
+#ifndef _LIBCPP_NO_RTTI
 
 const void*
 __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
@@ -117,9 +119,9 @@
     return 0;
 }
 
-#endif  // !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
+#endif  // _LIBCPP_NO_RTTI
 
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 static const std::size_t __sp_mut_count = 16;
 static pthread_mutex_t mut_back_imp[__sp_mut_count] =
@@ -172,7 +174,7 @@
     return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
 }
 
-#endif // __has_feature(cxx_atomic)
+#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
 
 void
 declare_reachable(void*)
diff --git a/src/mutex.cpp b/src/mutex.cpp
index 0767897..e56271d 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -14,6 +14,7 @@
 #include "cassert"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
+#ifndef _LIBCPP_HAS_NO_THREADS
 
 const defer_lock_t  defer_lock = {};
 const try_to_lock_t try_to_lock = {};
@@ -206,18 +207,42 @@
     }
 }
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 // If dispatch_once_f ever handles C++ exceptions, and if one can get to it
 // without illegal macros (unexpected macros not beginning with _UpperCase or
 // __lowercase), and if it stops spinning waiting threads, then call_once should
 // call into dispatch_once_f instead of here. Relevant radar this code needs to
 // keep in sync with:  7741191.
 
+#ifndef _LIBCPP_HAS_NO_THREADS
 static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t  cv  = PTHREAD_COND_INITIALIZER;
+#endif
 
 void
 __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
 {
+#if defined(_LIBCPP_HAS_NO_THREADS)
+    if (flag == 0)
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            flag = 1;
+            func(arg);
+            flag = ~0ul;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            flag = 0ul;
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+#else // !_LIBCPP_HAS_NO_THREADS
     pthread_mutex_lock(&mut);
     while (flag == 1)
         pthread_cond_wait(&cv, &mut);
@@ -248,6 +273,8 @@
     }
     else
         pthread_mutex_unlock(&mut);
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 }
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/src/new.cpp b/src/new.cpp
index 3b7c341..a88d4cc 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -17,7 +17,7 @@
 #define __has_include(inc) 0
 #endif
 
-#ifdef __APPLE__
+#if defined(__APPLE__) && !defined(LIBCXXRT)
     #include <cxxabi.h>
 
     #ifndef _LIBCPPABI_VERSION
@@ -192,8 +192,6 @@
 
 #endif // !__GLIBCXX__
 
-#endif //LIBCXXRT
-
 bad_array_new_length::bad_array_new_length() _NOEXCEPT
 {
 }
@@ -203,6 +201,14 @@
 }
 
 const char*
+bad_array_new_length::what() const _NOEXCEPT
+{
+    return "bad_array_new_length";
+}
+
+#endif //LIBCXXRT
+
+const char*
 bad_array_length::what() const _NOEXCEPT
 {
     return "bad_array_length";
@@ -216,12 +222,6 @@
 {
 }
 
-const char*
-bad_array_new_length::what() const _NOEXCEPT
-{
-    return "bad_array_new_length";
-}
-
 #endif // _LIBCPPABI_VERSION
 
 #ifndef LIBSTDCXX
diff --git a/src/shared_mutex.cpp b/src/shared_mutex.cpp
index dd78a16..2b78c1f 100644
--- a/src/shared_mutex.cpp
+++ b/src/shared_mutex.cpp
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #define _LIBCPP_BUILDING_SHARED_MUTEX
 #include "shared_mutex"
 
@@ -99,3 +102,5 @@
 
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
diff --git a/src/string.cpp b/src/string.cpp
index fde5212..febc532 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -7,8 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-
 #include "string"
 #include "cstdlib"
 #include "cwchar"
@@ -65,7 +63,7 @@
 V
 as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
 {
-    typename S::value_type* ptr;
+    typename S::value_type* ptr = nullptr;
     const typename S::value_type* const p = str.c_str();
     typename remove_reference<decltype(errno)>::type errno_save = errno;
     errno = 0;
@@ -182,7 +180,7 @@
 V
 as_float_helper(const string& func, const S& str, size_t* idx, F f )
 {
-    typename S::value_type* ptr;
+    typename S::value_type* ptr = nullptr;
     const typename S::value_type* const p = str.c_str();
     typename remove_reference<decltype(errno)>::type errno_save = errno;
     errno = 0;
diff --git a/src/system_error.cpp b/src/system_error.cpp
index d5cb2d4..9c8adc4 100644
--- a/src/system_error.cpp
+++ b/src/system_error.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #define _LIBCPP_BUILDING_SYSTEM_ERROR
+#include "__config"
 #include "system_error"
 #include "string"
 #include "cstring"
@@ -65,13 +66,10 @@
 string
 __generic_error_category::message(int ev) const
 {
-#ifdef ELAST
-    if (ev > ELAST)
+#ifdef _LIBCPP_ELAST
+    if (ev > _LIBCPP_ELAST)
       return string("unspecified generic_category error");
-#elif defined(__linux__)
-    if (ev > 4095)
-      return string("unspecified generic_category error");
-#endif  // ELAST
+#endif  // _LIBCPP_ELAST
     return __do_message::message(ev);
 }
 
@@ -100,26 +98,20 @@
 string
 __system_error_category::message(int ev) const
 {
-#ifdef ELAST
-    if (ev > ELAST)
+#ifdef _LIBCPP_ELAST
+    if (ev > _LIBCPP_ELAST)
       return string("unspecified system_category error");
-#elif defined(__linux__)
-    if (ev > 4095)
-      return string("unspecified system_category error");
-#endif  // ELAST
+#endif  // _LIBCPP_ELAST
     return __do_message::message(ev);
 }
 
 error_condition
 __system_error_category::default_error_condition(int ev) const _NOEXCEPT
 {
-#ifdef ELAST
-    if (ev > ELAST)
+#ifdef _LIBCPP_ELAST
+    if (ev > _LIBCPP_ELAST)
       return error_condition(ev, system_category());
-#elif defined(__linux__)
-    if (ev > 4095)
-      return error_condition(ev, system_category());
-#endif  // ELAST
+#endif  // _LIBCPP_ELAST
     return error_condition(ev, generic_category());
 }
 
diff --git a/src/thread.cpp b/src/thread.cpp
index e6f57c4..0ced1e3 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #include "thread"
 #include "exception"
 #include "vector"
@@ -225,3 +228,5 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
diff --git a/src/valarray.cpp b/src/valarray.cpp
index e4c9ed0..2d8db52 100644
--- a/src/valarray.cpp
+++ b/src/valarray.cpp
@@ -7,8 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-
 #include "valarray"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp b/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
index fe67854..0cf06bb 100644
--- a/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
@@ -28,31 +28,26 @@
     int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
     int ib[] = {0, 1, 2, 3, 0, 1, 2, 3};
-    assert(std::mismatch(input_iterator<const int*>(ia),
-                         input_iterator<const int*>(ia + sa),
-                         input_iterator<const int*>(ib)) ==
-                         (std::pair<input_iterator<const int*>,
-                                    input_iterator<const int*> >(
-                            input_iterator<const int*>(ia+3),
-                            input_iterator<const int*>(ib+3))));
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+
+	typedef input_iterator<const int*> II;
+	typedef random_access_iterator<const int*>  RAI;
+
+    assert(std::mismatch(II(ia), II(ia + sa), II(ib))
+    		== (std::pair<II, II>(II(ia+3), II(ib+3))));
+
+    assert(std::mismatch(RAI(ia), RAI(ia + sa), RAI(ib))
+    		== (std::pair<RAI, RAI>(RAI(ia+3), RAI(ib+3))));
 
 #ifdef HAS_FOUR_ITERATOR_VERSION
-    assert(std::mismatch(input_iterator<const int*>(ia),
-                         input_iterator<const int*>(ia + sa),
-                         input_iterator<const int*>(ib),
-                         input_iterator<const int*>(ib + sa)) ==
-                         (std::pair<input_iterator<const int*>,
-                                    input_iterator<const int*> >(
-                            input_iterator<const int*>(ia+3),
-                            input_iterator<const int*>(ib+3))));
+    assert(std::mismatch(II(ia), II(ia + sa), II(ib), II(ib+sb))
+    		== (std::pair<II, II>(II(ia+3), II(ib+3))));
 
-    assert(std::mismatch(input_iterator<const int*>(ia),
-                         input_iterator<const int*>(ia + sa),
-                         input_iterator<const int*>(ib),
-                         input_iterator<const int*>(ib + 2)) ==
-                         (std::pair<input_iterator<const int*>,
-                                    input_iterator<const int*> >(
-                            input_iterator<const int*>(ia+2),
-                            input_iterator<const int*>(ib+2))));
+    assert(std::mismatch(RAI(ia), RAI(ia + sa), RAI(ib), RAI(ib+sb))
+    		== (std::pair<RAI, RAI>(RAI(ia+3), RAI(ib+3))));
+
+
+    assert(std::mismatch(II(ia), II(ia + sa), II(ib), II(ib+2))
+    		== (std::pair<II, II>(II(ia+2), II(ib+2))));
 #endif
 }
diff --git a/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp b/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
index 202a1b7..ce0326c 100644
--- a/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
@@ -20,43 +20,52 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "counting_predicates.hpp"
 
 #if _LIBCPP_STD_VER > 11
 #define HAS_FOUR_ITERATOR_VERSION
 #endif
 
-
 int main()
 {
     int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
     const unsigned sa = sizeof(ia)/sizeof(ia[0]);
     int ib[] = {0, 1, 2, 3, 0, 1, 2, 3};
-    assert(std::mismatch(input_iterator<const int*>(ia),
-                         input_iterator<const int*>(ia + sa),
-                         input_iterator<const int*>(ib),
-                         std::equal_to<int>()) ==
-                         (std::pair<input_iterator<const int*>,
-                                    input_iterator<const int*> >(
-                            input_iterator<const int*>(ia+3),
-                            input_iterator<const int*>(ib+3))));
+    const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+    
+	typedef input_iterator<const int*> II;
+	typedef random_access_iterator<const int*>  RAI;
+	typedef std::equal_to<int> EQ;
+
+    assert(std::mismatch(II(ia), II(ia + sa), II(ib), EQ())
+            == (std::pair<II, II>(II(ia+3), II(ib+3))));
+    assert(std::mismatch(RAI(ia), RAI(ia + sa), RAI(ib), EQ())
+            == (std::pair<RAI, RAI>(RAI(ia+3), RAI(ib+3))));
+
+    binary_counting_predicate<EQ, int> bcp((EQ()));
+    assert(std::mismatch(RAI(ia), RAI(ia + sa), RAI(ib), std::ref(bcp))
+            == (std::pair<RAI, RAI>(RAI(ia+3), RAI(ib+3))));
+	assert(bcp.count() > 0 && bcp.count() < sa);
+	bcp.reset();
+		
 #ifdef HAS_FOUR_ITERATOR_VERSION
-    assert(std::mismatch(input_iterator<const int*>(ia),
-                         input_iterator<const int*>(ia + sa),
-                         input_iterator<const int*>(ib),
-                         input_iterator<const int*>(ib + sa),
-                         std::equal_to<int>()) ==
-                         (std::pair<input_iterator<const int*>,
-                                    input_iterator<const int*> >(
-                            input_iterator<const int*>(ia+3),
-                            input_iterator<const int*>(ib+3))));
+    assert(std::mismatch(II(ia), II(ia + sa), II(ib), II(ib + sb), EQ())
+            == (std::pair<II, II>(II(ia+3), II(ib+3))));
+    assert(std::mismatch(RAI(ia), RAI(ia + sa), RAI(ib), RAI(ib + sb), EQ())
+            == (std::pair<RAI, RAI>(RAI(ia+3), RAI(ib+3))));
+
+    assert(std::mismatch(II(ia), II(ia + sa), II(ib), II(ib + sb), std::ref(bcp))
+            == (std::pair<II, II>(II(ia+3), II(ib+3))));
+	assert(bcp.count() > 0 && bcp.count() < std::min(sa, sb));
 #endif
 
-    assert(std::mismatch(ia, ia + sa, ib, std::equal_to<int>()) ==
+    assert(std::mismatch(ia, ia + sa, ib, EQ()) ==
            (std::pair<int*,int*>(ia+3,ib+3)));
+
 #ifdef HAS_FOUR_ITERATOR_VERSION
-    assert(std::mismatch(ia, ia + sa, ib, ib + sa, std::equal_to<int>()) ==
+    assert(std::mismatch(ia, ia + sa, ib, ib + sb, EQ()) ==
            (std::pair<int*,int*>(ia+3,ib+3)));
-    assert(std::mismatch(ia, ia + sa, ib, ib + 2, std::equal_to<int>()) ==
+    assert(std::mismatch(ia, ia + sa, ib, ib + 2, EQ()) ==
            (std::pair<int*,int*>(ia+2,ib+2)));
 #endif
 }
diff --git a/test/atomics/atomics.fences/atomic_signal_fence.pass.cpp b/test/atomics/atomics.fences/atomic_signal_fence.pass.cpp
index 65e1d38..aec060c 100644
--- a/test/atomics/atomics.fences/atomic_signal_fence.pass.cpp
+++ b/test/atomics/atomics.fences/atomic_signal_fence.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.fences/atomic_thread_fence.pass.cpp b/test/atomics/atomics.fences/atomic_thread_fence.pass.cpp
index 8c2abc0..4f3b0e3 100644
--- a/test/atomics/atomics.fences/atomic_thread_fence.pass.cpp
+++ b/test/atomics/atomics.fences/atomic_thread_fence.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/atomic_flag_clear.pass.cpp b/test/atomics/atomics.flag/atomic_flag_clear.pass.cpp
index 12be67c..64093d6 100644
--- a/test/atomics/atomics.flag/atomic_flag_clear.pass.cpp
+++ b/test/atomics/atomics.flag/atomic_flag_clear.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp b/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
index f1065dc..e1a9349 100644
--- a/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
+++ b/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp b/test/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp
index e3934d8..ae82df9 100644
--- a/test/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp
+++ b/test/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp b/test/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp
index 83ee78d..1548506 100644
--- a/test/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp
+++ b/test/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/clear.pass.cpp b/test/atomics/atomics.flag/clear.pass.cpp
index 171f038..65051af 100644
--- a/test/atomics/atomics.flag/clear.pass.cpp
+++ b/test/atomics/atomics.flag/clear.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/default.pass.cpp b/test/atomics/atomics.flag/default.pass.cpp
index 5c077b0..45f5e70 100644
--- a/test/atomics/atomics.flag/default.pass.cpp
+++ b/test/atomics/atomics.flag/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/init.pass.cpp b/test/atomics/atomics.flag/init.pass.cpp
index 8a67e14..c90509d 100644
--- a/test/atomics/atomics.flag/init.pass.cpp
+++ b/test/atomics/atomics.flag/init.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.flag/test_and_set.pass.cpp b/test/atomics/atomics.flag/test_and_set.pass.cpp
index 2405275..210ba20 100644
--- a/test/atomics/atomics.flag/test_and_set.pass.cpp
+++ b/test/atomics/atomics.flag/test_and_set.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.lockfree/lockfree.pass.cpp b/test/atomics/atomics.lockfree/lockfree.pass.cpp
index 467f561..a975a69 100644
--- a/test/atomics/atomics.lockfree/lockfree.pass.cpp
+++ b/test/atomics/atomics.lockfree/lockfree.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.order/kill_dependency.pass.cpp b/test/atomics/atomics.order/kill_dependency.pass.cpp
index 1beeb08..0f0bafc 100644
--- a/test/atomics/atomics.order/kill_dependency.pass.cpp
+++ b/test/atomics/atomics.order/kill_dependency.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.order/memory_order.pass.cpp b/test/atomics/atomics.order/memory_order.pass.cpp
index 8289304..e734a4c 100644
--- a/test/atomics/atomics.order/memory_order.pass.cpp
+++ b/test/atomics/atomics.order/memory_order.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.generic/address.pass.cpp b/test/atomics/atomics.types.generic/address.pass.cpp
index 94abfbe..3b9f3ce 100644
--- a/test/atomics/atomics.types.generic/address.pass.cpp
+++ b/test/atomics/atomics.types.generic/address.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... test case crashes clang.
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.generic/bool.pass.cpp b/test/atomics/atomics.types.generic/bool.pass.cpp
index e00ec86..dd851e8 100644
--- a/test/atomics/atomics.types.generic/bool.pass.cpp
+++ b/test/atomics/atomics.types.generic/bool.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
@@ -66,6 +68,7 @@
         std::atomic_init(&obj, true);
         assert(obj == true);
         bool b0 = obj.is_lock_free();
+        (void)b0; // to placate scan-build
         obj.store(false);
         assert(obj == false);
         obj.store(true, std::memory_order_release);
@@ -121,6 +124,7 @@
         std::atomic_init(&obj, true);
         assert(obj == true);
         bool b0 = obj.is_lock_free();
+        (void)b0; // to placate scan-build
         obj.store(false);
         assert(obj == false);
         obj.store(true, std::memory_order_release);
@@ -176,6 +180,7 @@
         std::atomic_init(&obj, true);
         assert(obj == true);
         bool b0 = obj.is_lock_free();
+        (void)b0; // to placate scan-build
         obj.store(false);
         assert(obj == false);
         obj.store(true, std::memory_order_release);
diff --git a/test/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp b/test/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp
index eac5177..a7874b9 100644
--- a/test/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp
+++ b/test/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.generic/integral.pass.cpp b/test/atomics/atomics.types.generic/integral.pass.cpp
index 106fe88..f9c7583 100644
--- a/test/atomics/atomics.types.generic/integral.pass.cpp
+++ b/test/atomics/atomics.types.generic/integral.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.generic/integral_typedefs.pass.cpp b/test/atomics/atomics.types.generic/integral_typedefs.pass.cpp
index c622d6e..e8fae85 100644
--- a/test/atomics/atomics.types.generic/integral_typedefs.pass.cpp
+++ b/test/atomics/atomics.types.generic/integral_typedefs.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.generic/trivially_copyable.fail.cpp b/test/atomics/atomics.types.generic/trivially_copyable.fail.cpp
index 49ec069..f2bf4db 100644
--- a/test/atomics/atomics.types.generic/trivially_copyable.fail.cpp
+++ b/test/atomics/atomics.types.generic/trivially_copyable.fail.cpp
@@ -54,17 +54,17 @@
 #include <chrono> // for nanoseconds
 
 struct NotTriviallyCopyable {
-	NotTriviallyCopyable ( int i ) : i_(i) {}
-	NotTriviallyCopyable ( const NotTriviallyCopyable &rhs) : i_(rhs.i_) {}
-	int i_;
-	};
+    NotTriviallyCopyable ( int i ) : i_(i) {}
+    NotTriviallyCopyable ( const NotTriviallyCopyable &rhs) : i_(rhs.i_) {}
+    int i_;
+    };
 
 template <class T>
 void test ( T t ) {
-	std::atomic<T> t0(t);
-	}
+    std::atomic<T> t0(t);
+    }
 
 int main()
 {
-	test(NotTriviallyCopyable(42));
+    test(NotTriviallyCopyable(42));
 }
diff --git a/test/atomics/atomics.types.generic/trivially_copyable.pass.cpp b/test/atomics/atomics.types.generic/trivially_copyable.pass.cpp
index 0cf3f58..e6e9bcc 100644
--- a/test/atomics/atomics.types.generic/trivially_copyable.pass.cpp
+++ b/test/atomics/atomics.types.generic/trivially_copyable.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
@@ -47,9 +49,6 @@
 //     T operator=(T) noexcept;
 // };
 
-// Android's clang isn't new enough to have the fix for this test.
-// XFAIL: android
-
 #include <atomic>
 #include <new>
 #include <cassert>
@@ -57,18 +56,18 @@
 #include <chrono> // for nanoseconds
 
 struct TriviallyCopyable {
-	TriviallyCopyable ( int i ) : i_(i) {}
-	int i_;
-	};
+    TriviallyCopyable ( int i ) : i_(i) {}
+    int i_;
+    };
 
 template <class T>
 void test ( T t ) {
-	std::atomic<T> t0(t);
-	}
+    std::atomic<T> t0(t);
+    }
 
 int main()
 {
-	test(TriviallyCopyable(42));
-	test(std::this_thread::get_id());
-	test(std::chrono::nanoseconds(2));
+    test(TriviallyCopyable(42));
+    test(std::this_thread::get_id());
+    test(std::chrono::nanoseconds(2));
 }
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
index fd5102b..f1cc993 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 34
 
 // <atomic>
 
@@ -55,7 +58,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
index f2610a3..f667ab7 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 38
 
 // <atomic>
 
@@ -62,7 +65,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
index 8929523..175c445 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 34
 
 // <atomic>
 
@@ -57,7 +60,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
index 81c9241..46f80bf 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 38
 
 // <atomic>
 
@@ -64,7 +67,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
index 4264943..525e74a 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... fails assertion line 31
 
 // <atomic>
 
@@ -40,7 +43,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
index 0f3add5..9fe4ac8 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 32
 
 // <atomic>
 
@@ -42,7 +45,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
index 9ce60ad..3408def 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... test crashes clang
 
 // <atomic>
 
@@ -75,7 +78,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
     A(const A& a) : i(a.i) {}
     A(const volatile A& a) : i(a.i) {}
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
index a2a1a44..9977bd4 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... test crashes clang
 
 // <atomic>
 
@@ -79,7 +82,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
     A(const A& a) : i(a.i) {}
     A(const volatile A& a) : i(a.i) {}
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
index 01d2cc6..4c7c043 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
index abfb83d..d83bbf2 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
index 43b6c4f..acf6d43 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
index 21078bb..72685e4 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
index d33b81e..ed8b541 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... test crashes clang
 
 // <atomic>
 
@@ -75,7 +78,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
     A(const A& a) : i(a.i) {}
     A(const volatile A& a) : i(a.i) {}
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
index 886a65f..e6c92ea 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... test crashes clang
 
 // <atomic>
 
@@ -80,7 +83,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
     A(const A& a) : i(a.i) {}
     A(const volatile A& a) : i(a.i) {}
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
index 78120a7..fc6b97b 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
index 0a0cd15..58772aa 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
index f0d9a24..137b6f6 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 34
 
 // <atomic>
 
@@ -38,7 +41,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
index 4071989..18a1605 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
index b239886..66918c7 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 34
 
 // <atomic>
 
@@ -38,7 +41,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
index 3072dd5..5f402a9 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 31
 
 // <atomic>
 
@@ -38,7 +41,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
index f9044bf..2b9582b 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 31
 
 // <atomic>
 
@@ -38,7 +41,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
index 18038ae..8fe0c7d 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
@@ -6,6 +6,9 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//  ... assertion fails line 31
 
 // <atomic>
 
@@ -38,7 +41,7 @@
 {
     int i;
 
-    explicit A(int d = 0) : i(d) {}
+    explicit A(int d = 0) noexcept {i=d;}
 
     friend bool operator==(const A& x, const A& y)
         {return x.i == y.i;}
diff --git a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
index 6758c7b..5fed691 100644
--- a/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
+++ b/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/atomics/libcpp-has-no-threads.fail.cpp b/test/atomics/libcpp-has-no-threads.fail.cpp
new file mode 100644
index 0000000..fe95e6a
--- /dev/null
+++ b/test/atomics/libcpp-has-no-threads.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <atomic>
+
+// Test that including <atomic> fails to compile when _LIBCPP_HAS_NO_THREADS
+// is defined.
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+#define _LIBCPP_HAS_NO_THREADS
+#endif
+
+#include <atomic>
+
+int main()
+{
+}
diff --git a/test/atomics/libcpp-has-no-threads.pass.cpp b/test/atomics/libcpp-has-no-threads.pass.cpp
new file mode 100644
index 0000000..9c0cccb
--- /dev/null
+++ b/test/atomics/libcpp-has-no-threads.pass.cpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-has-no-threads
+
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error This should be XFAIL'd for the purpose of detecting that the LIT feature\
+ 'libcpp-has-no-threads' is available iff _LIBCPP_HAS_NO_THREADS is defined
+#endif
+
+int main()
+{
+}
diff --git a/test/atomics/version.pass.cpp b/test/atomics/version.pass.cpp
index 85c4270..fae2736 100644
--- a/test/atomics/version.pass.cpp
+++ b/test/atomics/version.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <atomic>
 
diff --git a/test/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp
index ebae10e..33821d3 100644
--- a/test/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp
@@ -71,6 +71,7 @@
         assert(next(m.begin(), 5)->second == 2);
 
         i = m.erase(3);
+        assert(i == 3);
         assert(m.size() == 3);
         assert(next(m.begin(), 0)->first == 1);
         assert(next(m.begin(), 0)->second == 1);
@@ -135,6 +136,7 @@
         assert(next(m.begin(), 5)->second == 2);
 
         i = m.erase(3);
+        assert(i == 3);
         assert(m.size() == 3);
         assert(next(m.begin(), 0)->first == 1);
         assert(next(m.begin(), 0)->second == 1);
diff --git a/test/containers/sequences/array/array.data/data.pass.cpp b/test/containers/sequences/array/array.data/data.pass.cpp
index ea91357..08e4fd3 100644
--- a/test/containers/sequences/array/array.data/data.pass.cpp
+++ b/test/containers/sequences/array/array.data/data.pass.cpp
@@ -30,5 +30,6 @@
         typedef std::array<T, 0> C;
         C c = {};
         T* p = c.data();
+        (void)p; // to placate scan-build
     }
 }
diff --git a/test/containers/sequences/array/array.data/data_const.pass.cpp b/test/containers/sequences/array/array.data/data_const.pass.cpp
index 93acb71..8eb9762 100644
--- a/test/containers/sequences/array/array.data/data_const.pass.cpp
+++ b/test/containers/sequences/array/array.data/data_const.pass.cpp
@@ -30,5 +30,6 @@
         typedef std::array<T, 0> C;
         const C c = {};
         const T* p = c.data();
+        (void)p; // to placate scan-build
     }
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp
index fb3765d..0b348e6 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp
@@ -70,7 +70,7 @@
         typedef input_iterator<const T*> I;
         c.assign(I(std::begin(t0)), I(std::end(t0)));
         int n = 0;
-        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, ++n)
+        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, (void) ++n)
             assert(*i == 10+n);
         assert(n == 4);
     }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp
index ae381e6..18d4cae 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp
@@ -18,14 +18,14 @@
 #include "min_allocator.h"
 
 struct S {
-	S(int i) : i_(new int(i)) {}
-	S(const S &rhs) : i_(new int(*rhs.i_)) {}
-	S& operator = (const S &rhs) { *i_ = *rhs.i_; return *this; }
-	~S () { delete i_; i_ = NULL; }
-	bool operator == (const S &rhs) const { return *i_ == *rhs.i_; }
-	int get () const { return *i_; }
-	int *i_;
-	};
+    S(int i) : i_(new int(i)) {}
+    S(const S &rhs) : i_(new int(*rhs.i_)) {}
+    S& operator = (const S &rhs) { *i_ = *rhs.i_; return *this; }
+    ~S () { delete i_; i_ = NULL; }
+    bool operator == (const S &rhs) const { return *i_ == *rhs.i_; }
+    int get () const { return *i_; }
+    int *i_;
+    };
 
 
 int main()
@@ -98,10 +98,10 @@
     c.remove(c.front());
     C::const_iterator it = c.begin();
     for(int *ip = std::begin(t2); ip != std::end(t2); ++ip, ++it) {
-	    assert ( it != c.end());
+        assert ( it != c.end());
         assert ( *ip == it->get());
-	    }
-	assert ( it == c.end ());
+        }
+    assert ( it == c.end ());
     }
 #if __cplusplus >= 201103L
     {
diff --git a/test/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp b/test/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp
index 625004b..d69deac 100644
--- a/test/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp
@@ -12,6 +12,8 @@
 // template <InputIterator Iter>
 //   iterator insert(const_iterator position, Iter first, Iter last);
 
+// UNSUPPORTED: asan, msan
+
 #if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
diff --git a/test/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp b/test/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp
index ce2d386..a552e1f 100644
--- a/test/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp
@@ -11,6 +11,8 @@
 
 // iterator insert(const_iterator position, size_type n, const value_type& x);
 
+// UNSUPPORTED: asan, msan
+
 #if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
diff --git a/test/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp b/test/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp
index 1b097e3..093ad42 100644
--- a/test/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp
@@ -11,6 +11,8 @@
 
 // iterator insert(const_iterator position, const value_type& x);
 
+// UNSUPPORTED: asan, msan
+
 #if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
diff --git a/test/containers/sequences/list/list.ops/remove.pass.cpp b/test/containers/sequences/list/list.ops/remove.pass.cpp
index 106c052..f580c94 100644
--- a/test/containers/sequences/list/list.ops/remove.pass.cpp
+++ b/test/containers/sequences/list/list.ops/remove.pass.cpp
@@ -17,14 +17,14 @@
 #include "min_allocator.h"
 
 struct S {
-	S(int i) : i_(new int(i)) {}
-	S(const S &rhs) : i_(new int(*rhs.i_)) {}
-	S& operator = (const S &rhs) { *i_ = *rhs.i_; return *this; }
-	~S () { delete i_; i_ = NULL; }
-	bool operator == (const S &rhs) const { return *i_ == *rhs.i_; }
-	int get () const { return *i_; }
-	int *i_;
-	};
+    S(int i) : i_(new int(i)) {}
+    S(const S &rhs) : i_(new int(*rhs.i_)) {}
+    S& operator = (const S &rhs) { *i_ = *rhs.i_; return *this; }
+    ~S () { delete i_; i_ = NULL; }
+    bool operator == (const S &rhs) const { return *i_ == *rhs.i_; }
+    int get () const { return *i_; }
+    int *i_;
+    };
 
 
 int main()
@@ -52,10 +52,10 @@
     c.remove(c.front());
     std::list<S>::const_iterator it = c.begin();
     for(int *ip = a2; ip < a2+5; ++ip, ++it) {
-	    assert ( it != c.end());
+        assert ( it != c.end());
         assert ( *ip == it->get());
-	    }
-	assert ( it == c.end ());
+        }
+    assert ( it == c.end ());
     }
 #if __cplusplus >= 201103L
     {
diff --git a/test/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp b/test/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp
index c49ef9b..e51f8b5 100644
--- a/test/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector.bool/insert_iter_iter_iter.pass.cpp
@@ -33,7 +33,7 @@
             assert(v[j] == 0);
         for (int k = 0; k < N; ++j, ++k)
             assert(v[j] == a[k]);
-        for (; j < 105; ++j)
+        for (; j < v.size(); ++j)
             assert(v[j] == 0);
     }
     {
@@ -52,6 +52,43 @@
         for (; j < 105; ++j)
             assert(v[j] == 0);
     }
+    {
+        std::vector<bool> v(100);
+        while(v.size() < v.capacity()) v.push_back(false);
+        size_t sz = v.size();
+        bool a[] = {1, 0, 0, 1, 1};
+        const unsigned N = sizeof(a)/sizeof(a[0]);
+        std::vector<bool>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const bool*>(a),
+                                        forward_iterator<const bool*>(a+N));
+        assert(v.size() == sz + N);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (int k = 0; k < N; ++j, ++k)
+            assert(v[j] == a[k]);
+        for (; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<bool> v(100);
+        while(v.size() < v.capacity()) v.push_back(false);
+        v.pop_back(); v.pop_back(); v.pop_back();
+        size_t sz = v.size();
+        bool a[] = {1, 0, 0, 1, 1};
+        const unsigned N = sizeof(a)/sizeof(a[0]);
+        std::vector<bool>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const bool*>(a),
+                                        forward_iterator<const bool*>(a+N));
+        assert(v.size() == sz + N);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (int k = 0; k < N; ++j, ++k)
+            assert(v[j] == a[k]);
+        for (; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
 #if __cplusplus >= 201103L
     {
         std::vector<bool, min_allocator<bool>> v(100);
@@ -66,7 +103,7 @@
             assert(v[j] == 0);
         for (int k = 0; k < N; ++j, ++k)
             assert(v[j] == a[k]);
-        for (; j < 105; ++j)
+        for (; j < v.size(); ++j)
             assert(v[j] == 0);
     }
     {
@@ -82,7 +119,7 @@
             assert(v[j] == 0);
         for (int k = 0; k < N; ++j, ++k)
             assert(v[j] == a[k]);
-        for (; j < 105; ++j)
+        for (; j < v.size(); ++j)
             assert(v[j] == 0);
     }
 #endif
diff --git a/test/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp b/test/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp
index f9cb65c..710ad48 100644
--- a/test/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp
+++ b/test/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp
@@ -29,7 +29,38 @@
             assert(v[j] == 0);
         for (; j < 15; ++j)
             assert(v[j] == 1);
-        for (++j; j < 105; ++j)
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<bool> v(100);
+        while(v.size() < v.capacity()) v.push_back(false);
+        size_t sz = v.size();
+        std::vector<bool>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
+        assert(v.size() == sz + 5);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (; j < 15; ++j)
+            assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<bool> v(100);
+        while(v.size() < v.capacity()) v.push_back(false);
+        v.pop_back(); v.pop_back();
+        size_t sz = v.size();
+        std::vector<bool>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
+        assert(v.size() == sz + 5);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (; j < 15; ++j)
+            assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
             assert(v[j] == 0);
     }
 #if __cplusplus >= 201103L
@@ -43,7 +74,7 @@
             assert(v[j] == 0);
         for (; j < 15; ++j)
             assert(v[j] == 1);
-        for (++j; j < 105; ++j)
+        for (++j; j < v.size(); ++j)
             assert(v[j] == 0);
     }
 #endif
diff --git a/test/containers/sequences/vector.bool/insert_iter_value.pass.cpp b/test/containers/sequences/vector.bool/insert_iter_value.pass.cpp
index 1213985..51c4626 100644
--- a/test/containers/sequences/vector.bool/insert_iter_value.pass.cpp
+++ b/test/containers/sequences/vector.bool/insert_iter_value.pass.cpp
@@ -28,7 +28,36 @@
         for (j = 0; j < 10; ++j)
             assert(v[j] == 0);
         assert(v[j] == 1);
-        for (++j; j < 101; ++j)
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<bool> v(100);
+        while(v.size() < v.capacity()) v.push_back(false);
+        size_t sz = v.size();
+        std::vector<bool>::iterator i = v.insert(v.cbegin() + 10, 1);
+        assert(v.size() == sz + 1);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<bool> v(100);
+        while(v.size() < v.capacity()) v.push_back(false);
+        v.pop_back(); v.pop_back();
+        size_t sz = v.size();
+        std::vector<bool>::iterator i = v.insert(v.cbegin() + 10, 1);
+        assert(v.size() == sz + 1);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
             assert(v[j] == 0);
     }
 #if __cplusplus >= 201103L
@@ -41,7 +70,7 @@
         for (j = 0; j < 10; ++j)
             assert(v[j] == 0);
         assert(v[j] == 1);
-        for (++j; j < 101; ++j)
+        for (++j; j < v.size(); ++j)
             assert(v[j] == 0);
     }
 #endif
diff --git a/test/containers/sequences/vector.bool/resize_size.pass.cpp b/test/containers/sequences/vector.bool/resize_size.pass.cpp
index 77d54e5..f75720c 100644
--- a/test/containers/sequences/vector.bool/resize_size.pass.cpp
+++ b/test/containers/sequences/vector.bool/resize_size.pass.cpp
@@ -27,6 +27,10 @@
         v.resize(200);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        v.reserve(400);
+        v.resize(300);  // check the case when resizing and we already have room
+        assert(v.size() == 300);
+        assert(v.capacity() >= 400);
     }
 #if __cplusplus >= 201103L
     {
@@ -37,6 +41,10 @@
         v.resize(200);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        v.reserve(400);
+        v.resize(300);  // check the case when resizing and we already have room
+        assert(v.size() == 300);
+        assert(v.capacity() >= 400);
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/asan_throw.pass.cc b/test/containers/sequences/vector/asan_throw.pass.cc
new file mode 100644
index 0000000..a1dce4a
--- /dev/null
+++ b/test/containers/sequences/vector/asan_throw.pass.cc
@@ -0,0 +1,198 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test asan vector annotations with a class that throws in a CTOR.
+
+#include <vector>
+#include <cassert>
+
+#include "asan_testing.h"
+
+class X {
+public:
+  X(const X &x) { Init(x.a); }
+  X(char arg) { Init(arg); }
+  X() { Init(42); }
+  X &operator=(const X &x) {
+    Init(x.a);
+    return *this;
+  }
+  void Init(char arg) {
+    if (arg == 42)
+      throw 0;
+    if (arg == 66)
+      arg = 42;
+    a = arg;
+  }
+  char get() const { return a; }
+  void set(char arg) { a = arg; }
+
+private:
+  char a;
+};
+
+void test_push_back() {
+  std::vector<X> v;
+  v.reserve(2);
+  v.push_back(X(2));
+  assert(v.size() == 1);
+  try {
+    v.push_back(X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace_back() {
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+  std::vector<X> v;
+  v.reserve(2);
+  v.push_back(X(2));
+  assert(v.size() == 1);
+  try {
+    v.emplace_back(42);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
+
+void test_insert_range() {
+  std::vector<X> v;
+  v.reserve(4);
+  v.push_back(X(1));
+  v.push_back(X(2));
+  assert(v.size() == 2);
+  assert(v.capacity() >= 4);
+  try {
+    char a[2] = {21, 42};
+    v.insert(v.end(), a, a + 2);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 3);
+  }
+  assert(v.size() == 3);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_insert() {
+  std::vector<X> v;
+  v.reserve(3);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  try {
+    v.insert(v.end(), X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 2);
+  }
+  assert(v.size() == 2);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace() {
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+  std::vector<X> v;
+  v.reserve(3);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  try {
+    v.emplace(v.end(), 42);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 2);
+  }
+  assert(v.size() == 2);
+  assert(is_contiguous_container_asan_correct(v));
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
+
+void test_insert_range2() {
+  std::vector<X> v;
+  v.reserve(4);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  assert(v.capacity() >= 4);
+  try {
+    char a[2] = {10, 42};
+    v.insert(v.begin(), a, a + 2);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() <= 4);
+    assert(is_contiguous_container_asan_correct(v));
+    return;
+  }
+  assert(0);
+}
+
+void test_insert_n() {
+  std::vector<X> v;
+  v.reserve(10);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  try {
+    v.insert(v.begin(), 1, X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() <= 3);
+    assert(is_contiguous_container_asan_correct(v));
+    return;
+  }
+  assert(0);
+}
+
+void test_resize() {
+  std::vector<X> v;
+  v.reserve(3);
+  v.push_back(X(0));
+  try {
+    v.resize(3);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_resize_param() {
+  std::vector<X> v;
+  v.reserve(3);
+  v.push_back(X(0));
+  try {
+    v.resize(3, X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+int main() {
+  test_push_back();
+  test_emplace_back();
+  test_insert_range();
+  test_insert();
+  test_emplace();
+  test_insert_range2();
+  test_insert_n();
+  test_resize();
+  test_resize_param();
+}
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
index cf24a87..782437b 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
@@ -60,6 +60,42 @@
             assert(v[j] == 0);
     }
     {
+        std::vector<int> v(100);
+        while(v.size() < v.capacity()) v.push_back(0); // force reallocation
+        size_t sz = v.size();
+        int a[] = {1, 2, 3, 4, 5};
+        const unsigned N = sizeof(a)/sizeof(a[0]);
+        std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+                                        forward_iterator<const int*>(a+N));
+        assert(v.size() == sz + N);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (int k = 0; k < N; ++j, ++k)
+            assert(v[j] == a[k]);
+        for (; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<int> v(100);
+        v.reserve(128); // force no reallocation
+        size_t sz = v.size();
+        int a[] = {1, 2, 3, 4, 5};
+        const unsigned N = sizeof(a)/sizeof(a[0]);
+        std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+                                        forward_iterator<const int*>(a+N));
+        assert(v.size() == sz + N);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (int k = 0; k < N; ++j, ++k)
+            assert(v[j] == a[k]);
+        for (; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
         std::vector<int, stack_allocator<int, 308> > v(100);
         int a[] = {1, 2, 3, 4, 5};
         const int N = sizeof(a)/sizeof(a[0]);
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp
index 42effc7..6997284 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp
@@ -38,6 +38,38 @@
             assert(v[j] == 0);
     }
     {
+        std::vector<int> v(100);
+        while(v.size() < v.capacity()) v.push_back(0); // force reallocation
+        size_t sz = v.size();
+        std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
+        assert(v.size() == sz + 5);
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (; j < 15; ++j)
+            assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<int> v(100);
+        v.reserve(128); // force no reallocation
+        size_t sz = v.size();
+        std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
+        assert(v.size() == sz + 5);
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        for (; j < 15; ++j)
+            assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
         std::vector<int, stack_allocator<int, 300> > v(100);
         std::vector<int, stack_allocator<int, 300> >::iterator i = v.insert(v.cbegin() + 10, 5, 1);
         assert(v.size() == 105);
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp
index feb74c0..782e752 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp
@@ -37,6 +37,37 @@
             assert(v[j] == 0);
     }
     {
+        std::vector<int> v(100);
+        while(v.size() < v.capacity()) v.push_back(0); // force reallocation
+        size_t sz = v.size();
+        std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 1);
+        assert(v.size() == sz + 1);
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<int> v(100);
+        while(v.size() < v.capacity()) v.push_back(0);
+        v.pop_back(); v.pop_back(); // force no reallocation
+        size_t sz = v.size();
+        std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 1);
+        assert(v.size() == sz + 1);
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        assert(v[j] == 1);
+        for (++j; j < v.size(); ++j)
+            assert(v[j] == 0);
+    }
+    {
         std::vector<int, stack_allocator<int, 300> > v(100);
         std::vector<int, stack_allocator<int, 300> >::iterator i = v.insert(v.cbegin() + 10, 1);
         assert(v.size() == 101);
diff --git a/test/depr/depr.c.headers/locale_h.pass.cpp b/test/depr/depr.c.headers/locale_h.pass.cpp
index eff9b2b..6ecf5a8 100644
--- a/test/depr/depr.c.headers/locale_h.pass.cpp
+++ b/test/depr/depr.c.headers/locale_h.pass.cpp
@@ -43,6 +43,6 @@
 int main()
 {
     lconv lc;
-    static_assert((std::is_same<__typeof__(setlocale(0, "")), char*>::value), "");
-    static_assert((std::is_same<__typeof__(localeconv()), lconv*>::value), "");
+    static_assert((std::is_same<decltype(setlocale(0, "")), char*>::value), "");
+    static_assert((std::is_same<decltype(localeconv()), lconv*>::value), "");
 }
diff --git a/test/depr/depr.c.headers/setjmp_h.pass.cpp b/test/depr/depr.c.headers/setjmp_h.pass.cpp
index 2a8abe3..36f4253 100644
--- a/test/depr/depr.c.headers/setjmp_h.pass.cpp
+++ b/test/depr/depr.c.headers/setjmp_h.pass.cpp
@@ -15,6 +15,6 @@
 int main()
 {
     jmp_buf jb;
-    static_assert((std::is_same<__typeof__(longjmp(jb, 0)), void>::value),
-                  "std::is_same<__typeof__(longjmp(jb, 0)), void>::value");
+    static_assert((std::is_same<decltype(longjmp(jb, 0)), void>::value),
+                  "std::is_same<decltype(longjmp(jb, 0)), void>::value");
 }
diff --git a/test/depr/depr.c.headers/stdarg_h.pass.cpp b/test/depr/depr.c.headers/stdarg_h.pass.cpp
index 2c18c5d..7a60902 100644
--- a/test/depr/depr.c.headers/stdarg_h.pass.cpp
+++ b/test/depr/depr.c.headers/stdarg_h.pass.cpp
@@ -15,8 +15,10 @@
 #error va_arg not defined
 #endif
 
-#ifndef va_copy
-#error va_copy not defined
+#if __cplusplus >= 201103L
+#  ifndef va_copy
+#    error va_copy is not defined when c++ >= 11
+#  endif
 #endif
 
 #ifndef va_end
diff --git a/test/depr/depr.c.headers/tgmath_h.pass.cpp b/test/depr/depr.c.headers/tgmath_h.pass.cpp
index c4c9e85..a2ef814 100644
--- a/test/depr/depr.c.headers/tgmath_h.pass.cpp
+++ b/test/depr/depr.c.headers/tgmath_h.pass.cpp
@@ -19,4 +19,5 @@
 {
     std::complex<double> cd;
     double x = sin(1.0);
+    (void)x; // to placate scan-build
 }
diff --git a/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp b/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp
index 78343f8..5ea4988 100644
--- a/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.cons/default.pass.cpp
@@ -24,4 +24,5 @@
     std::string s("dog");
     out << i << ' ' << d << ' ' << s << std::ends;
     assert(out.str() == std::string("123 4.5 dog"));
+    out.freeze(false);
 }
diff --git a/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/freeze.pass.cpp b/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/freeze.pass.cpp
index 97869f6..a60c7cb 100644
--- a/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/freeze.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/freeze.pass.cpp
@@ -29,5 +29,6 @@
         out << 'a';
         out << char(0);
         assert(out.str() == std::string("a"));
+        out.freeze(false);
     }
 }
diff --git a/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/str.pass.cpp b/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/str.pass.cpp
index 9a5542a..9a7160f 100644
--- a/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/str.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.ostrstream/depr.ostrstream.members/str.pass.cpp
@@ -22,5 +22,6 @@
         std::ostrstream out;
         out << 123 << ' ' << 4.5 << ' ' << "dog" << std::ends;
         assert(out.str() == std::string("123 4.5 dog"));
+        out.freeze(false);
     }
 }
diff --git a/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp b/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp
index 374f430..2ec5e7f 100644
--- a/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.cons/default.pass.cpp
@@ -31,4 +31,5 @@
     assert(i == 123);
     assert(d == 4.5);
     assert(strcmp(s.c_str(), "dog") == 0);
+    inout.freeze(false);
 }
diff --git a/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/freeze.pass.cpp b/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/freeze.pass.cpp
index 525073c..4734338 100644
--- a/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/freeze.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/freeze.pass.cpp
@@ -29,5 +29,6 @@
         out << 'a';
         out << char(0);
         assert(out.str() == std::string("a"));
+        out.freeze(false);
     }
 }
diff --git a/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/str.pass.cpp b/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/str.pass.cpp
index 4ac1c44..5c273dc 100644
--- a/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/str.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.strstream/depr.strstream.oper/str.pass.cpp
@@ -22,5 +22,6 @@
         std::strstream out;
         out << 123 << ' ' << 4.5 << ' ' << "dog" << std::ends;
         assert(out.str() == std::string("123 4.5 dog"));
+        out.freeze(false);
     }
 }
diff --git a/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/pcount.pass.cpp b/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/pcount.pass.cpp
index 03e58cb..d96f0f7 100644
--- a/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/pcount.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/pcount.pass.cpp
@@ -27,5 +27,6 @@
         assert(sb.pcount() == 2);
         assert(sb.str() == std::string("a"));
         assert(sb.pcount() == 2);
+        sb.freeze(false);
     }
 }
diff --git a/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/str.pass.cpp b/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/str.pass.cpp
index dce29c9..27de56f 100644
--- a/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/str.pass.cpp
+++ b/test/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.members/str.pass.cpp
@@ -23,5 +23,6 @@
         assert(sb.sputc('a') == 'a');
         assert(sb.sputc(0) == 0);
         assert(sb.str() == std::string("a"));
+        sb.freeze(false);
     }
 }
diff --git a/test/experimental/nothing_to_do.pass.cpp b/test/experimental/nothing_to_do.pass.cpp
new file mode 100644
index 0000000..c21f8a7
--- /dev/null
+++ b/test/experimental/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <experimental/string_view>
+
+int main () {}
diff --git a/test/experimental/string.view/nothing_to_do.pass.cpp b/test/experimental/string.view/nothing_to_do.pass.cpp
new file mode 100644
index 0000000..c21f8a7
--- /dev/null
+++ b/test/experimental/string.view/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <experimental/string_view>
+
+int main () {}
diff --git a/test/experimental/string.view/string.view.access/at.pass.cpp b/test/experimental/string.view/string.view.access/at.pass.cpp
new file mode 100644
index 0000000..90c4ac8
--- /dev/null
+++ b/test/experimental/string.view/string.view.access/at.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr const _CharT& at(size_type _pos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <typename CharT>
+void test ( const CharT *s, size_t len ) {
+    std::experimental::basic_string_view<CharT> sv ( s, len );
+    assert ( sv.length() == len );
+    for ( size_t i = 0; i < len; ++i ) {
+        assert (  sv.at(i) == s[i] );
+        assert ( &sv.at(i) == s + i );
+        }
+
+    try { sv.at(len); } catch ( const std::out_of_range & ) { return ; }
+    assert ( false );
+    }
+    
+int main () {
+    test ( "ABCDE", 5 );
+    test ( "a", 1 );
+
+    test ( L"ABCDE", 5 );
+    test ( L"a", 1 );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDE", 5 );
+    test ( u"a", 1 );
+
+    test ( U"ABCDE", 5 );
+    test ( U"a", 1 );
+#endif
+
+#if __cplusplus >= 201103L
+    {
+    constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 );
+    static_assert ( sv.length() ==  2,  "" );
+    static_assert ( sv.at(0) == 'A', "" );
+    static_assert ( sv.at(1) == 'B', "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.access/back.pass.cpp b/test/experimental/string.view/string.view.access/back.pass.cpp
new file mode 100644
index 0000000..093a858
--- /dev/null
+++ b/test/experimental/string.view/string.view.access/back.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr const _CharT& front();
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <typename CharT>
+bool test ( const CharT *s, size_t len ) {
+    std::experimental::basic_string_view<CharT> sv ( s, len );
+    assert ( sv.length() == len );
+    assert ( sv.back() == s[len-1] );
+    return &sv.back() == s + len - 1;
+    }
+    
+int main () {
+    assert ( test ( "ABCDE", 5 ));
+    assert ( test ( "a", 1 ));
+
+    assert ( test ( L"ABCDE", 5 ));
+    assert ( test ( L"a", 1 ));
+
+#if __cplusplus >= 201103L
+    assert ( test ( u"ABCDE", 5 ));
+    assert ( test ( u"a", 1 ));
+
+    assert ( test ( U"ABCDE", 5 ));
+    assert ( test ( U"a", 1 ));
+#endif
+
+#if __cplusplus >= 201103L
+    {
+    constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 );
+    static_assert ( sv.length() ==  2,  "" );
+    static_assert ( sv.back()  == 'B', "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.access/data.pass.cpp b/test/experimental/string.view/string.view.access/data.pass.cpp
new file mode 100644
index 0000000..562a765
--- /dev/null
+++ b/test/experimental/string.view/string.view.access/data.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr const _CharT* data() const noexcept;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <typename CharT>
+void test ( const CharT *s, size_t len ) {
+    std::experimental::basic_string_view<CharT> sv ( s, len );
+    assert ( sv.length() == len );
+    assert ( sv.data() == s );
+    }
+    
+int main () {
+    test ( "ABCDE", 5 );
+    test ( "a", 1 );
+
+    test ( L"ABCDE", 5 );
+    test ( L"a", 1 );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDE", 5 );
+    test ( u"a", 1 );
+
+    test ( U"ABCDE", 5 );
+    test ( U"a", 1 );
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr const char *s = "ABC";
+    constexpr std::experimental::basic_string_view<char> sv( s, 2 );
+    static_assert( sv.length() ==  2,  "" );
+    static_assert( sv.data() == s, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.access/front.pass.cpp b/test/experimental/string.view/string.view.access/front.pass.cpp
new file mode 100644
index 0000000..e9df44b
--- /dev/null
+++ b/test/experimental/string.view/string.view.access/front.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr const _CharT& back();
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <typename CharT>
+bool test ( const CharT *s, size_t len ) {
+    std::experimental::basic_string_view<CharT> sv ( s, len );
+    assert ( sv.length() == len );
+    assert ( sv.front() == s[0] );
+    return &sv.front() == s;
+    }
+    
+int main () {
+    assert ( test ( "ABCDE", 5 ));
+    assert ( test ( "a", 1 ));
+
+    assert ( test ( L"ABCDE", 5 ));
+    assert ( test ( L"a", 1 ));
+
+#if __cplusplus >= 201103L
+    assert ( test ( u"ABCDE", 5 ));
+    assert ( test ( u"a", 1 ));
+
+    assert ( test ( U"ABCDE", 5 ));
+    assert ( test ( U"a", 1 ));
+#endif
+
+#if __cplusplus >= 201103L
+    {
+    constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 );
+    static_assert ( sv.length() ==  2,  "" );
+    static_assert ( sv.front()  == 'A', "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.access/index.pass.cpp b/test/experimental/string.view/string.view.access/index.pass.cpp
new file mode 100644
index 0000000..4491207
--- /dev/null
+++ b/test/experimental/string.view/string.view.access/index.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr const _CharT& operator[](size_type _pos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <typename CharT>
+void test ( const CharT *s, size_t len ) {
+    std::experimental::basic_string_view<CharT> sv ( s, len );
+    assert ( sv.length() == len );
+    for ( size_t i = 0; i < len; ++i ) {
+        assert ( sv[i] == s[i] );
+        assert ( &sv[i] == s + i );
+        }
+    }
+    
+int main () {
+    test ( "ABCDE", 5 );
+    test ( "a", 1 );
+
+    test ( L"ABCDE", 5 );
+    test ( L"a", 1 );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDE", 5 );
+    test ( u"a", 1 );
+
+    test ( U"ABCDE", 5 );
+    test ( U"a", 1 );
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr std::experimental::basic_string_view<char> sv ( "ABC", 2 );
+    static_assert ( sv.length() ==  2,  "" );
+    static_assert ( sv[0]  == 'A', "" );
+    static_assert ( sv[1]  == 'B', "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.capacity/capacity.pass.cpp b/test/experimental/string.view/string.view.capacity/capacity.pass.cpp
new file mode 100644
index 0000000..eb80216
--- /dev/null
+++ b/test/experimental/string.view/string.view.capacity/capacity.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// [string.view.capacity], capacity
+// constexpr size_type size()     const noexcept;
+// constexpr size_type length()   const noexcept;
+// constexpr size_type max_size() const noexcept;
+// constexpr bool empty()         const noexcept;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename SV>
+void test1 () {
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr SV sv1;
+    static_assert ( sv1.size() == 0, "" );
+    static_assert ( sv1.empty(), "");
+    static_assert ( sv1.size() == sv1.length(), "" );
+    static_assert ( sv1.max_size() > sv1.size(), "");
+    }
+#endif
+    
+    {
+    SV sv1;
+    assert ( sv1.size() == 0 );
+    assert ( sv1.empty());
+    assert ( sv1.size() == sv1.length());
+    assert ( sv1.max_size() > sv1.size());
+    }
+}
+
+template<typename CharT>
+void test2 ( const CharT *s, size_t len ) {
+    {
+    std::experimental::basic_string_view<CharT> sv1 ( s );
+    assert ( sv1.size() == len );
+    assert ( sv1.data() == s );
+    assert ( sv1.empty() == (len == 0));
+    assert ( sv1.size() == sv1.length());
+    assert ( sv1.max_size() > sv1.size());
+    }
+}
+
+int main () {
+    typedef std::experimental::string_view    string_view;
+    typedef std::experimental::u16string_view u16string_view;
+    typedef std::experimental::u32string_view u32string_view;
+    typedef std::experimental::wstring_view   wstring_view;
+
+    test1<string_view> ();
+    test1<u16string_view> ();
+    test1<u32string_view> ();
+    test1<wstring_view> ();
+
+    test2 ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 );
+    test2 ( "ABCDE", 5 );
+    test2 ( "a", 1 );
+    test2 ( "", 0 );
+
+    test2 ( L"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 );
+    test2 ( L"ABCDE", 5 );
+    test2 ( L"a", 1 );
+    test2 ( L"", 0 );
+
+#if __cplusplus >= 201103L
+    test2 ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 );
+    test2 ( u"ABCDE", 5 );
+    test2 ( u"a", 1 );
+    test2 ( u"", 0 );
+
+    test2 ( U"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE", 105 );
+    test2 ( U"ABCDE", 5 );
+    test2 ( U"a", 1 );
+    test2 ( U"", 0 );
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp b/test/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp
new file mode 100644
index 0000000..148dc18
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opeq.string_view.pointer.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits>
+//   constexpr bool operator==(basic_string_view<charT,traits> lhs, const charT* rhs);
+// template<class charT, class traits>
+//   constexpr bool operator==(const charT* lhs, basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(S lhs, const typename S::value_type* rhs, bool x)
+{
+    assert((lhs == rhs) == x);
+    assert((rhs == lhs) == x);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), "", true);
+    test(S(""), "abcde", false);
+    test(S(""), "abcdefghij", false);
+    test(S(""), "abcdefghijklmnopqrst", false);
+    test(S("abcde"), "", false);
+    test(S("abcde"), "abcde", true);
+    test(S("abcde"), "abcdefghij", false);
+    test(S("abcde"), "abcdefghijklmnopqrst", false);
+    test(S("abcdefghij"), "", false);
+    test(S("abcdefghij"), "abcde", false);
+    test(S("abcdefghij"), "abcdefghij", true);
+    test(S("abcdefghij"), "abcdefghijklmnopqrst", false);
+    test(S("abcdefghijklmnopqrst"), "", false);
+    test(S("abcdefghijklmnopqrst"), "abcde", false);
+    test(S("abcdefghijklmnopqrst"), "abcdefghij", false);
+    test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+    static_assert (  sv1     == "", "" );
+    static_assert (  ""      == sv1, "" );
+    static_assert (!(sv1     == "abcde"), "" );
+    static_assert (!("abcde" == sv1), "" );
+    
+    static_assert (  sv2      == "abcde", "" );
+    static_assert (  "abcde"  == sv2, "" );
+    static_assert (!(sv2      == "abcde0"), "" );
+    static_assert (!("abcde0" == sv2), "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp b/test/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp
new file mode 100644
index 0000000..23a2aef
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opeq.string_view.string.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   bool operator==(const charT* lhs, const basic_string<charT,traits> rhs);
+// template<class charT, class traits, class Allocator>
+//   bool operator==(const basic_string_view<charT,traits> lhs, const CharT* rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+template <class S>
+void
+test(const std::string &lhs, S rhs, bool x)
+{
+    assert((lhs == rhs) == x);
+    assert((rhs == lhs) == x);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test("", S(""), true);
+    test("", S("abcde"), false);
+    test("", S("abcdefghij"), false);
+    test("", S("abcdefghijklmnopqrst"), false);
+    test("abcde", S(""), false);
+    test("abcde", S("abcde"), true);
+    test("abcde", S("abcdefghij"), false);
+    test("abcde", S("abcdefghijklmnopqrst"), false);
+    test("abcdefghij", S(""), false);
+    test("abcdefghij", S("abcde"), false);
+    test("abcdefghij", S("abcdefghij"), true);
+    test("abcdefghij", S("abcdefghijklmnopqrst"), false);
+    test("abcdefghijklmnopqrst", S(""), false);
+    test("abcdefghijklmnopqrst", S("abcde"), false);
+    test("abcdefghijklmnopqrst", S("abcdefghij"), false);
+    test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true);
+    }
+}
+#else
+int main () {}
+#endif
diff --git a/test/experimental/string.view/string.view.comparison/opeq.string_view.string_view.pass.cpp b/test/experimental/string.view/string.view.comparison/opeq.string_view.string_view.pass.cpp
new file mode 100644
index 0000000..5971f69
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opeq.string_view.string_view.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator==(const basic_string_view<charT,traits> lhs,
+//                   const basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(S lhs, S rhs, bool x)
+{
+    assert((lhs == rhs) == x);
+    assert((rhs == lhs) == x);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), S(""), true);
+    test(S(""), S("abcde"), false);
+    test(S(""), S("abcdefghij"), false);
+    test(S(""), S("abcdefghijklmnopqrst"), false);
+    test(S("abcde"), S(""), false);
+    test(S("abcde"), S("abcde"), true);
+    test(S("abcde"), S("abcdefghij"), false);
+    test(S("abcde"), S("abcdefghijklmnopqrst"), false);
+    test(S("abcdefghij"), S(""), false);
+    test(S("abcdefghij"), S("abcde"), false);
+    test(S("abcdefghij"), S("abcdefghij"), true);
+    test(S("abcdefghij"), S("abcdefghijklmnopqrst"), false);
+    test(S("abcdefghijklmnopqrst"), S(""), false);
+    test(S("abcdefghijklmnopqrst"), S("abcde"), false);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghij"), false);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2;
+    constexpr SV  sv3 { "abcde", 5 };
+    static_assert (  sv1 == sv2, "" );
+    static_assert (!(sv1 == sv3), "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp b/test/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp
new file mode 100644
index 0000000..f02459b
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opge.string_view.pointer.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator>=(const charT* lhs, basic_string_wiew<charT,traits> rhs);
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator>=(basic_string_wiew<charT,traits> lhs, const charT* rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const typename S::value_type* lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs >= rhs) == x);
+    assert((rhs >= lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test("", S(""), true, true);
+    test("", S("abcde"), false, true);
+    test("", S("abcdefghij"), false, true);
+    test("", S("abcdefghijklmnopqrst"), false, true);
+    test("abcde", S(""), true, false);
+    test("abcde", S("abcde"), true, true);
+    test("abcde", S("abcdefghij"), false, true);
+    test("abcde", S("abcdefghijklmnopqrst"), false, true);
+    test("abcdefghij", S(""), true, false);
+    test("abcdefghij", S("abcde"), true, false);
+    test("abcdefghij", S("abcdefghij"), true, true);
+    test("abcdefghij", S("abcdefghijklmnopqrst"), false, true);
+    test("abcdefghijklmnopqrst", S(""), true, false);
+    test("abcdefghijklmnopqrst", S("abcde"), true, false);
+    test("abcdefghijklmnopqrst", S("abcdefghij"), true, false);
+    test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true, true);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (  sv1     >= "", "" );
+    static_assert (  ""      >= sv1, "" );
+    static_assert (!(sv1     >= "abcde"), "" );
+    static_assert (  "abcde" >= sv1, "" );
+    
+    static_assert (  sv2      >= "", "" );
+    static_assert (!(""       >= sv2), "" );
+    static_assert (  sv2      >= "abcde", "" );
+    static_assert (  "abcde"  >= sv2, "" );
+    static_assert (!(sv2      >= "abcde0"), "" );
+    static_assert (  "abcde0" >= sv2, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opge.string_view.string.pass.cpp b/test/experimental/string.view/string.view.comparison/opge.string_view.string.pass.cpp
new file mode 100644
index 0000000..0790f80
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opge.string_view.string.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
+//                   basic_string_view<charT,traits> rhs);
+//   bool operator>=(basic_string_view<charT,traits> lhs,
+//            const basic_string<charT,traits,Allocator>&  rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& lhs, const typename S::value_type* rhs, bool x, bool y)
+{
+    assert((lhs >= rhs) == x);
+    assert((rhs >= lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), "", true, true);
+    test(S(""), "abcde", false, true);
+    test(S(""), "abcdefghij", false, true);
+    test(S(""), "abcdefghijklmnopqrst", false, true);
+    test(S("abcde"), "", true, false);
+    test(S("abcde"), "abcde", true, true);
+    test(S("abcde"), "abcdefghij", false, true);
+    test(S("abcde"), "abcdefghijklmnopqrst", false, true);
+    test(S("abcdefghij"), "", true, false);
+    test(S("abcdefghij"), "abcde", true, false);
+    test(S("abcdefghij"), "abcdefghij", true, true);
+    test(S("abcdefghij"), "abcdefghijklmnopqrst", false, true);
+    test(S("abcdefghijklmnopqrst"), "", true, false);
+    test(S("abcdefghijklmnopqrst"), "abcde", true, false);
+    test(S("abcdefghijklmnopqrst"), "abcdefghij", true, false);
+    test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true, true);
+    }
+}
diff --git a/test/experimental/string.view/string.view.comparison/opge.string_view.string_view.pass.cpp b/test/experimental/string.view/string.view.comparison/opge.string_view.string_view.pass.cpp
new file mode 100644
index 0000000..e13a4ea
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opge.string_view.string_view.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits>
+//   constexpr bool operator>=(basic_string_view<charT,traits> lhs,
+//                  basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs >= rhs) == x);
+    assert((rhs >= lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), S(""), true, true);
+    test(S(""), S("abcde"), false, true);
+    test(S(""), S("abcdefghij"), false, true);
+    test(S(""), S("abcdefghijklmnopqrst"), false, true);
+    test(S("abcde"), S(""), true, false);
+    test(S("abcde"), S("abcde"), true, true);
+    test(S("abcde"), S("abcdefghij"), false, true);
+    test(S("abcde"), S("abcdefghijklmnopqrst"), false, true);
+    test(S("abcdefghij"), S(""), true, false);
+    test(S("abcdefghij"), S("abcde"), true, false);
+    test(S("abcdefghij"), S("abcdefghij"), true, true);
+    test(S("abcdefghij"), S("abcdefghijklmnopqrst"), false, true);
+    test(S("abcdefghijklmnopqrst"), S(""), true, false);
+    test(S("abcdefghijklmnopqrst"), S("abcde"), true, false);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghij"), true, false);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true, true);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (  sv1 >= sv1,  "" );
+    static_assert (  sv2 >= sv2,  "" );
+
+    static_assert (!(sv1 >= sv2), "" );
+    static_assert (  sv2 >= sv1,  "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp b/test/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp
new file mode 100644
index 0000000..48703ca
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opgt.string_view.pointer.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// constexpr template<class charT, class traits, class Allocator>
+//   bool operator>(const charT* lhs, basic_string_wiew<charT,traits> rhs);
+// constexpr template<class charT, class traits, class Allocator>
+//   bool operator>(basic_string_wiew<charT,traits> lhs, const charT* rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const typename S::value_type* lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs > rhs) == x);
+    assert((rhs > lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test("", S(""), false, false);
+    test("", S("abcde"), false, true);
+    test("", S("abcdefghij"), false, true);
+    test("", S("abcdefghijklmnopqrst"), false, true);
+    test("abcde", S(""), true, false);
+    test("abcde", S("abcde"), false, false);
+    test("abcde", S("abcdefghij"), false, true);
+    test("abcde", S("abcdefghijklmnopqrst"), false, true);
+    test("abcdefghij", S(""), true, false);
+    test("abcdefghij", S("abcde"), true, false);
+    test("abcdefghij", S("abcdefghij"), false, false);
+    test("abcdefghij", S("abcdefghijklmnopqrst"), false, true);
+    test("abcdefghijklmnopqrst", S(""), true, false);
+    test("abcdefghijklmnopqrst", S("abcde"), true, false);
+    test("abcdefghijklmnopqrst", S("abcdefghij"), true, false);
+    test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), false, false);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (!(sv1     > ""), "" );
+    static_assert (!(""      > sv1), "" );
+    static_assert (!(sv1     > "abcde"), "" );
+    static_assert (  "abcde" > sv1, "" );
+    
+    static_assert (  sv2      > "", "" );
+    static_assert (!(""       > sv2), "" );
+    static_assert (!(sv2      > "abcde"), "" );
+    static_assert (!("abcde"  > sv2), "" );
+    static_assert (!(sv2      > "abcde0"), "" );
+    static_assert (  "abcde0" > sv2, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opgt.string_view.string.pass.cpp b/test/experimental/string.view/string.view.comparison/opgt.string_view.string.pass.cpp
new file mode 100644
index 0000000..92f812f
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opgt.string_view.string.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   bool operator>(const basic_string<charT,traits,Allocator>& lhs,
+//                   basic_string_view<charT,traits> rhs);
+//   bool operator>(basic_string_view<charT,traits> lhs,
+//            const basic_string<charT,traits,Allocator>&  rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& lhs, const typename S::value_type* rhs, bool x, bool y)
+{
+    assert((lhs > rhs) == x);
+    assert((rhs > lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), "", false, false);
+    test(S(""), "abcde", false, true);
+    test(S(""), "abcdefghij", false, true);
+    test(S(""), "abcdefghijklmnopqrst", false, true);
+    test(S("abcde"), "", true, false);
+    test(S("abcde"), "abcde", false, false);
+    test(S("abcde"), "abcdefghij", false, true);
+    test(S("abcde"), "abcdefghijklmnopqrst", false, true);
+    test(S("abcdefghij"), "", true, false);
+    test(S("abcdefghij"), "abcde", true, false);
+    test(S("abcdefghij"), "abcdefghij", false, false);
+    test(S("abcdefghij"), "abcdefghijklmnopqrst", false, true);
+    test(S("abcdefghijklmnopqrst"), "", true, false);
+    test(S("abcdefghijklmnopqrst"), "abcde", true, false);
+    test(S("abcdefghijklmnopqrst"), "abcdefghij", true, false);
+    test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false, false);
+    }
+}
diff --git a/test/experimental/string.view/string.view.comparison/opgt.string_view.string_view.pass.cpp b/test/experimental/string.view/string.view.comparison/opgt.string_view.string_view.pass.cpp
new file mode 100644
index 0000000..3047cc7
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opgt.string_view.string_view.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits>
+//  constexpr bool operator>(basic_string_view<charT,traits> lhs,
+//                  basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs > rhs) == x);
+    assert((rhs > lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), S(""), false, false);
+    test(S(""), S("abcde"), false, true);
+    test(S(""), S("abcdefghij"), false, true);
+    test(S(""), S("abcdefghijklmnopqrst"), false, true);
+    test(S("abcde"), S(""), true, false);
+    test(S("abcde"), S("abcde"), false, false);
+    test(S("abcde"), S("abcdefghij"), false, true);
+    test(S("abcde"), S("abcdefghijklmnopqrst"), false, true);
+    test(S("abcdefghij"), S(""), true, false);
+    test(S("abcdefghij"), S("abcde"), true, false);
+    test(S("abcdefghij"), S("abcdefghij"), false, false);
+    test(S("abcdefghij"), S("abcdefghijklmnopqrst"), false, true);
+    test(S("abcdefghijklmnopqrst"), S(""), true, false);
+    test(S("abcdefghijklmnopqrst"), S("abcde"), true, false);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghij"), true, false);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false, false);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (!(sv1 > sv1), "" );
+    static_assert (!(sv2 > sv2), "" );
+
+    static_assert (!(sv1 > sv2), "" );
+    static_assert (  sv2 > sv1, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp b/test/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp
new file mode 100644
index 0000000..539f5fa
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/ople.string_view.pointer.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator<=(const charT* lhs, basic_string_wiew<charT,traits> rhs);
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator<=(basic_string_wiew<charT,traits> lhs, const charT* rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const typename S::value_type* lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs <= rhs) == x);
+    assert((rhs <= lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test("", S(""), true, true);
+    test("", S("abcde"), true, false);
+    test("", S("abcdefghij"), true, false);
+    test("", S("abcdefghijklmnopqrst"), true, false);
+    test("abcde", S(""), false, true);
+    test("abcde", S("abcde"), true, true);
+    test("abcde", S("abcdefghij"), true, false);
+    test("abcde", S("abcdefghijklmnopqrst"), true, false);
+    test("abcdefghij", S(""), false, true);
+    test("abcdefghij", S("abcde"), false, true);
+    test("abcdefghij", S("abcdefghij"), true, true);
+    test("abcdefghij", S("abcdefghijklmnopqrst"), true, false);
+    test("abcdefghijklmnopqrst", S(""), false, true);
+    test("abcdefghijklmnopqrst", S("abcde"), false, true);
+    test("abcdefghijklmnopqrst", S("abcdefghij"), false, true);
+    test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), true, true);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (  sv1     <= "", "" );
+    static_assert (  ""      <= sv1, "" );
+    static_assert (  sv1     <= "abcde", "" );
+    static_assert (!("abcde" <= sv1), "" );
+    
+    static_assert (!(sv2      <= ""), "" );
+    static_assert (  ""       <= sv2, "" );
+    static_assert (  sv2      <= "abcde", "" );
+    static_assert (  "abcde"  <= sv2, "" );
+    static_assert (  sv2      <= "abcde0", "" );
+    static_assert (!("abcde0" <= sv2), "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/ople.string_view.string.pass.cpp b/test/experimental/string.view/string.view.comparison/ople.string_view.string.pass.cpp
new file mode 100644
index 0000000..39abbd0
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/ople.string_view.string.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
+//                   basic_string_view<charT,traits> rhs);
+//   bool operator<=(basic_string_view<charT,traits> lhs,
+//            const basic_string<charT,traits,Allocator>&  rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& lhs, const typename S::value_type* rhs, bool x, bool y)
+{
+    assert((lhs <= rhs) == x);
+    assert((rhs <= lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), "", true, true);
+    test(S(""), "abcde", true, false);
+    test(S(""), "abcdefghij", true, false);
+    test(S(""), "abcdefghijklmnopqrst", true, false);
+    test(S("abcde"), "", false, true);
+    test(S("abcde"), "abcde", true, true);
+    test(S("abcde"), "abcdefghij", true, false);
+    test(S("abcde"), "abcdefghijklmnopqrst", true, false);
+    test(S("abcdefghij"), "", false, true);
+    test(S("abcdefghij"), "abcde", false, true);
+    test(S("abcdefghij"), "abcdefghij", true, true);
+    test(S("abcdefghij"), "abcdefghijklmnopqrst", true, false);
+    test(S("abcdefghijklmnopqrst"), "", false, true);
+    test(S("abcdefghijklmnopqrst"), "abcde", false, true);
+    test(S("abcdefghijklmnopqrst"), "abcdefghij", false, true);
+    test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", true, true);
+    }
+}
diff --git a/test/experimental/string.view/string.view.comparison/ople.string_view.string_view.pass.cpp b/test/experimental/string.view/string.view.comparison/ople.string_view.string_view.pass.cpp
new file mode 100644
index 0000000..17219a4
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/ople.string_view.string_view.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits>
+//   constexpr bool operator<=(basic_string_view<charT,traits> lhs,
+//                  basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs <= rhs) == x);
+    assert((rhs <= lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), S(""), true, true);
+    test(S(""), S("abcde"), true, false);
+    test(S(""), S("abcdefghij"), true, false);
+    test(S(""), S("abcdefghijklmnopqrst"), true, false);
+    test(S("abcde"), S(""), false, true);
+    test(S("abcde"), S("abcde"), true, true);
+    test(S("abcde"), S("abcdefghij"), true, false);
+    test(S("abcde"), S("abcdefghijklmnopqrst"), true, false);
+    test(S("abcdefghij"), S(""), false, true);
+    test(S("abcdefghij"), S("abcde"), false, true);
+    test(S("abcdefghij"), S("abcdefghij"), true, true);
+    test(S("abcdefghij"), S("abcdefghijklmnopqrst"), true, false);
+    test(S("abcdefghijklmnopqrst"), S(""), false, true);
+    test(S("abcdefghijklmnopqrst"), S("abcde"), false, true);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghij"), false, true);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), true, true);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (  sv1 <= sv1,  "" );
+    static_assert (  sv2 <= sv2,  "" );
+
+    static_assert (  sv1 <= sv2,  "" );
+    static_assert (!(sv2 <= sv1), "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp b/test/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp
new file mode 100644
index 0000000..a1013e4
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/oplt.string_view.pointer.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator<(const charT* lhs, basic_string_wiew<charT,traits> rhs);
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator<(basic_string_wiew<charT,traits> lhs, const charT* rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const typename S::value_type* lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs < rhs) == x);
+    assert((rhs < lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test("", S(""), false, false);
+    test("", S("abcde"), true, false);
+    test("", S("abcdefghij"), true, false);
+    test("", S("abcdefghijklmnopqrst"), true, false);
+    test("abcde", S(""), false, true);
+    test("abcde", S("abcde"), false, false);
+    test("abcde", S("abcdefghij"), true, false);
+    test("abcde", S("abcdefghijklmnopqrst"), true, false);
+    test("abcdefghij", S(""), false, true);
+    test("abcdefghij", S("abcde"), false, true);
+    test("abcdefghij", S("abcdefghij"), false, false);
+    test("abcdefghij", S("abcdefghijklmnopqrst"), true, false);
+    test("abcdefghijklmnopqrst", S(""), false, true);
+    test("abcdefghijklmnopqrst", S("abcde"), false, true);
+    test("abcdefghijklmnopqrst", S("abcdefghij"), false, true);
+    test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), false, false);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (!(sv1     < ""), "" );
+    static_assert (!(""      < sv1), "" );
+    static_assert (  sv1     < "abcde", "" );
+    static_assert (!("abcde" < sv1), "" );
+    
+    static_assert (!(sv2      < ""), "" );
+    static_assert (  ""       < sv2, "" );
+    static_assert (!(sv2      < "abcde"), "" );
+    static_assert (!("abcde"  < sv2), "" );
+    static_assert (  sv2      < "abcde0", "" );
+    static_assert (!("abcde0" < sv2), "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/oplt.string_view.string.pass.cpp b/test/experimental/string.view/string.view.comparison/oplt.string_view.string.pass.cpp
new file mode 100644
index 0000000..51ea639
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/oplt.string_view.string.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   bool operator<(const basic_string<charT,traits,Allocator>& lhs,
+//                   basic_string_view<charT,traits> rhs);
+//   bool operator<(basic_string_view<charT,traits> lhs,
+//            const basic_string<charT,traits,Allocator>&  rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& lhs, const typename S::value_type* rhs, bool x, bool y)
+{
+    assert((lhs < rhs) == x);
+    assert((rhs < lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), "", false, false);
+    test(S(""), "abcde", true, false);
+    test(S(""), "abcdefghij", true, false);
+    test(S(""), "abcdefghijklmnopqrst", true, false);
+    test(S("abcde"), "", false, true);
+    test(S("abcde"), "abcde", false, false);
+    test(S("abcde"), "abcdefghij", true, false);
+    test(S("abcde"), "abcdefghijklmnopqrst", true, false);
+    test(S("abcdefghij"), "", false, true);
+    test(S("abcdefghij"), "abcde", false, true);
+    test(S("abcdefghij"), "abcdefghij", false, false);
+    test(S("abcdefghij"), "abcdefghijklmnopqrst", true, false);
+    test(S("abcdefghijklmnopqrst"), "", false, true);
+    test(S("abcdefghijklmnopqrst"), "abcde", false, true);
+    test(S("abcdefghijklmnopqrst"), "abcdefghij", false, true);
+    test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false, false);
+    }
+}
diff --git a/test/experimental/string.view/string.view.comparison/oplt.string_view.string_view.pass.cpp b/test/experimental/string.view/string.view.comparison/oplt.string_view.string_view.pass.cpp
new file mode 100644
index 0000000..df9e908
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/oplt.string_view.string_view.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits>
+//   constexpr bool operator<(basic_string_view<charT,traits> lhs,
+//                  basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& lhs, const S& rhs, bool x, bool y)
+{
+    assert((lhs < rhs) == x);
+    assert((rhs < lhs) == y);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), S(""), false, false);
+    test(S(""), S("abcde"), true, false);
+    test(S(""), S("abcdefghij"), true, false);
+    test(S(""), S("abcdefghijklmnopqrst"), true, false);
+    test(S("abcde"), S(""), false, true);
+    test(S("abcde"), S("abcde"), false, false);
+    test(S("abcde"), S("abcdefghij"), true, false);
+    test(S("abcde"), S("abcdefghijklmnopqrst"), true, false);
+    test(S("abcdefghij"), S(""), false, true);
+    test(S("abcdefghij"), S("abcde"), false, true);
+    test(S("abcdefghij"), S("abcdefghij"), false, false);
+    test(S("abcdefghij"), S("abcdefghijklmnopqrst"), true, false);
+    test(S("abcdefghijklmnopqrst"), S(""), false, true);
+    test(S("abcdefghijklmnopqrst"), S("abcde"), false, true);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghij"), false, true);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false, false);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (!(sv1 < sv1), "" );
+    static_assert (!(sv2 < sv2), "" );
+
+    static_assert (  sv1 < sv2,  "" );
+    static_assert (!(sv2 < sv1), "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp b/test/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp
new file mode 100644
index 0000000..299be93
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opne.string_view.pointer.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits>
+//   constexpr bool operator!=(basic_string_view<charT,traits> lhs, const charT* rhs);
+// template<class charT, class traits>
+//   constexpr bool operator!=(const charT* lhs, basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(S lhs, const typename S::value_type* rhs, bool x)
+{
+    assert((lhs != rhs) == x);
+    assert((rhs != lhs) == x);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), "", false);
+    test(S(""), "abcde", true);
+    test(S(""), "abcdefghij", true);
+    test(S(""), "abcdefghijklmnopqrst", true);
+    test(S("abcde"), "", true);
+    test(S("abcde"), "abcde", false);
+    test(S("abcde"), "abcdefghij", true);
+    test(S("abcde"), "abcdefghijklmnopqrst", true);
+    test(S("abcdefghij"), "", true);
+    test(S("abcdefghij"), "abcde", true);
+    test(S("abcdefghij"), "abcdefghij", false);
+    test(S("abcdefghij"), "abcdefghijklmnopqrst", true);
+    test(S("abcdefghijklmnopqrst"), "", true);
+    test(S("abcdefghijklmnopqrst"), "abcde", true);
+    test(S("abcdefghijklmnopqrst"), "abcdefghij", true);
+    test(S("abcdefghijklmnopqrst"), "abcdefghijklmnopqrst", false);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (!(sv1     != ""), "" );
+    static_assert (!(""      != sv1), "" );
+    static_assert (  sv1     != "abcde", "" );
+    static_assert (  "abcde" != sv1, "" );
+    
+    static_assert (!(sv2      != "abcde"), "" );
+    static_assert (!("abcde"  != sv2), "" );
+    static_assert (  sv2      != "abcde0",   "" );
+    static_assert (  "abcde0" != sv2, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.comparison/opne.string_view.string.pass.cpp b/test/experimental/string.view/string.view.comparison/opne.string_view.string.pass.cpp
new file mode 100644
index 0000000..9ed0ac1
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opne.string_view.string.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   bool operator!=(const basic_string<charT, traits, Allocator> &lhs, basic_string_view<charT,traits> rhs);
+// template<class charT, class traits, class Allocator>
+//   bool operator!=(basic_string_view<charT,traits> lhs, const basic_string<charT, traits, Allocator> &rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const std::string &lhs, S rhs, bool x)
+{
+    assert((lhs != rhs) == x);
+    assert((rhs != lhs) == x);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test("", S(""), false);
+    test("", S("abcde"), true);
+    test("", S("abcdefghij"), true);
+    test("", S("abcdefghijklmnopqrst"), true);
+    test("abcde", S(""), true);
+    test("abcde", S("abcde"), false);
+    test("abcde", S("abcdefghij"), true);
+    test("abcde", S("abcdefghijklmnopqrst"), true);
+    test("abcdefghij", S(""), true);
+    test("abcdefghij", S("abcde"), true);
+    test("abcdefghij", S("abcdefghij"), false);
+    test("abcdefghij", S("abcdefghijklmnopqrst"), true);
+    test("abcdefghijklmnopqrst", S(""), true);
+    test("abcdefghijklmnopqrst", S("abcde"), true);
+    test("abcdefghijklmnopqrst", S("abcdefghij"), true);
+    test("abcdefghijklmnopqrst", S("abcdefghijklmnopqrst"), false);
+    }
+}
diff --git a/test/experimental/string.view/string.view.comparison/opne.string_view.string_view.pass.cpp b/test/experimental/string.view/string.view.comparison/opne.string_view.string_view.pass.cpp
new file mode 100644
index 0000000..c99489e
--- /dev/null
+++ b/test/experimental/string.view/string.view.comparison/opne.string_view.string_view.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// template<class charT, class traits, class Allocator>
+//   constexpr bool operator!=(const basic_string_view<charT,traits> lhs,
+//                   const basic_string_view<charT,traits> rhs);
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(S lhs, S rhs, bool x)
+{
+    assert((lhs != rhs) == x);
+    assert((rhs != lhs) == x);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), S(""), false);
+    test(S(""), S("abcde"), true);
+    test(S(""), S("abcdefghij"), true);
+    test(S(""), S("abcdefghijklmnopqrst"), true);
+    test(S("abcde"), S(""), true);
+    test(S("abcde"), S("abcde"), false);
+    test(S("abcde"), S("abcdefghij"), true);
+    test(S("abcde"), S("abcdefghijklmnopqrst"), true);
+    test(S("abcdefghij"), S(""), true);
+    test(S("abcdefghij"), S("abcde"), true);
+    test(S("abcdefghij"), S("abcdefghij"), false);
+    test(S("abcdefghij"), S("abcdefghijklmnopqrst"), true);
+    test(S("abcdefghijklmnopqrst"), S(""), true);
+    test(S("abcdefghijklmnopqrst"), S("abcde"), true);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghij"), true);
+    test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrst"), false);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2;
+    constexpr SV  sv3 { "abcde", 5 };
+    static_assert (!( sv1 != sv2), "" );
+    static_assert (   sv1 != sv3,  "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.cons/default.pass.cpp b/test/experimental/string.view/string.view.cons/default.pass.cpp
new file mode 100644
index 0000000..e1d69f4
--- /dev/null
+++ b/test/experimental/string.view/string.view.cons/default.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr basic_string_view () noexcept;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename T>
+void test () {
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr T sv1;
+    static_assert ( sv1.size() == 0, "" );
+    static_assert ( sv1.empty(), "");
+    }
+#endif
+    
+    {
+    T sv1;
+    assert ( sv1.size() == 0 );
+    assert ( sv1.empty());
+    }
+}
+
+int main () {
+    typedef std::experimental::string_view    string_view;
+    typedef std::experimental::u16string_view u16string_view;
+    typedef std::experimental::u32string_view u32string_view;
+    typedef std::experimental::wstring_view   wstring_view;
+
+    test<string_view> ();
+    test<u16string_view> ();
+    test<u32string_view> ();
+    test<wstring_view> ();
+
+}
diff --git a/test/experimental/string.view/string.view.cons/from_literal.pass.cpp b/test/experimental/string.view/string.view.cons/from_literal.pass.cpp
new file mode 100644
index 0000000..82d0d79
--- /dev/null
+++ b/test/experimental/string.view/string.view.cons/from_literal.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr basic_string_view(const _CharT* _s)
+//    : __data (_s), __size(_Traits::length(_s)) {}
+
+
+#include <experimental/string_view>
+#include <string>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template<typename CharT>
+size_t StrLen ( const CharT *s ) {
+    size_t retVal = 0;
+    while ( *s != 0 ) { ++retVal; ++s; }
+    return retVal;
+    }
+
+template<typename CharT>
+void test ( const CharT *s ) {
+    std::experimental::basic_string_view<CharT> sv1 ( s );
+    assert ( sv1.size() == StrLen( s ));
+    assert ( sv1.data() == s );
+    }
+
+
+int main () {
+
+    test ( "QBCDE" );
+    test ( "A" );
+    test ( "" );
+    
+    test ( L"QBCDE" );
+    test ( L"A" );
+    test ( L"" );
+
+#if __cplusplus >= 201103L
+    test ( u"QBCDE" );
+    test ( u"A" );
+    test ( u"" );
+
+    test ( U"QBCDE" );
+    test ( U"A" );
+    test ( U"" );
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr std::experimental::basic_string_view<char, constexpr_char_traits<char>> sv1 ( "ABCDE" );
+    static_assert ( sv1.size() == 5, "");
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp b/test/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp
new file mode 100644
index 0000000..1038d04
--- /dev/null
+++ b/test/experimental/string.view/string.view.cons/from_ptr_len.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+//  constexpr basic_string_view(const _CharT* _s, size_type _len)
+//      : __data (_s), __size(_len) {}
+
+
+#include <experimental/string_view>
+#include <string>
+#include <cassert>
+
+template<typename CharT>
+void test ( const CharT *s, size_t sz ) {
+    {
+    std::experimental::basic_string_view<CharT> sv1 ( s, sz );
+    assert ( sv1.size() == sz );
+    assert ( sv1.data() == s );
+    }
+}
+
+int main () {
+
+    test ( "QBCDE", 5 );
+    test ( "QBCDE", 2 );
+    test ( "", 0 );
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr const char *s = "QBCDE";
+    constexpr std::experimental::basic_string_view<char> sv1 ( s, 2 );
+    static_assert ( sv1.size() == 2, "" );
+    static_assert ( sv1.data() == s, "" );
+    }
+#endif
+
+    test ( L"QBCDE", 5 );
+    test ( L"QBCDE", 2 );
+    test ( L"", 0 );
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr const wchar_t *s = L"QBCDE";
+    constexpr std::experimental::basic_string_view<wchar_t> sv1 ( s, 2 );
+    static_assert ( sv1.size() == 2, "" );
+    static_assert ( sv1.data() == s, "" );
+    }
+#endif
+
+#if __cplusplus >= 201103L
+    test ( u"QBCDE", 5 );
+    test ( u"QBCDE", 2 );
+    test ( u"", 0 );
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr const char16_t *s = u"QBCDE";
+    constexpr std::experimental::basic_string_view<char16_t> sv1 ( s, 2 );
+    static_assert ( sv1.size() == 2, "" );
+    static_assert ( sv1.data() == s, "" );
+    }
+#endif
+
+    test ( U"QBCDE", 5 );
+    test ( U"QBCDE", 2 );
+    test ( U"", 0 );
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr const char32_t *s = U"QBCDE";
+    constexpr std::experimental::basic_string_view<char32_t> sv1 ( s, 2 );
+    static_assert ( sv1.size() == 2, "" );
+    static_assert ( sv1.data() == s, "" );
+    }
+#endif
+#endif
+}
diff --git a/test/experimental/string.view/string.view.cons/from_string.pass.cpp b/test/experimental/string.view/string.view.cons/from_string.pass.cpp
new file mode 100644
index 0000000..670c033
--- /dev/null
+++ b/test/experimental/string.view/string.view.cons/from_string.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// template<class Allocator>
+// basic_string_view(const basic_string<_CharT, _Traits, Allocator>& _str) noexcept
+
+
+#include <experimental/string_view>
+#include <string>
+#include <cassert>
+
+struct dummy_char_traits : public std::char_traits<char> {};
+
+template<typename CharT, typename Traits>
+void test ( const std::basic_string<CharT, Traits> &str ) {
+    std::experimental::basic_string_view<CharT, Traits> sv1 ( str );
+    assert ( sv1.size() == str.size());
+    assert ( sv1.data() == str.data());
+}
+
+int main () {
+
+    test ( std::string("QBCDE") );
+    test ( std::string("") );
+    test ( std::string() );
+    
+    test ( std::wstring(L"QBCDE") );
+    test ( std::wstring(L"") );
+    test ( std::wstring() );
+
+#if __cplusplus >= 201103L
+    test ( std::u16string{u"QBCDE"} );
+    test ( std::u16string{u""} );
+    test ( std::u16string{} );
+
+    test ( std::u32string{U"QBCDE"} );
+    test ( std::u32string{U""} );
+    test ( std::u32string{} );
+#endif
+    
+    test ( std::basic_string<char, dummy_char_traits>("QBCDE") );
+    test ( std::basic_string<char, dummy_char_traits>("") );
+    test ( std::basic_string<char, dummy_char_traits>() );
+
+}
diff --git a/test/experimental/string.view/string.view.cons/from_string1.fail.cpp b/test/experimental/string.view/string.view.cons/from_string1.fail.cpp
new file mode 100644
index 0000000..6ef4b96
--- /dev/null
+++ b/test/experimental/string.view/string.view.cons/from_string1.fail.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// template<class Allocator>
+// basic_string_view(const basic_string<_CharT, _Traits, Allocator>& _str) noexcept
+
+#include <experimental/string_view>
+#include <string>
+#include <cassert>
+
+struct dummy_char_traits : public std::char_traits<char> {};
+
+int main () {
+    using string_view = std::experimental::basic_string_view<char>;
+    using string      = std::              basic_string     <char, dummy_char_traits>;
+    
+    {
+    string s{"QBCDE"};
+    string_view sv1 ( s );
+    assert ( sv1.size() == s.size());
+    assert ( sv1.data() == s.data());
+    }
+}
\ No newline at end of file
diff --git a/test/experimental/string.view/string.view.cons/from_string2.fail.cpp b/test/experimental/string.view/string.view.cons/from_string2.fail.cpp
new file mode 100644
index 0000000..6c77a3f
--- /dev/null
+++ b/test/experimental/string.view/string.view.cons/from_string2.fail.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// template<class Allocator>
+// basic_string_view(const basic_string<_CharT, _Traits, Allocator>& _str) noexcept
+
+#include <experimental/string_view>
+#include <string>
+#include <cassert>
+
+struct dummy_char_traits : public std::char_traits<char> {};
+
+int main () {
+    using string_view = std::experimental::basic_string_view<char, dummy_char_traits>;
+    using string      = std::              basic_string     <char>;
+    
+    {
+    string s{"QBCDE"};
+    string_view sv1 ( s );
+    assert ( sv1.size() == s.size());
+    assert ( sv1.data() == s.data());
+    }
+}
diff --git a/test/experimental/string.view/string.view.find/find_char_size.pass.cpp b/test/experimental/string.view/string.view.find/find_char_size.pass.cpp
new file mode 100644
index 0000000..6e6a1f5
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_char_size.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find(charT c, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find(c, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x + 1 <= s.size());
+}
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type x)
+{
+    assert(s.find(c) == x);
+    if (x != S::npos)
+        assert(0 <= x && x + 1 <= s.size());
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), 'c', 0, S::npos);
+    test(S(""), 'c', 1, S::npos);
+    test(S("abcde"), 'c', 0, 2);
+    test(S("abcde"), 'c', 1, 2);
+    test(S("abcde"), 'c', 2, 2);
+    test(S("abcde"), 'c', 4, S::npos);
+    test(S("abcde"), 'c', 5, S::npos);
+    test(S("abcde"), 'c', 6, S::npos);
+    test(S("abcdeabcde"), 'c', 0, 2);
+    test(S("abcdeabcde"), 'c', 1, 2);
+    test(S("abcdeabcde"), 'c', 5, 7);
+    test(S("abcdeabcde"), 'c', 9, S::npos);
+    test(S("abcdeabcde"), 'c', 10, S::npos);
+    test(S("abcdeabcde"), 'c', 11, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), 'c', 0, 2);
+    test(S("abcdeabcdeabcdeabcde"), 'c', 1, 2);
+    test(S("abcdeabcdeabcdeabcde"), 'c', 10, 12);
+    test(S("abcdeabcdeabcdeabcde"), 'c', 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), 'c', 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), 'c', 21, S::npos);
+
+    test(S(""), 'c', S::npos);
+    test(S("abcde"), 'c', 2);
+    test(S("abcdeabcde"), 'c', 2);
+    test(S("abcdeabcdeabcdeabcde"), 'c', 2);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find( 'c', 0 ) == SV::npos, "" );
+    static_assert (sv1.find( 'c', 1 ) == SV::npos, "" );
+    static_assert (sv2.find( 'c', 0 ) == 2, "" );
+    static_assert (sv2.find( 'c', 1 ) == 2, "" );
+    static_assert (sv2.find( 'c', 2 ) == 2, "" );
+    static_assert (sv2.find( 'c', 3 ) == SV::npos, "" );
+    static_assert (sv2.find( 'c', 4 ) == SV::npos, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_not_of_char_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_not_of_char_size.pass.cpp
new file mode 100644
index 0000000..73580ae
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_not_of_char_size.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find_first_not_of(charT c, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_first_not_of(c, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type x)
+{
+    assert(s.find_first_not_of(c) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), 'q', 0, S::npos);
+    test(S(""), 'q', 1, S::npos);
+    test(S("kitcj"), 'q', 0, 0);
+    test(S("qkamf"), 'q', 1, 1);
+    test(S("nhmko"), 'q', 2, 2);
+    test(S("tpsaf"), 'q', 4, 4);
+    test(S("lahfb"), 'q', 5, S::npos);
+    test(S("irkhs"), 'q', 6, S::npos);
+    test(S("gmfhdaipsr"), 'q', 0, 0);
+    test(S("kantesmpgj"), 'q', 1, 1);
+    test(S("odaftiegpm"), 'q', 5, 5);
+    test(S("oknlrstdpi"), 'q', 9, 9);
+    test(S("eolhfgpjqk"), 'q', 10, S::npos);
+    test(S("pcdrofikas"), 'q', 11, S::npos);
+    test(S("nbatdlmekrgcfqsophij"), 'q', 0, 0);
+    test(S("bnrpehidofmqtcksjgla"), 'q', 1, 1);
+    test(S("jdmciepkaqgotsrfnhlb"), 'q', 10, 10);
+    test(S("jtdaefblsokrmhpgcnqi"), 'q', 19, 19);
+    test(S("hkbgspofltajcnedqmri"), 'q', 20, S::npos);
+    test(S("oselktgbcapndfjihrmq"), 'q', 21, S::npos);
+
+    test(S(""), 'q', S::npos);
+    test(S("q"), 'q', S::npos);
+    test(S("qqq"), 'q', S::npos);
+    test(S("csope"), 'q', 0);
+    test(S("gfsmthlkon"), 'q', 0);
+    test(S("laenfsbridchgotmkqpj"), 'q', 0);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_first_not_of( 'q', 0 ) == SV::npos, "" );
+    static_assert (sv1.find_first_not_of( 'q', 1 ) == SV::npos, "" );
+    static_assert (sv2.find_first_not_of( 'q', 0 ) == 0, "" );
+    static_assert (sv2.find_first_not_of( 'q', 1 ) == 1, "" );
+    static_assert (sv2.find_first_not_of( 'q', 5 ) == SV::npos, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_not_of_pointer_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_not_of_pointer_size.pass.cpp
new file mode 100644
index 0000000..de93288
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_not_of_pointer_size.pass.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_first_not_of(str, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type x)
+{
+    assert(s.find_first_not_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, S::npos);
+    test(S(""), "laenf", 0, S::npos);
+    test(S(""), "pqlnkmbdjo", 0, S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", 0, S::npos);
+    test(S(""), "", 1, S::npos);
+    test(S(""), "bjaht", 1, S::npos);
+    test(S(""), "hjlcmgpket", 1, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos);
+    test(S("fodgq"), "", 0, 0);
+    test(S("qanej"), "dfkap", 0, 0);
+    test(S("clbao"), "ihqrfebgad", 0, 0);
+    test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, S::npos);
+    test(S("srdfq"), "", 1, 1);
+    test(S("oemth"), "ikcrq", 1, 1);
+    test(S("cdaih"), "dmajblfhsg", 1, 3);
+    test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, S::npos);
+    test(S("cshmd"), "", 2, 2);
+    test(S("lhcdo"), "oebqi", 2, 2);
+    test(S("qnsoh"), "kojhpmbsfe", 2, S::npos);
+    test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, S::npos);
+    test(S("fmtsp"), "", 4, 4);
+    test(S("khbpm"), "aobjd", 4, 4);
+    test(S("pbsji"), "pcbahntsje", 4, 4);
+    test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, S::npos);
+    test(S("eqmpa"), "", 5, S::npos);
+    test(S("omigs"), "kocgb", 5, S::npos);
+    test(S("onmje"), "fbslrjiqkm", 5, S::npos);
+    test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, S::npos);
+    test(S("schfa"), "", 6, S::npos);
+    test(S("igdsc"), "qngpd", 6, S::npos);
+    test(S("brqgo"), "rodhqklgmb", 6, S::npos);
+    test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, S::npos);
+    test(S("hcjitbfapl"), "", 0, 0);
+    test(S("daiprenocl"), "ashjd", 0, 2);
+    test(S("litpcfdghe"), "mgojkldsqh", 0, 1);
+    test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, S::npos);
+    test(S("qpghtfbaji"), "", 1, 1);
+    test(S("gfshlcmdjr"), "nadkh", 1, 1);
+    test(S("nkodajteqp"), "ofdrqmkebl", 1, 4);
+    test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, S::npos);
+    test(S("crnklpmegd"), "", 5, 5);
+    test(S("jsbtafedoc"), "prqgn", 5, 5);
+    test(S("qnmodrtkeb"), "pejafmnokr", 5, 6);
+    test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, S::npos);
+    test(S("lmofqdhpki"), "", 9, 9);
+    test(S("hnefkqimca"), "rtjpa", 9, S::npos);
+    test(S("drtasbgmfp"), "ktsrmnqagd", 9, 9);
+    test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, S::npos);
+    test(S("elgofjmbrq"), "", 10, S::npos);
+    test(S("mjqdgalkpc"), "dplqa", 10, S::npos);
+    test(S("kthqnfcerm"), "dkacjoptns", 10, S::npos);
+    test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, S::npos);
+    test(S("eqsgalomhb"), "", 11, S::npos);
+    test(S("akiteljmoh"), "lofbc", 11, S::npos);
+    test(S("hlbdfreqjo"), "astoegbfpn", 11, S::npos);
+    test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, S::npos);
+    test(S("snafbdlghrjkpqtoceim"), "", 0, 0);
+    test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, 0);
+    test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, 1);
+    test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, S::npos);
+    test(S("jlnkraeodhcspfgbqitm"), "", 1, 1);
+    test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, 1);
+    test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 3);
+    test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, S::npos);
+    test(S("hdpkobnsalmcfijregtq"), "", 10, 10);
+    test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 11);
+    test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 13);
+    test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, S::npos);
+    test(S("niptglfbosehkamrdqcj"), "", 19, 19);
+    test(S("copqdhstbingamjfkler"), "djkqc", 19, 19);
+    test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, S::npos);
+    test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, S::npos);
+    test(S("eaintpchlqsbdgrkjofm"), "", 20, S::npos);
+    test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, S::npos);
+    test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, S::npos);
+    test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, S::npos);
+    test(S("liatsqdoegkmfcnbhrpj"), "", 21, S::npos);
+    test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, S::npos);
+    test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, S::npos);
+    test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), "", S::npos);
+    test(S(""), "laenf", S::npos);
+    test(S(""), "pqlnkmbdjo", S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", S::npos);
+    test(S("nhmko"), "", 0);
+    test(S("lahfb"), "irkhs", 0);
+    test(S("gmfhd"), "kantesmpgj", 2);
+    test(S("odaft"), "oknlrstdpiqmjbaghcfe", S::npos);
+    test(S("eolhfgpjqk"), "", 0);
+    test(S("nbatdlmekr"), "bnrpe", 2);
+    test(S("jdmciepkaq"), "jtdaefblso", 2);
+    test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", S::npos);
+    test(S("gprdcokbnjhlsfmtieqa"), "", 0);
+    test(S("qjghlnftcaismkropdeb"), "bjaht", 0);
+    test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 1);
+    test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_first_not_of( "",      0) == SV::npos, "" );
+    static_assert (sv1.find_first_not_of( "irkhs", 0) == SV::npos, "" );
+    static_assert (sv2.find_first_not_of( "",      0) == 0, "" );
+    static_assert (sv2.find_first_not_of( "gfsrt", 0) == 0, "" );
+    static_assert (sv2.find_first_not_of( "lecar", 0) == 1, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_not_of_pointer_size_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_not_of_pointer_size_size.pass.cpp
new file mode 100644
index 0000000..cfb0029
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_not_of_pointer_size_size.pass.cpp
@@ -0,0 +1,392 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type n, typename S::size_type x)
+{
+    assert(s.find_first_not_of(str, pos, n) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0, S::npos);
+    test(S(""), "irkhs", 0, 0, S::npos);
+    test(S(""), "kante", 0, 1, S::npos);
+    test(S(""), "oknlr", 0, 2, S::npos);
+    test(S(""), "pcdro", 0, 4, S::npos);
+    test(S(""), "bnrpe", 0, 5, S::npos);
+    test(S(""), "jtdaefblso", 0, 0, S::npos);
+    test(S(""), "oselktgbca", 0, 1, S::npos);
+    test(S(""), "eqgaplhckj", 0, 5, S::npos);
+    test(S(""), "bjahtcmnlp", 0, 9, S::npos);
+    test(S(""), "hjlcmgpket", 0, 10, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos);
+    test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos);
+    test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos);
+    test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos);
+    test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos);
+    test(S(""), "", 1, 0, S::npos);
+    test(S(""), "lbtqd", 1, 0, S::npos);
+    test(S(""), "tboim", 1, 1, S::npos);
+    test(S(""), "slcer", 1, 2, S::npos);
+    test(S(""), "cbjfs", 1, 4, S::npos);
+    test(S(""), "aqibs", 1, 5, S::npos);
+    test(S(""), "gtfblmqinc", 1, 0, S::npos);
+    test(S(""), "mkqpbtdalg", 1, 1, S::npos);
+    test(S(""), "kphatlimcd", 1, 5, S::npos);
+    test(S(""), "pblasqogic", 1, 9, S::npos);
+    test(S(""), "arosdhcfme", 1, 10, S::npos);
+    test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos);
+    test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos);
+    test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos);
+    test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos);
+    test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos);
+    test(S("eaint"), "", 0, 0, 0);
+    test(S("binja"), "gfsrt", 0, 0, 0);
+    test(S("latkm"), "pfsoc", 0, 1, 0);
+    test(S("lecfr"), "tpflm", 0, 2, 0);
+    test(S("eqkst"), "sgkec", 0, 4, 1);
+    test(S("cdafr"), "romds", 0, 5, 0);
+    test(S("prbhe"), "qhjistlgmr", 0, 0, 0);
+    test(S("lbisk"), "pedfirsglo", 0, 1, 0);
+    test(S("hrlpd"), "aqcoslgrmk", 0, 5, 0);
+    test(S("ehmja"), "dabckmepqj", 0, 9, 1);
+    test(S("mhqgd"), "pqscrjthli", 0, 10, 0);
+    test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, 0);
+    test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, 0);
+    test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, 0);
+    test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, S::npos);
+    test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, S::npos);
+    test(S("clrgb"), "", 1, 0, 1);
+    test(S("tjmek"), "osmia", 1, 0, 1);
+    test(S("bgstp"), "ckonl", 1, 1, 1);
+    test(S("hstrk"), "ilcaj", 1, 2, 1);
+    test(S("kmspj"), "lasiq", 1, 4, 1);
+    test(S("tjboh"), "kfqmr", 1, 5, 1);
+    test(S("ilbcj"), "klnitfaobg", 1, 0, 1);
+    test(S("jkngf"), "gjhmdlqikp", 1, 1, 1);
+    test(S("gfcql"), "skbgtahqej", 1, 5, 1);
+    test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 1);
+    test(S("bthpg"), "bjgfmnlkio", 1, 10, 1);
+    test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, 1);
+    test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, 1);
+    test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, 3);
+    test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, S::npos);
+    test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, S::npos);
+    test(S("ndrhl"), "", 2, 0, 2);
+    test(S("mrecp"), "otkgb", 2, 0, 2);
+    test(S("qlasf"), "cqsjl", 2, 1, 2);
+    test(S("smaqd"), "dpifl", 2, 2, 2);
+    test(S("hjeni"), "oapht", 2, 4, 2);
+    test(S("ocmfj"), "cifts", 2, 5, 2);
+    test(S("hmftq"), "nmsckbgalo", 2, 0, 2);
+    test(S("fklad"), "tpksqhamle", 2, 1, 2);
+    test(S("dirnm"), "tpdrchmkji", 2, 5, 3);
+    test(S("hrgdc"), "ijagfkblst", 2, 9, 3);
+    test(S("ifakg"), "kpocsignjb", 2, 10, 2);
+    test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, 2);
+    test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, 2);
+    test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 2);
+    test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, S::npos);
+    test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, S::npos);
+    test(S("cjgao"), "", 4, 0, 4);
+    test(S("kjplq"), "mabns", 4, 0, 4);
+    test(S("herni"), "bdnrp", 4, 1, 4);
+    test(S("tadrb"), "scidp", 4, 2, 4);
+    test(S("pkfeo"), "agbjl", 4, 4, 4);
+    test(S("hoser"), "jfmpr", 4, 5, S::npos);
+    test(S("kgrsp"), "rbpefghsmj", 4, 0, 4);
+    test(S("pgejb"), "apsfntdoqc", 4, 1, 4);
+    test(S("thlnq"), "ndkjeisgcl", 4, 5, 4);
+    test(S("nbmit"), "rnfpqatdeo", 4, 9, S::npos);
+    test(S("jgmib"), "bntjlqrfik", 4, 10, S::npos);
+    test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, 4);
+    test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, 4);
+    test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, S::npos);
+    test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, S::npos);
+    test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, S::npos);
+    test(S("klopi"), "", 5, 0, S::npos);
+    test(S("dajhn"), "psthd", 5, 0, S::npos);
+    test(S("jbgno"), "rpmjd", 5, 1, S::npos);
+    test(S("hkjae"), "dfsmk", 5, 2, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S("gbhqo"), "skqne", 5, 4, S::npos);
+    test(S("ktdor"), "kipnf", 5, 5, S::npos);
+    test(S("ldprn"), "hmrnqdgifl", 5, 0, S::npos);
+    test(S("egmjk"), "fsmjcdairn", 5, 1, S::npos);
+    test(S("armql"), "pcdgltbrfj", 5, 5, S::npos);
+    test(S("cdhjo"), "aekfctpirg", 5, 9, S::npos);
+    test(S("jcons"), "ledihrsgpf", 5, 10, S::npos);
+    test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, S::npos);
+    test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, S::npos);
+    test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, S::npos);
+    test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, S::npos);
+    test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, S::npos);
+    test(S("gajqn"), "", 6, 0, S::npos);
+    test(S("stedk"), "hrnat", 6, 0, S::npos);
+    test(S("tjkaf"), "gsqdt", 6, 1, S::npos);
+    test(S("dthpe"), "bspkd", 6, 2, S::npos);
+    test(S("klhde"), "ohcmb", 6, 4, S::npos);
+    test(S("bhlki"), "heatr", 6, 5, S::npos);
+    test(S("lqmoh"), "pmblckedfn", 6, 0, S::npos);
+    test(S("mtqin"), "aceqmsrbik", 6, 1, S::npos);
+    test(S("dpqbr"), "lmbtdehjrn", 6, 5, S::npos);
+    test(S("kdhmo"), "teqmcrlgib", 6, 9, S::npos);
+    test(S("jblqp"), "njolbmspac", 6, 10, S::npos);
+    test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, S::npos);
+    test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, S::npos);
+    test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, S::npos);
+    test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, S::npos);
+    test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, S::npos);
+    test(S("jnkrfhotgl"), "", 0, 0, 0);
+    test(S("dltjfngbko"), "rqegt", 0, 0, 0);
+    test(S("bmjlpkiqde"), "dashm", 0, 1, 0);
+    test(S("skrflobnqm"), "jqirk", 0, 2, 0);
+    test(S("jkpldtshrm"), "rckeg", 0, 4, 0);
+    test(S("ghasdbnjqo"), "jscie", 0, 5, 0);
+    test(S("igrkhpbqjt"), "efsphndliq", 0, 0, 0);
+    test(S("ikthdgcamf"), "gdicosleja", 0, 1, 0);
+    test(S("pcofgeniam"), "qcpjibosfl", 0, 5, 2);
+    test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, 4);
+    test(S("itphbqsker"), "dtablcrseo", 0, 10, 0);
+    test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, 0);
+    test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, 0);
+    test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, 0);
+    test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, 1);
+    test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, S::npos);
+    test(S("shbcqnmoar"), "", 1, 0, 1);
+    test(S("bdoshlmfin"), "ontrs", 1, 0, 1);
+    test(S("khfrebnsgq"), "pfkna", 1, 1, 1);
+    test(S("getcrsaoji"), "ekosa", 1, 2, 2);
+    test(S("fjiknedcpq"), "anqhk", 1, 4, 1);
+    test(S("tkejgnafrm"), "jekca", 1, 5, 4);
+    test(S("jnakolqrde"), "ikemsjgacf", 1, 0, 1);
+    test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, 1);
+    test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 3);
+    test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 1);
+    test(S("cigfqkated"), "sqcflrgtim", 1, 10, 5);
+    test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, 1);
+    test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, 1);
+    test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, 5);
+    test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, 5);
+    test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, S::npos);
+    test(S("ectnhskflp"), "", 5, 0, 5);
+    test(S("fgtianblpq"), "pijag", 5, 0, 5);
+    test(S("mfeqklirnh"), "jrckd", 5, 1, 5);
+    test(S("astedncjhk"), "qcloh", 5, 2, 5);
+    test(S("fhlqgcajbr"), "thlmp", 5, 4, 5);
+    test(S("epfhocmdng"), "qidmo", 5, 5, 5);
+    test(S("apcnsibger"), "lnegpsjqrd", 5, 0, 5);
+    test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 6);
+    test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, 5);
+    test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 6);
+    test(S("jbhcfposld"), "trfqgmckbe", 5, 10, 5);
+    test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, 5);
+    test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, 5);
+    test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 6);
+    test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, 8);
+    test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, S::npos);
+    test(S("shoiedtcjb"), "", 9, 0, 9);
+    test(S("ebcinjgads"), "tqbnh", 9, 0, 9);
+    test(S("dqmregkcfl"), "akmle", 9, 1, 9);
+    test(S("ngcrieqajf"), "iqfkm", 9, 2, 9);
+    test(S("qosmilgnjb"), "tqjsr", 9, 4, 9);
+    test(S("ikabsjtdfl"), "jplqg", 9, 5, S::npos);
+    test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, 9);
+    test(S("fdnplotmgh"), "morkglpesn", 9, 1, 9);
+    test(S("fdbicojerm"), "dmicerngat", 9, 5, S::npos);
+    test(S("mbtafndjcq"), "radgeskbtc", 9, 9, 9);
+    test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, 9);
+    test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, 9);
+    test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, 9);
+    test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, 9);
+    test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, S::npos);
+    test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, S::npos);
+    test(S("ncjpmaekbs"), "", 10, 0, S::npos);
+    test(S("hlbosgmrak"), "hpmsd", 10, 0, S::npos);
+    test(S("pqfhsgilen"), "qnpor", 10, 1, S::npos);
+    test(S("gqtjsbdckh"), "otdma", 10, 2, S::npos);
+    test(S("cfkqpjlegi"), "efhjg", 10, 4, S::npos);
+    test(S("beanrfodgj"), "odpte", 10, 5, S::npos);
+    test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, S::npos);
+    test(S("iomkfthagj"), "oaklidrbqg", 10, 1, S::npos);
+}
+
+template <class S>
+void test2()
+{
+    test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, S::npos);
+    test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, S::npos);
+    test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, S::npos);
+    test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, S::npos);
+    test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, S::npos);
+    test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, S::npos);
+    test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, S::npos);
+    test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, S::npos);
+    test(S("cqjohampgd"), "", 11, 0, S::npos);
+    test(S("hobitmpsan"), "aocjb", 11, 0, S::npos);
+    test(S("tjehkpsalm"), "jbrnk", 11, 1, S::npos);
+    test(S("ngfbojitcl"), "tqedg", 11, 2, S::npos);
+    test(S("rcfkdbhgjo"), "nqskp", 11, 4, S::npos);
+    test(S("qghptonrea"), "eaqkl", 11, 5, S::npos);
+    test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, S::npos);
+    test(S("hlmgabenti"), "lsftgajqpm", 11, 1, S::npos);
+    test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, S::npos);
+    test(S("jqedtkornm"), "shkncmiaqj", 11, 9, S::npos);
+    test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, S::npos);
+    test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, S::npos);
+    test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, S::npos);
+    test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, S::npos);
+    test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, S::npos);
+    test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, S::npos);
+    test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, 0);
+    test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, 0);
+    test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, 0);
+    test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, 0);
+    test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, 0);
+    test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, 0);
+    test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, 0);
+    test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, 0);
+    test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, 0);
+    test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, 0);
+    test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, 0);
+    test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, 0);
+    test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, 0);
+    test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, 0);
+    test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, 11);
+    test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, S::npos);
+    test(S("febhmqtjanokscdirpgl"), "", 1, 0, 1);
+    test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, 1);
+    test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, 1);
+    test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 2);
+    test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 2);
+    test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, 1);
+    test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, 1);
+    test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, 1);
+    test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, 1);
+    test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 3);
+    test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 2);
+    test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, 1);
+    test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, 1);
+    test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 2);
+    test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, 13);
+    test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, S::npos);
+    test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, 10);
+    test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, 10);
+    test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, 10);
+    test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, 10);
+    test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 11);
+    test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 10);
+    test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, 10);
+    test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, 10);
+    test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 10);
+    test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 11);
+    test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 10);
+    test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, 10);
+    test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, 10);
+    test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 11);
+    test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, 11);
+    test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, S::npos);
+    test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, 19);
+    test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, 19);
+    test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, 19);
+    test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, 19);
+    test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, 19);
+    test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, S::npos);
+    test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, 19);
+    test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, 19);
+    test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, 19);
+    test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, 19);
+    test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, 19);
+    test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, 19);
+    test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, 19);
+    test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, S::npos);
+    test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, S::npos);
+    test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, S::npos);
+    test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, S::npos);
+    test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, S::npos);
+    test(S("grkpahljcftesdmonqib"), "odife", 20, 1, S::npos);
+    test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, S::npos);
+    test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, S::npos);
+    test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, S::npos);
+    test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, S::npos);
+    test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, S::npos);
+    test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, S::npos);
+    test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, S::npos);
+    test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, S::npos);
+    test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, S::npos);
+}
+
+template <class S>
+void test3()
+{
+    test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, S::npos);
+    test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, S::npos);
+    test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, S::npos);
+    test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, S::npos);
+    test(S("ecgdanriptblhjfqskom"), "", 21, 0, S::npos);
+    test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, S::npos);
+    test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, S::npos);
+    test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, S::npos);
+    test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, S::npos);
+    test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, S::npos);
+    test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, S::npos);
+    test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, S::npos);
+    test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, S::npos);
+    test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, S::npos);
+    test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, S::npos);
+    test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, S::npos);
+    test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, S::npos);
+    test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, S::npos);
+    test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, S::npos);
+    test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    test2<S>();
+    test3<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_first_not_of( "",      0, 0) == SV::npos, "" );
+    static_assert (sv1.find_first_not_of( "irkhs", 0, 5) == SV::npos, "" );
+    static_assert (sv2.find_first_not_of( "",      0, 0) == 0, "" );
+    static_assert (sv2.find_first_not_of( "gfsrt", 0, 5) == 0, "" );
+    static_assert (sv2.find_first_not_of( "lecar", 0, 5) == 1, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_not_of_string_view_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_not_of_string_view_size.pass.cpp
new file mode 100644
index 0000000..7002312
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_not_of_string_view_size.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// size_type find_first_not_of(const basic_string& str, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
+{
+    assert(s.find_first_not_of(str, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type x)
+{
+    assert(s.find_first_not_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), S(""), 0, S::npos);
+    test(S(""), S("laenf"), 0, S::npos);
+    test(S(""), S("pqlnkmbdjo"), 0, S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos);
+    test(S(""), S(""), 1, S::npos);
+    test(S(""), S("bjaht"), 1, S::npos);
+    test(S(""), S("hjlcmgpket"), 1, S::npos);
+    test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos);
+    test(S("fodgq"), S(""), 0, 0);
+    test(S("qanej"), S("dfkap"), 0, 0);
+    test(S("clbao"), S("ihqrfebgad"), 0, 0);
+    test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, S::npos);
+    test(S("srdfq"), S(""), 1, 1);
+    test(S("oemth"), S("ikcrq"), 1, 1);
+    test(S("cdaih"), S("dmajblfhsg"), 1, 3);
+    test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, S::npos);
+    test(S("cshmd"), S(""), 2, 2);
+    test(S("lhcdo"), S("oebqi"), 2, 2);
+    test(S("qnsoh"), S("kojhpmbsfe"), 2, S::npos);
+    test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, S::npos);
+    test(S("fmtsp"), S(""), 4, 4);
+    test(S("khbpm"), S("aobjd"), 4, 4);
+    test(S("pbsji"), S("pcbahntsje"), 4, 4);
+    test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, S::npos);
+    test(S("eqmpa"), S(""), 5, S::npos);
+    test(S("omigs"), S("kocgb"), 5, S::npos);
+    test(S("onmje"), S("fbslrjiqkm"), 5, S::npos);
+    test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, S::npos);
+    test(S("schfa"), S(""), 6, S::npos);
+    test(S("igdsc"), S("qngpd"), 6, S::npos);
+    test(S("brqgo"), S("rodhqklgmb"), 6, S::npos);
+    test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, S::npos);
+    test(S("hcjitbfapl"), S(""), 0, 0);
+    test(S("daiprenocl"), S("ashjd"), 0, 2);
+    test(S("litpcfdghe"), S("mgojkldsqh"), 0, 1);
+    test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, S::npos);
+    test(S("qpghtfbaji"), S(""), 1, 1);
+    test(S("gfshlcmdjr"), S("nadkh"), 1, 1);
+    test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 4);
+    test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, S::npos);
+    test(S("crnklpmegd"), S(""), 5, 5);
+    test(S("jsbtafedoc"), S("prqgn"), 5, 5);
+    test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 6);
+    test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, S::npos);
+    test(S("lmofqdhpki"), S(""), 9, 9);
+    test(S("hnefkqimca"), S("rtjpa"), 9, S::npos);
+    test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, 9);
+    test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, S::npos);
+    test(S("elgofjmbrq"), S(""), 10, S::npos);
+    test(S("mjqdgalkpc"), S("dplqa"), 10, S::npos);
+    test(S("kthqnfcerm"), S("dkacjoptns"), 10, S::npos);
+    test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, S::npos);
+    test(S("eqsgalomhb"), S(""), 11, S::npos);
+    test(S("akiteljmoh"), S("lofbc"), 11, S::npos);
+    test(S("hlbdfreqjo"), S("astoegbfpn"), 11, S::npos);
+    test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, S::npos);
+    test(S("snafbdlghrjkpqtoceim"), S(""), 0, 0);
+    test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, 0);
+    test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, 1);
+    test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, S::npos);
+    test(S("jlnkraeodhcspfgbqitm"), S(""), 1, 1);
+    test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, 1);
+    test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 3);
+    test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, S::npos);
+    test(S("hdpkobnsalmcfijregtq"), S(""), 10, 10);
+    test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 11);
+    test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 13);
+    test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, S::npos);
+    test(S("niptglfbosehkamrdqcj"), S(""), 19, 19);
+    test(S("copqdhstbingamjfkler"), S("djkqc"), 19, 19);
+    test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, S::npos);
+    test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, S::npos);
+    test(S("eaintpchlqsbdgrkjofm"), S(""), 20, S::npos);
+    test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, S::npos);
+    test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, S::npos);
+    test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, S::npos);
+    test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, S::npos);
+    test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, S::npos);
+    test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, S::npos);
+    test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), S(""), S::npos);
+    test(S(""), S("laenf"), S::npos);
+    test(S(""), S("pqlnkmbdjo"), S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), S::npos);
+    test(S("nhmko"), S(""), 0);
+    test(S("lahfb"), S("irkhs"), 0);
+    test(S("gmfhd"), S("kantesmpgj"), 2);
+    test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), S::npos);
+    test(S("eolhfgpjqk"), S(""), 0);
+    test(S("nbatdlmekr"), S("bnrpe"), 2);
+    test(S("jdmciepkaq"), S("jtdaefblso"), 2);
+    test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), S::npos);
+    test(S("gprdcokbnjhlsfmtieqa"), S(""), 0);
+    test(S("qjghlnftcaismkropdeb"), S("bjaht"), 0);
+    test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 1);
+    test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_of_char_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_of_char_size.pass.cpp
new file mode 100644
index 0000000..dde2f2c
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_of_char_size.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// constexpr size_type find_first_of(charT c, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_first_of(c, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type x)
+{
+    assert(s.find_first_of(c) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), 'e', 0, S::npos);
+    test(S(""), 'e', 1, S::npos);
+    test(S("kitcj"), 'e', 0, S::npos);
+    test(S("qkamf"), 'e', 1, S::npos);
+    test(S("nhmko"), 'e', 2, S::npos);
+    test(S("tpsaf"), 'e', 4, S::npos);
+    test(S("lahfb"), 'e', 5, S::npos);
+    test(S("irkhs"), 'e', 6, S::npos);
+    test(S("gmfhdaipsr"), 'e', 0, S::npos);
+    test(S("kantesmpgj"), 'e', 1, 4);
+    test(S("odaftiegpm"), 'e', 5, 6);
+    test(S("oknlrstdpi"), 'e', 9, S::npos);
+    test(S("eolhfgpjqk"), 'e', 10, S::npos);
+    test(S("pcdrofikas"), 'e', 11, S::npos);
+    test(S("nbatdlmekrgcfqsophij"), 'e', 0, 7);
+    test(S("bnrpehidofmqtcksjgla"), 'e', 1, 4);
+    test(S("jdmciepkaqgotsrfnhlb"), 'e', 10, S::npos);
+    test(S("jtdaefblsokrmhpgcnqi"), 'e', 19, S::npos);
+    test(S("hkbgspofltajcnedqmri"), 'e', 20, S::npos);
+    test(S("oselktgbcapndfjihrmq"), 'e', 21, S::npos);
+
+    test(S(""), 'e', S::npos);
+    test(S("csope"), 'e', 4);
+    test(S("gfsmthlkon"), 'e', S::npos);
+    test(S("laenfsbridchgotmkqpj"), 'e', 2);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_first_of( 'e', 0 ) == SV::npos, "" );
+    static_assert (sv1.find_first_of( 'e', 1 ) == SV::npos, "" );
+    static_assert (sv2.find_first_of( 'q', 0 ) == SV::npos, "" );
+    static_assert (sv2.find_first_of( 'e', 1 ) == 4, "" );
+    static_assert (sv2.find_first_of( 'e', 5 ) == SV::npos, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_of_pointer_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_of_pointer_size.pass.cpp
new file mode 100644
index 0000000..e49e82c
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_of_pointer_size.pass.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_first_of(str, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type x)
+{
+    assert(s.find_first_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, S::npos);
+    test(S(""), "laenf", 0, S::npos);
+    test(S(""), "pqlnkmbdjo", 0, S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", 0, S::npos);
+    test(S(""), "", 1, S::npos);
+    test(S(""), "bjaht", 1, S::npos);
+    test(S(""), "hjlcmgpket", 1, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos);
+    test(S("fodgq"), "", 0, S::npos);
+    test(S("qanej"), "dfkap", 0, 1);
+    test(S("clbao"), "ihqrfebgad", 0, 2);
+    test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, 0);
+    test(S("srdfq"), "", 1, S::npos);
+    test(S("oemth"), "ikcrq", 1, S::npos);
+    test(S("cdaih"), "dmajblfhsg", 1, 1);
+    test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, 1);
+    test(S("cshmd"), "", 2, S::npos);
+    test(S("lhcdo"), "oebqi", 2, 4);
+    test(S("qnsoh"), "kojhpmbsfe", 2, 2);
+    test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, 2);
+    test(S("fmtsp"), "", 4, S::npos);
+    test(S("khbpm"), "aobjd", 4, S::npos);
+    test(S("pbsji"), "pcbahntsje", 4, S::npos);
+    test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, 4);
+    test(S("eqmpa"), "", 5, S::npos);
+    test(S("omigs"), "kocgb", 5, S::npos);
+    test(S("onmje"), "fbslrjiqkm", 5, S::npos);
+    test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, S::npos);
+    test(S("schfa"), "", 6, S::npos);
+    test(S("igdsc"), "qngpd", 6, S::npos);
+    test(S("brqgo"), "rodhqklgmb", 6, S::npos);
+    test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, S::npos);
+    test(S("hcjitbfapl"), "", 0, S::npos);
+    test(S("daiprenocl"), "ashjd", 0, 0);
+    test(S("litpcfdghe"), "mgojkldsqh", 0, 0);
+    test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, 0);
+    test(S("qpghtfbaji"), "", 1, S::npos);
+    test(S("gfshlcmdjr"), "nadkh", 1, 3);
+    test(S("nkodajteqp"), "ofdrqmkebl", 1, 1);
+    test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, 1);
+    test(S("crnklpmegd"), "", 5, S::npos);
+    test(S("jsbtafedoc"), "prqgn", 5, S::npos);
+    test(S("qnmodrtkeb"), "pejafmnokr", 5, 5);
+    test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, 5);
+    test(S("lmofqdhpki"), "", 9, S::npos);
+    test(S("hnefkqimca"), "rtjpa", 9, 9);
+    test(S("drtasbgmfp"), "ktsrmnqagd", 9, S::npos);
+    test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, 9);
+    test(S("elgofjmbrq"), "", 10, S::npos);
+    test(S("mjqdgalkpc"), "dplqa", 10, S::npos);
+    test(S("kthqnfcerm"), "dkacjoptns", 10, S::npos);
+    test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, S::npos);
+    test(S("eqsgalomhb"), "", 11, S::npos);
+    test(S("akiteljmoh"), "lofbc", 11, S::npos);
+    test(S("hlbdfreqjo"), "astoegbfpn", 11, S::npos);
+    test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, S::npos);
+    test(S("snafbdlghrjkpqtoceim"), "", 0, S::npos);
+    test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, 3);
+    test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, 0);
+    test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, 0);
+    test(S("jlnkraeodhcspfgbqitm"), "", 1, S::npos);
+    test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, 3);
+    test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 1);
+    test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, 1);
+    test(S("hdpkobnsalmcfijregtq"), "", 10, S::npos);
+    test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 10);
+    test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 10);
+    test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, 10);
+    test(S("niptglfbosehkamrdqcj"), "", 19, S::npos);
+    test(S("copqdhstbingamjfkler"), "djkqc", 19, S::npos);
+    test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, 19);
+    test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, 19);
+    test(S("eaintpchlqsbdgrkjofm"), "", 20, S::npos);
+    test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, S::npos);
+    test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, S::npos);
+    test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, S::npos);
+    test(S("liatsqdoegkmfcnbhrpj"), "", 21, S::npos);
+    test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, S::npos);
+    test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, S::npos);
+    test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), "", S::npos);
+    test(S(""), "laenf", S::npos);
+    test(S(""), "pqlnkmbdjo", S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", S::npos);
+    test(S("nhmko"), "", S::npos);
+    test(S("lahfb"), "irkhs", 2);
+    test(S("gmfhd"), "kantesmpgj", 0);
+    test(S("odaft"), "oknlrstdpiqmjbaghcfe", 0);
+    test(S("eolhfgpjqk"), "", S::npos);
+    test(S("nbatdlmekr"), "bnrpe", 0);
+    test(S("jdmciepkaq"), "jtdaefblso", 0);
+    test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", 0);
+    test(S("gprdcokbnjhlsfmtieqa"), "", S::npos);
+    test(S("qjghlnftcaismkropdeb"), "bjaht", 1);
+    test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 0);
+    test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", 0);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_first_of( "",      0) == SV::npos, "" );
+    static_assert (sv1.find_first_of( "irkhs", 0) == SV::npos, "" );
+    static_assert (sv2.find_first_of( "",      0) == SV::npos, "" );
+    static_assert (sv2.find_first_of( "gfsrt", 0) == SV::npos, "" );
+    static_assert (sv2.find_first_of( "lecar", 0) == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_of_pointer_size_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_of_pointer_size_size.pass.cpp
new file mode 100644
index 0000000..1dc8d85
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_of_pointer_size_size.pass.cpp
@@ -0,0 +1,392 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type n, typename S::size_type x)
+{
+    assert(s.find_first_of(str, pos, n) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0, S::npos);
+    test(S(""), "irkhs", 0, 0, S::npos);
+    test(S(""), "kante", 0, 1, S::npos);
+    test(S(""), "oknlr", 0, 2, S::npos);
+    test(S(""), "pcdro", 0, 4, S::npos);
+    test(S(""), "bnrpe", 0, 5, S::npos);
+    test(S(""), "jtdaefblso", 0, 0, S::npos);
+    test(S(""), "oselktgbca", 0, 1, S::npos);
+    test(S(""), "eqgaplhckj", 0, 5, S::npos);
+    test(S(""), "bjahtcmnlp", 0, 9, S::npos);
+    test(S(""), "hjlcmgpket", 0, 10, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos);
+    test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos);
+    test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos);
+    test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos);
+    test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos);
+    test(S(""), "", 1, 0, S::npos);
+    test(S(""), "lbtqd", 1, 0, S::npos);
+    test(S(""), "tboim", 1, 1, S::npos);
+    test(S(""), "slcer", 1, 2, S::npos);
+    test(S(""), "cbjfs", 1, 4, S::npos);
+    test(S(""), "aqibs", 1, 5, S::npos);
+    test(S(""), "gtfblmqinc", 1, 0, S::npos);
+    test(S(""), "mkqpbtdalg", 1, 1, S::npos);
+    test(S(""), "kphatlimcd", 1, 5, S::npos);
+    test(S(""), "pblasqogic", 1, 9, S::npos);
+    test(S(""), "arosdhcfme", 1, 10, S::npos);
+    test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos);
+    test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos);
+    test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos);
+    test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos);
+    test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos);
+    test(S("eaint"), "", 0, 0, S::npos);
+    test(S("binja"), "gfsrt", 0, 0, S::npos);
+    test(S("latkm"), "pfsoc", 0, 1, S::npos);
+    test(S("lecfr"), "tpflm", 0, 2, S::npos);
+    test(S("eqkst"), "sgkec", 0, 4, 0);
+    test(S("cdafr"), "romds", 0, 5, 1);
+    test(S("prbhe"), "qhjistlgmr", 0, 0, S::npos);
+    test(S("lbisk"), "pedfirsglo", 0, 1, S::npos);
+    test(S("hrlpd"), "aqcoslgrmk", 0, 5, S::npos);
+    test(S("ehmja"), "dabckmepqj", 0, 9, 0);
+    test(S("mhqgd"), "pqscrjthli", 0, 10, 1);
+    test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, S::npos);
+    test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, S::npos);
+    test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, S::npos);
+    test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, 0);
+    test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, 0);
+    test(S("clrgb"), "", 1, 0, S::npos);
+    test(S("tjmek"), "osmia", 1, 0, S::npos);
+    test(S("bgstp"), "ckonl", 1, 1, S::npos);
+    test(S("hstrk"), "ilcaj", 1, 2, S::npos);
+    test(S("kmspj"), "lasiq", 1, 4, 2);
+    test(S("tjboh"), "kfqmr", 1, 5, S::npos);
+    test(S("ilbcj"), "klnitfaobg", 1, 0, S::npos);
+    test(S("jkngf"), "gjhmdlqikp", 1, 1, 3);
+    test(S("gfcql"), "skbgtahqej", 1, 5, S::npos);
+    test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 2);
+    test(S("bthpg"), "bjgfmnlkio", 1, 10, 4);
+    test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, S::npos);
+    test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, S::npos);
+    test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, 1);
+    test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, 1);
+    test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, 1);
+    test(S("ndrhl"), "", 2, 0, S::npos);
+    test(S("mrecp"), "otkgb", 2, 0, S::npos);
+    test(S("qlasf"), "cqsjl", 2, 1, S::npos);
+    test(S("smaqd"), "dpifl", 2, 2, 4);
+    test(S("hjeni"), "oapht", 2, 4, S::npos);
+    test(S("ocmfj"), "cifts", 2, 5, 3);
+    test(S("hmftq"), "nmsckbgalo", 2, 0, S::npos);
+    test(S("fklad"), "tpksqhamle", 2, 1, S::npos);
+    test(S("dirnm"), "tpdrchmkji", 2, 5, 2);
+    test(S("hrgdc"), "ijagfkblst", 2, 9, 2);
+    test(S("ifakg"), "kpocsignjb", 2, 10, 3);
+    test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, S::npos);
+    test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, S::npos);
+    test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 3);
+    test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, 2);
+    test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, 2);
+    test(S("cjgao"), "", 4, 0, S::npos);
+    test(S("kjplq"), "mabns", 4, 0, S::npos);
+    test(S("herni"), "bdnrp", 4, 1, S::npos);
+    test(S("tadrb"), "scidp", 4, 2, S::npos);
+    test(S("pkfeo"), "agbjl", 4, 4, S::npos);
+    test(S("hoser"), "jfmpr", 4, 5, 4);
+    test(S("kgrsp"), "rbpefghsmj", 4, 0, S::npos);
+    test(S("pgejb"), "apsfntdoqc", 4, 1, S::npos);
+    test(S("thlnq"), "ndkjeisgcl", 4, 5, S::npos);
+    test(S("nbmit"), "rnfpqatdeo", 4, 9, 4);
+    test(S("jgmib"), "bntjlqrfik", 4, 10, 4);
+    test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, S::npos);
+    test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, S::npos);
+    test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, 4);
+    test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, 4);
+    test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, 4);
+    test(S("klopi"), "", 5, 0, S::npos);
+    test(S("dajhn"), "psthd", 5, 0, S::npos);
+    test(S("jbgno"), "rpmjd", 5, 1, S::npos);
+    test(S("hkjae"), "dfsmk", 5, 2, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S("gbhqo"), "skqne", 5, 4, S::npos);
+    test(S("ktdor"), "kipnf", 5, 5, S::npos);
+    test(S("ldprn"), "hmrnqdgifl", 5, 0, S::npos);
+    test(S("egmjk"), "fsmjcdairn", 5, 1, S::npos);
+    test(S("armql"), "pcdgltbrfj", 5, 5, S::npos);
+    test(S("cdhjo"), "aekfctpirg", 5, 9, S::npos);
+    test(S("jcons"), "ledihrsgpf", 5, 10, S::npos);
+    test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, S::npos);
+    test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, S::npos);
+    test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, S::npos);
+    test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, S::npos);
+    test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, S::npos);
+    test(S("gajqn"), "", 6, 0, S::npos);
+    test(S("stedk"), "hrnat", 6, 0, S::npos);
+    test(S("tjkaf"), "gsqdt", 6, 1, S::npos);
+    test(S("dthpe"), "bspkd", 6, 2, S::npos);
+    test(S("klhde"), "ohcmb", 6, 4, S::npos);
+    test(S("bhlki"), "heatr", 6, 5, S::npos);
+    test(S("lqmoh"), "pmblckedfn", 6, 0, S::npos);
+    test(S("mtqin"), "aceqmsrbik", 6, 1, S::npos);
+    test(S("dpqbr"), "lmbtdehjrn", 6, 5, S::npos);
+    test(S("kdhmo"), "teqmcrlgib", 6, 9, S::npos);
+    test(S("jblqp"), "njolbmspac", 6, 10, S::npos);
+    test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, S::npos);
+    test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, S::npos);
+    test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, S::npos);
+    test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, S::npos);
+    test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, S::npos);
+    test(S("jnkrfhotgl"), "", 0, 0, S::npos);
+    test(S("dltjfngbko"), "rqegt", 0, 0, S::npos);
+    test(S("bmjlpkiqde"), "dashm", 0, 1, 8);
+    test(S("skrflobnqm"), "jqirk", 0, 2, 8);
+    test(S("jkpldtshrm"), "rckeg", 0, 4, 1);
+    test(S("ghasdbnjqo"), "jscie", 0, 5, 3);
+    test(S("igrkhpbqjt"), "efsphndliq", 0, 0, S::npos);
+    test(S("ikthdgcamf"), "gdicosleja", 0, 1, 5);
+    test(S("pcofgeniam"), "qcpjibosfl", 0, 5, 0);
+    test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, 0);
+    test(S("itphbqsker"), "dtablcrseo", 0, 10, 1);
+    test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, S::npos);
+    test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, S::npos);
+    test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, 4);
+    test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, 0);
+    test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, 0);
+    test(S("shbcqnmoar"), "", 1, 0, S::npos);
+    test(S("bdoshlmfin"), "ontrs", 1, 0, S::npos);
+    test(S("khfrebnsgq"), "pfkna", 1, 1, S::npos);
+    test(S("getcrsaoji"), "ekosa", 1, 2, 1);
+    test(S("fjiknedcpq"), "anqhk", 1, 4, 4);
+    test(S("tkejgnafrm"), "jekca", 1, 5, 1);
+    test(S("jnakolqrde"), "ikemsjgacf", 1, 0, S::npos);
+    test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, S::npos);
+    test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 1);
+    test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 4);
+    test(S("cigfqkated"), "sqcflrgtim", 1, 10, 1);
+    test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, S::npos);
+    test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, S::npos);
+    test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, 1);
+    test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, 1);
+    test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, 1);
+    test(S("ectnhskflp"), "", 5, 0, S::npos);
+    test(S("fgtianblpq"), "pijag", 5, 0, S::npos);
+    test(S("mfeqklirnh"), "jrckd", 5, 1, S::npos);
+    test(S("astedncjhk"), "qcloh", 5, 2, 6);
+    test(S("fhlqgcajbr"), "thlmp", 5, 4, S::npos);
+    test(S("epfhocmdng"), "qidmo", 5, 5, 6);
+    test(S("apcnsibger"), "lnegpsjqrd", 5, 0, S::npos);
+    test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 5);
+    test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, 7);
+    test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 5);
+    test(S("jbhcfposld"), "trfqgmckbe", 5, 10, S::npos);
+    test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, S::npos);
+    test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, S::npos);
+    test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 5);
+    test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, 5);
+    test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, 5);
+    test(S("shoiedtcjb"), "", 9, 0, S::npos);
+    test(S("ebcinjgads"), "tqbnh", 9, 0, S::npos);
+    test(S("dqmregkcfl"), "akmle", 9, 1, S::npos);
+    test(S("ngcrieqajf"), "iqfkm", 9, 2, S::npos);
+    test(S("qosmilgnjb"), "tqjsr", 9, 4, S::npos);
+    test(S("ikabsjtdfl"), "jplqg", 9, 5, 9);
+    test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, S::npos);
+    test(S("fdnplotmgh"), "morkglpesn", 9, 1, S::npos);
+    test(S("fdbicojerm"), "dmicerngat", 9, 5, 9);
+    test(S("mbtafndjcq"), "radgeskbtc", 9, 9, S::npos);
+    test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, S::npos);
+    test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, S::npos);
+    test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, S::npos);
+    test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, S::npos);
+    test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, 9);
+    test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, 9);
+    test(S("ncjpmaekbs"), "", 10, 0, S::npos);
+    test(S("hlbosgmrak"), "hpmsd", 10, 0, S::npos);
+    test(S("pqfhsgilen"), "qnpor", 10, 1, S::npos);
+    test(S("gqtjsbdckh"), "otdma", 10, 2, S::npos);
+    test(S("cfkqpjlegi"), "efhjg", 10, 4, S::npos);
+    test(S("beanrfodgj"), "odpte", 10, 5, S::npos);
+    test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, S::npos);
+    test(S("iomkfthagj"), "oaklidrbqg", 10, 1, S::npos);
+}
+
+template <class S>
+void test2()
+{
+    test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, S::npos);
+    test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, S::npos);
+    test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, S::npos);
+    test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, S::npos);
+    test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, S::npos);
+    test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, S::npos);
+    test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, S::npos);
+    test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, S::npos);
+    test(S("cqjohampgd"), "", 11, 0, S::npos);
+    test(S("hobitmpsan"), "aocjb", 11, 0, S::npos);
+    test(S("tjehkpsalm"), "jbrnk", 11, 1, S::npos);
+    test(S("ngfbojitcl"), "tqedg", 11, 2, S::npos);
+    test(S("rcfkdbhgjo"), "nqskp", 11, 4, S::npos);
+    test(S("qghptonrea"), "eaqkl", 11, 5, S::npos);
+    test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, S::npos);
+    test(S("hlmgabenti"), "lsftgajqpm", 11, 1, S::npos);
+    test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, S::npos);
+    test(S("jqedtkornm"), "shkncmiaqj", 11, 9, S::npos);
+    test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, S::npos);
+    test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, S::npos);
+    test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, S::npos);
+    test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, S::npos);
+    test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, S::npos);
+    test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, S::npos);
+    test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, S::npos);
+    test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, S::npos);
+    test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, 4);
+    test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, 3);
+    test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, 3);
+    test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, 3);
+    test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, S::npos);
+    test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, 19);
+    test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, 2);
+    test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, 2);
+    test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, 2);
+    test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, S::npos);
+    test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, 16);
+    test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, 1);
+    test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, 0);
+    test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, 0);
+    test(S("febhmqtjanokscdirpgl"), "", 1, 0, S::npos);
+    test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, S::npos);
+    test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, 6);
+    test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 1);
+    test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 1);
+    test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, 6);
+    test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, S::npos);
+    test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, 19);
+    test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, 4);
+    test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 1);
+    test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 1);
+    test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, S::npos);
+    test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, 7);
+    test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 1);
+    test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, 1);
+    test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, 1);
+    test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, S::npos);
+    test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, S::npos);
+    test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, 12);
+    test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, S::npos);
+    test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 10);
+    test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 15);
+    test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, S::npos);
+    test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, S::npos);
+    test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 11);
+    test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 10);
+    test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 11);
+    test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, S::npos);
+    test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, 18);
+    test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 10);
+    test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, 10);
+    test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, 10);
+    test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, S::npos);
+    test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, S::npos);
+    test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, S::npos);
+    test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, S::npos);
+    test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, S::npos);
+    test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, 19);
+    test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, S::npos);
+    test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, S::npos);
+    test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, S::npos);
+    test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, S::npos);
+    test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, S::npos);
+    test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, S::npos);
+    test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, S::npos);
+    test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, 19);
+    test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, 19);
+    test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, 19);
+    test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, S::npos);
+    test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, S::npos);
+    test(S("grkpahljcftesdmonqib"), "odife", 20, 1, S::npos);
+    test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, S::npos);
+    test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, S::npos);
+    test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, S::npos);
+    test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, S::npos);
+    test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, S::npos);
+    test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, S::npos);
+    test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, S::npos);
+    test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, S::npos);
+    test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, S::npos);
+}
+
+template <class S>
+void test3()
+{
+    test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, S::npos);
+    test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, S::npos);
+    test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, S::npos);
+    test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, S::npos);
+    test(S("ecgdanriptblhjfqskom"), "", 21, 0, S::npos);
+    test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, S::npos);
+    test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, S::npos);
+    test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, S::npos);
+    test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, S::npos);
+    test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, S::npos);
+    test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, S::npos);
+    test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, S::npos);
+    test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, S::npos);
+    test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, S::npos);
+    test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, S::npos);
+    test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, S::npos);
+    test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, S::npos);
+    test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, S::npos);
+    test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, S::npos);
+    test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    test2<S>();
+    test3<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_first_of( "",      0, 0) == SV::npos, "" );
+    static_assert (sv1.find_first_of( "irkhs", 0, 5) == SV::npos, "" );
+    static_assert (sv2.find_first_of( "",      0, 0) == SV::npos, "" );
+    static_assert (sv2.find_first_of( "gfsrt", 0, 5) == SV::npos, "" );
+    static_assert (sv2.find_first_of( "lecar", 0, 5) == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_first_of_string_view_size.pass.cpp b/test/experimental/string.view/string.view.find/find_first_of_string_view_size.pass.cpp
new file mode 100644
index 0000000..fddd471
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_first_of_string_view_size.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// size_type find_first_of(const basic_string_view& str, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
+{
+    assert(s.find_first_of(str, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type x)
+{
+    assert(s.find_first_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), S(""), 0, S::npos);
+    test(S(""), S("laenf"), 0, S::npos);
+    test(S(""), S("pqlnkmbdjo"), 0, S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos);
+    test(S(""), S(""), 1, S::npos);
+    test(S(""), S("bjaht"), 1, S::npos);
+    test(S(""), S("hjlcmgpket"), 1, S::npos);
+    test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos);
+    test(S("fodgq"), S(""), 0, S::npos);
+    test(S("qanej"), S("dfkap"), 0, 1);
+    test(S("clbao"), S("ihqrfebgad"), 0, 2);
+    test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, 0);
+    test(S("srdfq"), S(""), 1, S::npos);
+    test(S("oemth"), S("ikcrq"), 1, S::npos);
+    test(S("cdaih"), S("dmajblfhsg"), 1, 1);
+    test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, 1);
+    test(S("cshmd"), S(""), 2, S::npos);
+    test(S("lhcdo"), S("oebqi"), 2, 4);
+    test(S("qnsoh"), S("kojhpmbsfe"), 2, 2);
+    test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, 2);
+    test(S("fmtsp"), S(""), 4, S::npos);
+    test(S("khbpm"), S("aobjd"), 4, S::npos);
+    test(S("pbsji"), S("pcbahntsje"), 4, S::npos);
+    test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, 4);
+    test(S("eqmpa"), S(""), 5, S::npos);
+    test(S("omigs"), S("kocgb"), 5, S::npos);
+    test(S("onmje"), S("fbslrjiqkm"), 5, S::npos);
+    test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, S::npos);
+    test(S("schfa"), S(""), 6, S::npos);
+    test(S("igdsc"), S("qngpd"), 6, S::npos);
+    test(S("brqgo"), S("rodhqklgmb"), 6, S::npos);
+    test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, S::npos);
+    test(S("hcjitbfapl"), S(""), 0, S::npos);
+    test(S("daiprenocl"), S("ashjd"), 0, 0);
+    test(S("litpcfdghe"), S("mgojkldsqh"), 0, 0);
+    test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, 0);
+    test(S("qpghtfbaji"), S(""), 1, S::npos);
+    test(S("gfshlcmdjr"), S("nadkh"), 1, 3);
+    test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 1);
+    test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, 1);
+    test(S("crnklpmegd"), S(""), 5, S::npos);
+    test(S("jsbtafedoc"), S("prqgn"), 5, S::npos);
+    test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 5);
+    test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, 5);
+    test(S("lmofqdhpki"), S(""), 9, S::npos);
+    test(S("hnefkqimca"), S("rtjpa"), 9, 9);
+    test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, S::npos);
+    test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, 9);
+    test(S("elgofjmbrq"), S(""), 10, S::npos);
+    test(S("mjqdgalkpc"), S("dplqa"), 10, S::npos);
+    test(S("kthqnfcerm"), S("dkacjoptns"), 10, S::npos);
+    test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, S::npos);
+    test(S("eqsgalomhb"), S(""), 11, S::npos);
+    test(S("akiteljmoh"), S("lofbc"), 11, S::npos);
+    test(S("hlbdfreqjo"), S("astoegbfpn"), 11, S::npos);
+    test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, S::npos);
+    test(S("snafbdlghrjkpqtoceim"), S(""), 0, S::npos);
+    test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, 3);
+    test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, 0);
+    test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, 0);
+    test(S("jlnkraeodhcspfgbqitm"), S(""), 1, S::npos);
+    test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, 3);
+    test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 1);
+    test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, 1);
+    test(S("hdpkobnsalmcfijregtq"), S(""), 10, S::npos);
+    test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 10);
+    test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 10);
+    test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, 10);
+    test(S("niptglfbosehkamrdqcj"), S(""), 19, S::npos);
+    test(S("copqdhstbingamjfkler"), S("djkqc"), 19, S::npos);
+    test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, 19);
+    test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, 19);
+    test(S("eaintpchlqsbdgrkjofm"), S(""), 20, S::npos);
+    test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, S::npos);
+    test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, S::npos);
+    test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, S::npos);
+    test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, S::npos);
+    test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, S::npos);
+    test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, S::npos);
+    test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), S(""), S::npos);
+    test(S(""), S("laenf"), S::npos);
+    test(S(""), S("pqlnkmbdjo"), S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), S::npos);
+    test(S("nhmko"), S(""), S::npos);
+    test(S("lahfb"), S("irkhs"), 2);
+    test(S("gmfhd"), S("kantesmpgj"), 0);
+    test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), 0);
+    test(S("eolhfgpjqk"), S(""), S::npos);
+    test(S("nbatdlmekr"), S("bnrpe"), 0);
+    test(S("jdmciepkaq"), S("jtdaefblso"), 0);
+    test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), 0);
+    test(S("gprdcokbnjhlsfmtieqa"), S(""), S::npos);
+    test(S("qjghlnftcaismkropdeb"), S("bjaht"), 1);
+    test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 0);
+    test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), 0);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_not_of_char_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_not_of_char_size.pass.cpp
new file mode 100644
index 0000000..ed1a35e
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_not_of_char_size.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// const size_type find_last_not_of(charT c, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_last_not_of(c, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type x)
+{
+    assert(s.find_last_not_of(c) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), 'i', 0, S::npos);
+    test(S(""), 'i', 1, S::npos);
+    test(S("kitcj"), 'i', 0, 0);
+    test(S("qkamf"), 'i', 1, 1);
+    test(S("nhmko"), 'i', 2, 2);
+    test(S("tpsaf"), 'i', 4, 4);
+    test(S("lahfb"), 'i', 5, 4);
+    test(S("irkhs"), 'i', 6, 4);
+    test(S("gmfhdaipsr"), 'i', 0, 0);
+    test(S("kantesmpgj"), 'i', 1, 1);
+    test(S("odaftiegpm"), 'i', 5, 4);
+    test(S("oknlrstdpi"), 'i', 9, 8);
+    test(S("eolhfgpjqk"), 'i', 10, 9);
+    test(S("pcdrofikas"), 'i', 11, 9);
+    test(S("nbatdlmekrgcfqsophij"), 'i', 0, 0);
+    test(S("bnrpehidofmqtcksjgla"), 'i', 1, 1);
+    test(S("jdmciepkaqgotsrfnhlb"), 'i', 10, 10);
+    test(S("jtdaefblsokrmhpgcnqi"), 'i', 19, 18);
+    test(S("hkbgspofltajcnedqmri"), 'i', 20, 18);
+    test(S("oselktgbcapndfjihrmq"), 'i', 21, 19);
+
+    test(S(""), 'i', S::npos);
+    test(S("csope"), 'i', 4);
+    test(S("gfsmthlkon"), 'i', 9);
+    test(S("laenfsbridchgotmkqpj"), 'i', 19);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_last_not_of( 'i', 0 ) == SV::npos, "" );
+    static_assert (sv1.find_last_not_of( 'i', 1 ) == SV::npos, "" );
+    static_assert (sv2.find_last_not_of( 'a', 0 ) == SV::npos, "" );
+    static_assert (sv2.find_last_not_of( 'a', 1 ) == 1, "" );
+    static_assert (sv2.find_last_not_of( 'e', 5 ) == 3, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_not_of_pointer_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_not_of_pointer_size.pass.cpp
new file mode 100644
index 0000000..e07c4f3
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_not_of_pointer_size.pass.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_last_not_of(str, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type x)
+{
+    assert(s.find_last_not_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, S::npos);
+    test(S(""), "laenf", 0, S::npos);
+    test(S(""), "pqlnkmbdjo", 0, S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", 0, S::npos);
+    test(S(""), "", 1, S::npos);
+    test(S(""), "bjaht", 1, S::npos);
+    test(S(""), "hjlcmgpket", 1, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos);
+    test(S("fodgq"), "", 0, 0);
+    test(S("qanej"), "dfkap", 0, 0);
+    test(S("clbao"), "ihqrfebgad", 0, 0);
+    test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, S::npos);
+    test(S("srdfq"), "", 1, 1);
+    test(S("oemth"), "ikcrq", 1, 1);
+    test(S("cdaih"), "dmajblfhsg", 1, 0);
+    test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, S::npos);
+    test(S("cshmd"), "", 2, 2);
+    test(S("lhcdo"), "oebqi", 2, 2);
+    test(S("qnsoh"), "kojhpmbsfe", 2, 1);
+    test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, S::npos);
+    test(S("fmtsp"), "", 4, 4);
+    test(S("khbpm"), "aobjd", 4, 4);
+    test(S("pbsji"), "pcbahntsje", 4, 4);
+    test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, S::npos);
+    test(S("eqmpa"), "", 5, 4);
+    test(S("omigs"), "kocgb", 5, 4);
+    test(S("onmje"), "fbslrjiqkm", 5, 4);
+    test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, S::npos);
+    test(S("schfa"), "", 6, 4);
+    test(S("igdsc"), "qngpd", 6, 4);
+    test(S("brqgo"), "rodhqklgmb", 6, S::npos);
+    test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, S::npos);
+    test(S("hcjitbfapl"), "", 0, 0);
+    test(S("daiprenocl"), "ashjd", 0, S::npos);
+    test(S("litpcfdghe"), "mgojkldsqh", 0, S::npos);
+    test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, S::npos);
+    test(S("qpghtfbaji"), "", 1, 1);
+    test(S("gfshlcmdjr"), "nadkh", 1, 1);
+    test(S("nkodajteqp"), "ofdrqmkebl", 1, 0);
+    test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, S::npos);
+    test(S("crnklpmegd"), "", 5, 5);
+    test(S("jsbtafedoc"), "prqgn", 5, 5);
+    test(S("qnmodrtkeb"), "pejafmnokr", 5, 4);
+    test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, S::npos);
+    test(S("lmofqdhpki"), "", 9, 9);
+    test(S("hnefkqimca"), "rtjpa", 9, 8);
+    test(S("drtasbgmfp"), "ktsrmnqagd", 9, 9);
+    test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, S::npos);
+    test(S("elgofjmbrq"), "", 10, 9);
+    test(S("mjqdgalkpc"), "dplqa", 10, 9);
+    test(S("kthqnfcerm"), "dkacjoptns", 10, 9);
+    test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, S::npos);
+    test(S("eqsgalomhb"), "", 11, 9);
+    test(S("akiteljmoh"), "lofbc", 11, 9);
+    test(S("hlbdfreqjo"), "astoegbfpn", 11, 8);
+    test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, S::npos);
+    test(S("snafbdlghrjkpqtoceim"), "", 0, 0);
+    test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, 0);
+    test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, S::npos);
+    test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, S::npos);
+    test(S("jlnkraeodhcspfgbqitm"), "", 1, 1);
+    test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, 1);
+    test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 0);
+    test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, S::npos);
+    test(S("hdpkobnsalmcfijregtq"), "", 10, 10);
+    test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 9);
+    test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 9);
+    test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, S::npos);
+    test(S("niptglfbosehkamrdqcj"), "", 19, 19);
+    test(S("copqdhstbingamjfkler"), "djkqc", 19, 19);
+    test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, 16);
+    test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, S::npos);
+    test(S("eaintpchlqsbdgrkjofm"), "", 20, 19);
+    test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, 18);
+    test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, 19);
+    test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, S::npos);
+    test(S("liatsqdoegkmfcnbhrpj"), "", 21, 19);
+    test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, 19);
+    test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, 19);
+    test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), "", S::npos);
+    test(S(""), "laenf", S::npos);
+    test(S(""), "pqlnkmbdjo", S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", S::npos);
+    test(S("nhmko"), "", 4);
+    test(S("lahfb"), "irkhs", 4);
+    test(S("gmfhd"), "kantesmpgj", 4);
+    test(S("odaft"), "oknlrstdpiqmjbaghcfe", S::npos);
+    test(S("eolhfgpjqk"), "", 9);
+    test(S("nbatdlmekr"), "bnrpe", 8);
+    test(S("jdmciepkaq"), "jtdaefblso", 9);
+    test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", S::npos);
+    test(S("gprdcokbnjhlsfmtieqa"), "", 19);
+    test(S("qjghlnftcaismkropdeb"), "bjaht", 18);
+    test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 17);
+    test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_last_not_of( "",      0) == SV::npos, "" );
+    static_assert (sv1.find_last_not_of( "irkhs", 5) == SV::npos, "" );
+    static_assert (sv2.find_last_not_of( "",      0) == 0, "" );
+    static_assert (sv2.find_last_not_of( "gfsrt", 5) == 4, "" );
+    static_assert (sv2.find_last_not_of( "lecar", 5) == 3, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_not_of_pointer_size_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_not_of_pointer_size_size.pass.cpp
new file mode 100644
index 0000000..3ddf033
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_not_of_pointer_size_size.pass.cpp
@@ -0,0 +1,392 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type n, typename S::size_type x)
+{
+    assert(s.find_last_not_of(str, pos, n) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0, S::npos);
+    test(S(""), "irkhs", 0, 0, S::npos);
+    test(S(""), "kante", 0, 1, S::npos);
+    test(S(""), "oknlr", 0, 2, S::npos);
+    test(S(""), "pcdro", 0, 4, S::npos);
+    test(S(""), "bnrpe", 0, 5, S::npos);
+    test(S(""), "jtdaefblso", 0, 0, S::npos);
+    test(S(""), "oselktgbca", 0, 1, S::npos);
+    test(S(""), "eqgaplhckj", 0, 5, S::npos);
+    test(S(""), "bjahtcmnlp", 0, 9, S::npos);
+    test(S(""), "hjlcmgpket", 0, 10, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos);
+    test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos);
+    test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos);
+    test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos);
+    test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos);
+    test(S(""), "", 1, 0, S::npos);
+    test(S(""), "lbtqd", 1, 0, S::npos);
+    test(S(""), "tboim", 1, 1, S::npos);
+    test(S(""), "slcer", 1, 2, S::npos);
+    test(S(""), "cbjfs", 1, 4, S::npos);
+    test(S(""), "aqibs", 1, 5, S::npos);
+    test(S(""), "gtfblmqinc", 1, 0, S::npos);
+    test(S(""), "mkqpbtdalg", 1, 1, S::npos);
+    test(S(""), "kphatlimcd", 1, 5, S::npos);
+    test(S(""), "pblasqogic", 1, 9, S::npos);
+    test(S(""), "arosdhcfme", 1, 10, S::npos);
+    test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos);
+    test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos);
+    test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos);
+    test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos);
+    test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos);
+    test(S("eaint"), "", 0, 0, 0);
+    test(S("binja"), "gfsrt", 0, 0, 0);
+    test(S("latkm"), "pfsoc", 0, 1, 0);
+    test(S("lecfr"), "tpflm", 0, 2, 0);
+    test(S("eqkst"), "sgkec", 0, 4, S::npos);
+    test(S("cdafr"), "romds", 0, 5, 0);
+    test(S("prbhe"), "qhjistlgmr", 0, 0, 0);
+    test(S("lbisk"), "pedfirsglo", 0, 1, 0);
+    test(S("hrlpd"), "aqcoslgrmk", 0, 5, 0);
+    test(S("ehmja"), "dabckmepqj", 0, 9, S::npos);
+    test(S("mhqgd"), "pqscrjthli", 0, 10, 0);
+    test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, 0);
+    test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, 0);
+    test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, 0);
+    test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, S::npos);
+    test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, S::npos);
+    test(S("clrgb"), "", 1, 0, 1);
+    test(S("tjmek"), "osmia", 1, 0, 1);
+    test(S("bgstp"), "ckonl", 1, 1, 1);
+    test(S("hstrk"), "ilcaj", 1, 2, 1);
+    test(S("kmspj"), "lasiq", 1, 4, 1);
+    test(S("tjboh"), "kfqmr", 1, 5, 1);
+    test(S("ilbcj"), "klnitfaobg", 1, 0, 1);
+    test(S("jkngf"), "gjhmdlqikp", 1, 1, 1);
+    test(S("gfcql"), "skbgtahqej", 1, 5, 1);
+    test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 1);
+    test(S("bthpg"), "bjgfmnlkio", 1, 10, 1);
+    test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, 1);
+    test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, 1);
+    test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, S::npos);
+    test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, S::npos);
+    test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, S::npos);
+    test(S("ndrhl"), "", 2, 0, 2);
+    test(S("mrecp"), "otkgb", 2, 0, 2);
+    test(S("qlasf"), "cqsjl", 2, 1, 2);
+    test(S("smaqd"), "dpifl", 2, 2, 2);
+    test(S("hjeni"), "oapht", 2, 4, 2);
+    test(S("ocmfj"), "cifts", 2, 5, 2);
+    test(S("hmftq"), "nmsckbgalo", 2, 0, 2);
+    test(S("fklad"), "tpksqhamle", 2, 1, 2);
+    test(S("dirnm"), "tpdrchmkji", 2, 5, 1);
+    test(S("hrgdc"), "ijagfkblst", 2, 9, 1);
+    test(S("ifakg"), "kpocsignjb", 2, 10, 2);
+    test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, 2);
+    test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, 2);
+    test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 2);
+    test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, S::npos);
+    test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, S::npos);
+    test(S("cjgao"), "", 4, 0, 4);
+    test(S("kjplq"), "mabns", 4, 0, 4);
+    test(S("herni"), "bdnrp", 4, 1, 4);
+    test(S("tadrb"), "scidp", 4, 2, 4);
+    test(S("pkfeo"), "agbjl", 4, 4, 4);
+    test(S("hoser"), "jfmpr", 4, 5, 3);
+    test(S("kgrsp"), "rbpefghsmj", 4, 0, 4);
+    test(S("pgejb"), "apsfntdoqc", 4, 1, 4);
+    test(S("thlnq"), "ndkjeisgcl", 4, 5, 4);
+    test(S("nbmit"), "rnfpqatdeo", 4, 9, 3);
+    test(S("jgmib"), "bntjlqrfik", 4, 10, 2);
+    test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, 4);
+    test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, 4);
+    test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, 3);
+    test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, 2);
+    test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, S::npos);
+    test(S("klopi"), "", 5, 0, 4);
+    test(S("dajhn"), "psthd", 5, 0, 4);
+    test(S("jbgno"), "rpmjd", 5, 1, 4);
+    test(S("hkjae"), "dfsmk", 5, 2, 4);
+}
+
+template <class S>
+void test1()
+{
+    test(S("gbhqo"), "skqne", 5, 4, 4);
+    test(S("ktdor"), "kipnf", 5, 5, 4);
+    test(S("ldprn"), "hmrnqdgifl", 5, 0, 4);
+    test(S("egmjk"), "fsmjcdairn", 5, 1, 4);
+    test(S("armql"), "pcdgltbrfj", 5, 5, 3);
+    test(S("cdhjo"), "aekfctpirg", 5, 9, 4);
+    test(S("jcons"), "ledihrsgpf", 5, 10, 3);
+    test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, 4);
+    test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, 4);
+    test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, 1);
+    test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, 2);
+    test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, S::npos);
+    test(S("gajqn"), "", 6, 0, 4);
+    test(S("stedk"), "hrnat", 6, 0, 4);
+    test(S("tjkaf"), "gsqdt", 6, 1, 4);
+    test(S("dthpe"), "bspkd", 6, 2, 4);
+    test(S("klhde"), "ohcmb", 6, 4, 4);
+    test(S("bhlki"), "heatr", 6, 5, 4);
+    test(S("lqmoh"), "pmblckedfn", 6, 0, 4);
+    test(S("mtqin"), "aceqmsrbik", 6, 1, 4);
+    test(S("dpqbr"), "lmbtdehjrn", 6, 5, 4);
+    test(S("kdhmo"), "teqmcrlgib", 6, 9, 4);
+    test(S("jblqp"), "njolbmspac", 6, 10, 3);
+    test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, 4);
+    test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, 4);
+    test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, 1);
+    test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, S::npos);
+    test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, S::npos);
+    test(S("jnkrfhotgl"), "", 0, 0, 0);
+    test(S("dltjfngbko"), "rqegt", 0, 0, 0);
+    test(S("bmjlpkiqde"), "dashm", 0, 1, 0);
+    test(S("skrflobnqm"), "jqirk", 0, 2, 0);
+    test(S("jkpldtshrm"), "rckeg", 0, 4, 0);
+    test(S("ghasdbnjqo"), "jscie", 0, 5, 0);
+    test(S("igrkhpbqjt"), "efsphndliq", 0, 0, 0);
+    test(S("ikthdgcamf"), "gdicosleja", 0, 1, 0);
+    test(S("pcofgeniam"), "qcpjibosfl", 0, 5, S::npos);
+    test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, S::npos);
+    test(S("itphbqsker"), "dtablcrseo", 0, 10, 0);
+    test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, 0);
+    test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, 0);
+    test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, 0);
+    test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, S::npos);
+    test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, S::npos);
+    test(S("shbcqnmoar"), "", 1, 0, 1);
+    test(S("bdoshlmfin"), "ontrs", 1, 0, 1);
+    test(S("khfrebnsgq"), "pfkna", 1, 1, 1);
+    test(S("getcrsaoji"), "ekosa", 1, 2, 0);
+    test(S("fjiknedcpq"), "anqhk", 1, 4, 1);
+    test(S("tkejgnafrm"), "jekca", 1, 5, 0);
+    test(S("jnakolqrde"), "ikemsjgacf", 1, 0, 1);
+    test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, 1);
+    test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 0);
+    test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 1);
+    test(S("cigfqkated"), "sqcflrgtim", 1, 10, S::npos);
+    test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, 1);
+    test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, 1);
+    test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, S::npos);
+    test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, S::npos);
+    test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, S::npos);
+    test(S("ectnhskflp"), "", 5, 0, 5);
+    test(S("fgtianblpq"), "pijag", 5, 0, 5);
+    test(S("mfeqklirnh"), "jrckd", 5, 1, 5);
+    test(S("astedncjhk"), "qcloh", 5, 2, 5);
+    test(S("fhlqgcajbr"), "thlmp", 5, 4, 5);
+    test(S("epfhocmdng"), "qidmo", 5, 5, 5);
+    test(S("apcnsibger"), "lnegpsjqrd", 5, 0, 5);
+    test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 4);
+    test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, 5);
+    test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 3);
+    test(S("jbhcfposld"), "trfqgmckbe", 5, 10, 5);
+    test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, 5);
+    test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, 5);
+    test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 1);
+    test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, S::npos);
+    test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, S::npos);
+    test(S("shoiedtcjb"), "", 9, 0, 9);
+    test(S("ebcinjgads"), "tqbnh", 9, 0, 9);
+    test(S("dqmregkcfl"), "akmle", 9, 1, 9);
+    test(S("ngcrieqajf"), "iqfkm", 9, 2, 9);
+    test(S("qosmilgnjb"), "tqjsr", 9, 4, 9);
+    test(S("ikabsjtdfl"), "jplqg", 9, 5, 8);
+    test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, 9);
+    test(S("fdnplotmgh"), "morkglpesn", 9, 1, 9);
+    test(S("fdbicojerm"), "dmicerngat", 9, 5, 8);
+    test(S("mbtafndjcq"), "radgeskbtc", 9, 9, 9);
+    test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, 9);
+    test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, 9);
+    test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, 9);
+    test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, 9);
+    test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, 3);
+    test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, S::npos);
+    test(S("ncjpmaekbs"), "", 10, 0, 9);
+    test(S("hlbosgmrak"), "hpmsd", 10, 0, 9);
+    test(S("pqfhsgilen"), "qnpor", 10, 1, 9);
+    test(S("gqtjsbdckh"), "otdma", 10, 2, 9);
+    test(S("cfkqpjlegi"), "efhjg", 10, 4, 9);
+    test(S("beanrfodgj"), "odpte", 10, 5, 9);
+    test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, 9);
+    test(S("iomkfthagj"), "oaklidrbqg", 10, 1, 9);
+}
+
+template <class S>
+void test2()
+{
+    test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, 8);
+    test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, 9);
+    test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, 8);
+    test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, 9);
+    test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, 9);
+    test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, 7);
+    test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, 5);
+    test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, S::npos);
+    test(S("cqjohampgd"), "", 11, 0, 9);
+    test(S("hobitmpsan"), "aocjb", 11, 0, 9);
+    test(S("tjehkpsalm"), "jbrnk", 11, 1, 9);
+    test(S("ngfbojitcl"), "tqedg", 11, 2, 9);
+    test(S("rcfkdbhgjo"), "nqskp", 11, 4, 9);
+    test(S("qghptonrea"), "eaqkl", 11, 5, 7);
+    test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, 9);
+    test(S("hlmgabenti"), "lsftgajqpm", 11, 1, 9);
+    test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, 9);
+    test(S("jqedtkornm"), "shkncmiaqj", 11, 9, 7);
+    test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, 8);
+    test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, 9);
+    test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, 9);
+    test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, 8);
+    test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, S::npos);
+    test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, S::npos);
+    test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, 0);
+    test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, 0);
+    test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, 0);
+    test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, 0);
+    test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, 0);
+    test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, 0);
+    test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, 0);
+    test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, 0);
+    test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, 0);
+    test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, 0);
+    test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, 0);
+    test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, 0);
+    test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, 0);
+    test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, 0);
+    test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, S::npos);
+    test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, S::npos);
+    test(S("febhmqtjanokscdirpgl"), "", 1, 0, 1);
+    test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, 1);
+    test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, 1);
+    test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 0);
+    test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 0);
+    test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, 1);
+    test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, 1);
+    test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, 1);
+    test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, 1);
+    test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 0);
+    test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 0);
+    test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, 1);
+    test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, 1);
+    test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 0);
+    test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, S::npos);
+    test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, S::npos);
+    test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, 10);
+    test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, 10);
+    test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, 10);
+    test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, 10);
+    test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 9);
+    test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 10);
+    test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, 10);
+    test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, 10);
+    test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 10);
+    test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 8);
+    test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 10);
+    test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, 10);
+    test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, 10);
+    test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 8);
+    test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, S::npos);
+    test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, S::npos);
+    test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, 19);
+    test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, 19);
+    test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, 19);
+    test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, 19);
+    test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, 19);
+    test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, 17);
+    test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, 19);
+    test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, 19);
+    test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, 19);
+    test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, 19);
+    test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, 19);
+    test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, 19);
+    test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, 19);
+    test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, 18);
+    test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, 7);
+    test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, S::npos);
+    test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, 19);
+    test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, 19);
+    test(S("grkpahljcftesdmonqib"), "odife", 20, 1, 19);
+    test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, 19);
+    test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, 18);
+    test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, 18);
+    test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, 19);
+    test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, 19);
+    test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, 18);
+    test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, 18);
+    test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, 17);
+    test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, 19);
+}
+
+template <class S>
+void test3()
+{
+    test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, 19);
+    test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, 19);
+    test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, 1);
+    test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, S::npos);
+    test(S("ecgdanriptblhjfqskom"), "", 21, 0, 19);
+    test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, 19);
+    test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, 19);
+    test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, 19);
+    test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, 19);
+    test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, 19);
+    test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, 19);
+    test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, 19);
+    test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, 18);
+    test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, 19);
+    test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, 19);
+    test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, 19);
+    test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, 19);
+    test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, 19);
+    test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, 7);
+    test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    test2<S>();
+    test3<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_last_not_of( "",      0, 0) == SV::npos, "" );
+    static_assert (sv1.find_last_not_of( "irkhs", 0, 5) == SV::npos, "" );
+    static_assert (sv2.find_last_not_of( "",      0, 0) == 0, "" );
+    static_assert (sv2.find_last_not_of( "gfsrt", 5, 0) == 4, "" );
+    static_assert (sv2.find_last_not_of( "lecar", 5, 0) == 4, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_not_of_string_view_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_not_of_string_view_size.pass.cpp
new file mode 100644
index 0000000..40c867d
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_not_of_string_view_size.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// size_type find_last_not_of(const basic_string& str, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
+{
+    assert(s.find_last_not_of(str, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type x)
+{
+    assert(s.find_last_not_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), S(""), 0, S::npos);
+    test(S(""), S("laenf"), 0, S::npos);
+    test(S(""), S("pqlnkmbdjo"), 0, S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos);
+    test(S(""), S(""), 1, S::npos);
+    test(S(""), S("bjaht"), 1, S::npos);
+    test(S(""), S("hjlcmgpket"), 1, S::npos);
+    test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos);
+    test(S("fodgq"), S(""), 0, 0);
+    test(S("qanej"), S("dfkap"), 0, 0);
+    test(S("clbao"), S("ihqrfebgad"), 0, 0);
+    test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, S::npos);
+    test(S("srdfq"), S(""), 1, 1);
+    test(S("oemth"), S("ikcrq"), 1, 1);
+    test(S("cdaih"), S("dmajblfhsg"), 1, 0);
+    test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, S::npos);
+    test(S("cshmd"), S(""), 2, 2);
+    test(S("lhcdo"), S("oebqi"), 2, 2);
+    test(S("qnsoh"), S("kojhpmbsfe"), 2, 1);
+    test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, S::npos);
+    test(S("fmtsp"), S(""), 4, 4);
+    test(S("khbpm"), S("aobjd"), 4, 4);
+    test(S("pbsji"), S("pcbahntsje"), 4, 4);
+    test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, S::npos);
+    test(S("eqmpa"), S(""), 5, 4);
+    test(S("omigs"), S("kocgb"), 5, 4);
+    test(S("onmje"), S("fbslrjiqkm"), 5, 4);
+    test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, S::npos);
+    test(S("schfa"), S(""), 6, 4);
+    test(S("igdsc"), S("qngpd"), 6, 4);
+    test(S("brqgo"), S("rodhqklgmb"), 6, S::npos);
+    test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, S::npos);
+    test(S("hcjitbfapl"), S(""), 0, 0);
+    test(S("daiprenocl"), S("ashjd"), 0, S::npos);
+    test(S("litpcfdghe"), S("mgojkldsqh"), 0, S::npos);
+    test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, S::npos);
+    test(S("qpghtfbaji"), S(""), 1, 1);
+    test(S("gfshlcmdjr"), S("nadkh"), 1, 1);
+    test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 0);
+    test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, S::npos);
+    test(S("crnklpmegd"), S(""), 5, 5);
+    test(S("jsbtafedoc"), S("prqgn"), 5, 5);
+    test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 4);
+    test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, S::npos);
+    test(S("lmofqdhpki"), S(""), 9, 9);
+    test(S("hnefkqimca"), S("rtjpa"), 9, 8);
+    test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, 9);
+    test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, S::npos);
+    test(S("elgofjmbrq"), S(""), 10, 9);
+    test(S("mjqdgalkpc"), S("dplqa"), 10, 9);
+    test(S("kthqnfcerm"), S("dkacjoptns"), 10, 9);
+    test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, S::npos);
+    test(S("eqsgalomhb"), S(""), 11, 9);
+    test(S("akiteljmoh"), S("lofbc"), 11, 9);
+    test(S("hlbdfreqjo"), S("astoegbfpn"), 11, 8);
+    test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, S::npos);
+    test(S("snafbdlghrjkpqtoceim"), S(""), 0, 0);
+    test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, 0);
+    test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, S::npos);
+    test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, S::npos);
+    test(S("jlnkraeodhcspfgbqitm"), S(""), 1, 1);
+    test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, 1);
+    test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 0);
+    test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, S::npos);
+    test(S("hdpkobnsalmcfijregtq"), S(""), 10, 10);
+    test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 9);
+    test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 9);
+    test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, S::npos);
+    test(S("niptglfbosehkamrdqcj"), S(""), 19, 19);
+    test(S("copqdhstbingamjfkler"), S("djkqc"), 19, 19);
+    test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, 16);
+    test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, S::npos);
+    test(S("eaintpchlqsbdgrkjofm"), S(""), 20, 19);
+    test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, 18);
+    test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, 19);
+    test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, S::npos);
+    test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, 19);
+    test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, 19);
+    test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, 19);
+    test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), S(""), S::npos);
+    test(S(""), S("laenf"), S::npos);
+    test(S(""), S("pqlnkmbdjo"), S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), S::npos);
+    test(S("nhmko"), S(""), 4);
+    test(S("lahfb"), S("irkhs"), 4);
+    test(S("gmfhd"), S("kantesmpgj"), 4);
+    test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), S::npos);
+    test(S("eolhfgpjqk"), S(""), 9);
+    test(S("nbatdlmekr"), S("bnrpe"), 8);
+    test(S("jdmciepkaq"), S("jtdaefblso"), 9);
+    test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), S::npos);
+    test(S("gprdcokbnjhlsfmtieqa"), S(""), 19);
+    test(S("qjghlnftcaismkropdeb"), S("bjaht"), 18);
+    test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 17);
+    test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_of_char_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_of_char_size.pass.cpp
new file mode 100644
index 0000000..d28e007
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_of_char_size.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find_last_of(charT c, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_last_of(c, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type x)
+{
+    assert(s.find_last_of(c) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), 'm', 0, S::npos);
+    test(S(""), 'm', 1, S::npos);
+    test(S("kitcj"), 'm', 0, S::npos);
+    test(S("qkamf"), 'm', 1, S::npos);
+    test(S("nhmko"), 'm', 2, 2);
+    test(S("tpsaf"), 'm', 4, S::npos);
+    test(S("lahfb"), 'm', 5, S::npos);
+    test(S("irkhs"), 'm', 6, S::npos);
+    test(S("gmfhdaipsr"), 'm', 0, S::npos);
+    test(S("kantesmpgj"), 'm', 1, S::npos);
+    test(S("odaftiegpm"), 'm', 5, S::npos);
+    test(S("oknlrstdpi"), 'm', 9, S::npos);
+    test(S("eolhfgpjqk"), 'm', 10, S::npos);
+    test(S("pcdrofikas"), 'm', 11, S::npos);
+    test(S("nbatdlmekrgcfqsophij"), 'm', 0, S::npos);
+    test(S("bnrpehidofmqtcksjgla"), 'm', 1, S::npos);
+    test(S("jdmciepkaqgotsrfnhlb"), 'm', 10, 2);
+    test(S("jtdaefblsokrmhpgcnqi"), 'm', 19, 12);
+    test(S("hkbgspofltajcnedqmri"), 'm', 20, 17);
+    test(S("oselktgbcapndfjihrmq"), 'm', 21, 18);
+
+    test(S(""), 'm', S::npos);
+    test(S("csope"), 'm', S::npos);
+    test(S("gfsmthlkon"), 'm', 3);
+    test(S("laenfsbridchgotmkqpj"), 'm', 15);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_last_of( 'i', 0 ) == SV::npos, "" );
+    static_assert (sv1.find_last_of( 'i', 1 ) == SV::npos, "" );
+    static_assert (sv2.find_last_of( 'a', 0 ) == 0, "" );
+    static_assert (sv2.find_last_of( 'a', 1 ) == 0, "" );
+    static_assert (sv2.find_last_of( 'e', 5 ) == 4, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_of_pointer_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_of_pointer_size.pass.cpp
new file mode 100644
index 0000000..f01e277
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_of_pointer_size.pass.cpp
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find_last_of(str, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type x)
+{
+    assert(s.find_last_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, S::npos);
+    test(S(""), "laenf", 0, S::npos);
+    test(S(""), "pqlnkmbdjo", 0, S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", 0, S::npos);
+    test(S(""), "", 1, S::npos);
+    test(S(""), "bjaht", 1, S::npos);
+    test(S(""), "hjlcmgpket", 1, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 1, S::npos);
+    test(S("fodgq"), "", 0, S::npos);
+    test(S("qanej"), "dfkap", 0, S::npos);
+    test(S("clbao"), "ihqrfebgad", 0, S::npos);
+    test(S("mekdn"), "ngtjfcalbseiqrphmkdo", 0, 0);
+    test(S("srdfq"), "", 1, S::npos);
+    test(S("oemth"), "ikcrq", 1, S::npos);
+    test(S("cdaih"), "dmajblfhsg", 1, 1);
+    test(S("qohtk"), "oqftjhdmkgsblacenirp", 1, 1);
+    test(S("cshmd"), "", 2, S::npos);
+    test(S("lhcdo"), "oebqi", 2, S::npos);
+    test(S("qnsoh"), "kojhpmbsfe", 2, 2);
+    test(S("pkrof"), "acbsjqogpltdkhinfrem", 2, 2);
+    test(S("fmtsp"), "", 4, S::npos);
+    test(S("khbpm"), "aobjd", 4, 2);
+    test(S("pbsji"), "pcbahntsje", 4, 3);
+    test(S("mprdj"), "fhepcrntkoagbmldqijs", 4, 4);
+    test(S("eqmpa"), "", 5, S::npos);
+    test(S("omigs"), "kocgb", 5, 3);
+    test(S("onmje"), "fbslrjiqkm", 5, 3);
+    test(S("oqmrj"), "jeidpcmalhfnqbgtrsko", 5, 4);
+    test(S("schfa"), "", 6, S::npos);
+    test(S("igdsc"), "qngpd", 6, 2);
+    test(S("brqgo"), "rodhqklgmb", 6, 4);
+    test(S("tnrph"), "thdjgafrlbkoiqcspmne", 6, 4);
+    test(S("hcjitbfapl"), "", 0, S::npos);
+    test(S("daiprenocl"), "ashjd", 0, 0);
+    test(S("litpcfdghe"), "mgojkldsqh", 0, 0);
+    test(S("aidjksrolc"), "imqnaghkfrdtlopbjesc", 0, 0);
+    test(S("qpghtfbaji"), "", 1, S::npos);
+    test(S("gfshlcmdjr"), "nadkh", 1, S::npos);
+    test(S("nkodajteqp"), "ofdrqmkebl", 1, 1);
+    test(S("gbmetiprqd"), "bdfjqgatlksriohemnpc", 1, 1);
+    test(S("crnklpmegd"), "", 5, S::npos);
+    test(S("jsbtafedoc"), "prqgn", 5, S::npos);
+    test(S("qnmodrtkeb"), "pejafmnokr", 5, 5);
+    test(S("cpebqsfmnj"), "odnqkgijrhabfmcestlp", 5, 5);
+    test(S("lmofqdhpki"), "", 9, S::npos);
+    test(S("hnefkqimca"), "rtjpa", 9, 9);
+    test(S("drtasbgmfp"), "ktsrmnqagd", 9, 7);
+    test(S("lsaijeqhtr"), "rtdhgcisbnmoaqkfpjle", 9, 9);
+    test(S("elgofjmbrq"), "", 10, S::npos);
+    test(S("mjqdgalkpc"), "dplqa", 10, 8);
+    test(S("kthqnfcerm"), "dkacjoptns", 10, 6);
+    test(S("dfsjhanorc"), "hqfimtrgnbekpdcsjalo", 10, 9);
+    test(S("eqsgalomhb"), "", 11, S::npos);
+    test(S("akiteljmoh"), "lofbc", 11, 8);
+    test(S("hlbdfreqjo"), "astoegbfpn", 11, 9);
+    test(S("taqobhlerg"), "pdgreqomsncafklhtibj", 11, 9);
+    test(S("snafbdlghrjkpqtoceim"), "", 0, S::npos);
+    test(S("aemtbrgcklhndjisfpoq"), "lbtqd", 0, S::npos);
+    test(S("pnracgfkjdiholtbqsem"), "tboimldpjh", 0, 0);
+    test(S("dicfltehbsgrmojnpkaq"), "slcerthdaiqjfnobgkpm", 0, 0);
+    test(S("jlnkraeodhcspfgbqitm"), "", 1, S::npos);
+    test(S("lhosrngtmfjikbqpcade"), "aqibs", 1, S::npos);
+    test(S("rbtaqjhgkneisldpmfoc"), "gtfblmqinc", 1, 1);
+    test(S("gpifsqlrdkbonjtmheca"), "mkqpbtdalgniorhfescj", 1, 1);
+    test(S("hdpkobnsalmcfijregtq"), "", 10, S::npos);
+    test(S("jtlshdgqaiprkbcoenfm"), "pblas", 10, 10);
+    test(S("fkdrbqltsgmcoiphneaj"), "arosdhcfme", 10, 10);
+    test(S("crsplifgtqedjohnabmk"), "blkhjeogicatqfnpdmsr", 10, 10);
+    test(S("niptglfbosehkamrdqcj"), "", 19, S::npos);
+    test(S("copqdhstbingamjfkler"), "djkqc", 19, 16);
+    test(S("mrtaefilpdsgocnhqbjk"), "lgokshjtpb", 19, 19);
+    test(S("kojatdhlcmigpbfrqnes"), "bqjhtkfepimcnsgrlado", 19, 19);
+    test(S("eaintpchlqsbdgrkjofm"), "", 20, S::npos);
+    test(S("gjnhidfsepkrtaqbmclo"), "nocfa", 20, 19);
+    test(S("spocfaktqdbiejlhngmr"), "bgtajmiedc", 20, 18);
+    test(S("rphmlekgfscndtaobiqj"), "lsckfnqgdahejiopbtmr", 20, 19);
+    test(S("liatsqdoegkmfcnbhrpj"), "", 21, S::npos);
+    test(S("binjagtfldkrspcomqeh"), "gfsrt", 21, 12);
+    test(S("latkmisecnorjbfhqpdg"), "pfsocbhjtm", 21, 17);
+    test(S("lecfratdjkhnsmqpoigb"), "tpflmdnoicjgkberhqsa", 21, 19);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), "", S::npos);
+    test(S(""), "laenf", S::npos);
+    test(S(""), "pqlnkmbdjo", S::npos);
+    test(S(""), "qkamfogpnljdcshbreti", S::npos);
+    test(S("nhmko"), "", S::npos);
+    test(S("lahfb"), "irkhs", 2);
+    test(S("gmfhd"), "kantesmpgj", 1);
+    test(S("odaft"), "oknlrstdpiqmjbaghcfe", 4);
+    test(S("eolhfgpjqk"), "", S::npos);
+    test(S("nbatdlmekr"), "bnrpe", 9);
+    test(S("jdmciepkaq"), "jtdaefblso", 8);
+    test(S("hkbgspoflt"), "oselktgbcapndfjihrmq", 9);
+    test(S("gprdcokbnjhlsfmtieqa"), "", S::npos);
+    test(S("qjghlnftcaismkropdeb"), "bjaht", 19);
+    test(S("pnalfrdtkqcmojiesbhg"), "hjlcmgpket", 19);
+    test(S("pniotcfrhqsmgdkjbael"), "htaobedqikfplcgjsmrn", 19);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_last_of( "",      0) == SV::npos, "" );
+    static_assert (sv1.find_last_of( "irkhs", 5) == SV::npos, "" );
+    static_assert (sv2.find_last_of( "",      0) == SV::npos, "" );
+    static_assert (sv2.find_last_of( "gfsrt", 5) == SV::npos, "" );
+    static_assert (sv2.find_last_of( "lecar", 5) == 4, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_of_pointer_size_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_of_pointer_size_size.pass.cpp
new file mode 100644
index 0000000..a38ffa6
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_of_pointer_size_size.pass.cpp
@@ -0,0 +1,392 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type n, typename S::size_type x)
+{
+    assert(s.find_last_of(str, pos, n) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0, S::npos);
+    test(S(""), "irkhs", 0, 0, S::npos);
+    test(S(""), "kante", 0, 1, S::npos);
+    test(S(""), "oknlr", 0, 2, S::npos);
+    test(S(""), "pcdro", 0, 4, S::npos);
+    test(S(""), "bnrpe", 0, 5, S::npos);
+    test(S(""), "jtdaefblso", 0, 0, S::npos);
+    test(S(""), "oselktgbca", 0, 1, S::npos);
+    test(S(""), "eqgaplhckj", 0, 5, S::npos);
+    test(S(""), "bjahtcmnlp", 0, 9, S::npos);
+    test(S(""), "hjlcmgpket", 0, 10, S::npos);
+    test(S(""), "htaobedqikfplcgjsmrn", 0, 0, S::npos);
+    test(S(""), "hpqiarojkcdlsgnmfetb", 0, 1, S::npos);
+    test(S(""), "dfkaprhjloqetcsimnbg", 0, 10, S::npos);
+    test(S(""), "ihqrfebgadntlpmjksoc", 0, 19, S::npos);
+    test(S(""), "ngtjfcalbseiqrphmkdo", 0, 20, S::npos);
+    test(S(""), "", 1, 0, S::npos);
+    test(S(""), "lbtqd", 1, 0, S::npos);
+    test(S(""), "tboim", 1, 1, S::npos);
+    test(S(""), "slcer", 1, 2, S::npos);
+    test(S(""), "cbjfs", 1, 4, S::npos);
+    test(S(""), "aqibs", 1, 5, S::npos);
+    test(S(""), "gtfblmqinc", 1, 0, S::npos);
+    test(S(""), "mkqpbtdalg", 1, 1, S::npos);
+    test(S(""), "kphatlimcd", 1, 5, S::npos);
+    test(S(""), "pblasqogic", 1, 9, S::npos);
+    test(S(""), "arosdhcfme", 1, 10, S::npos);
+    test(S(""), "blkhjeogicatqfnpdmsr", 1, 0, S::npos);
+    test(S(""), "bmhineprjcoadgstflqk", 1, 1, S::npos);
+    test(S(""), "djkqcmetslnghpbarfoi", 1, 10, S::npos);
+    test(S(""), "lgokshjtpbemarcdqnfi", 1, 19, S::npos);
+    test(S(""), "bqjhtkfepimcnsgrlado", 1, 20, S::npos);
+    test(S("eaint"), "", 0, 0, S::npos);
+    test(S("binja"), "gfsrt", 0, 0, S::npos);
+    test(S("latkm"), "pfsoc", 0, 1, S::npos);
+    test(S("lecfr"), "tpflm", 0, 2, S::npos);
+    test(S("eqkst"), "sgkec", 0, 4, 0);
+    test(S("cdafr"), "romds", 0, 5, S::npos);
+    test(S("prbhe"), "qhjistlgmr", 0, 0, S::npos);
+    test(S("lbisk"), "pedfirsglo", 0, 1, S::npos);
+    test(S("hrlpd"), "aqcoslgrmk", 0, 5, S::npos);
+    test(S("ehmja"), "dabckmepqj", 0, 9, 0);
+    test(S("mhqgd"), "pqscrjthli", 0, 10, S::npos);
+    test(S("tgklq"), "kfphdcsjqmobliagtren", 0, 0, S::npos);
+    test(S("bocjs"), "rokpefncljibsdhqtagm", 0, 1, S::npos);
+    test(S("grbsd"), "afionmkphlebtcjqsgrd", 0, 10, S::npos);
+    test(S("ofjqr"), "aenmqplidhkofrjbctsg", 0, 19, 0);
+    test(S("btlfi"), "osjmbtcadhiklegrpqnf", 0, 20, 0);
+    test(S("clrgb"), "", 1, 0, S::npos);
+    test(S("tjmek"), "osmia", 1, 0, S::npos);
+    test(S("bgstp"), "ckonl", 1, 1, S::npos);
+    test(S("hstrk"), "ilcaj", 1, 2, S::npos);
+    test(S("kmspj"), "lasiq", 1, 4, S::npos);
+    test(S("tjboh"), "kfqmr", 1, 5, S::npos);
+    test(S("ilbcj"), "klnitfaobg", 1, 0, S::npos);
+    test(S("jkngf"), "gjhmdlqikp", 1, 1, S::npos);
+    test(S("gfcql"), "skbgtahqej", 1, 5, 0);
+    test(S("dqtlg"), "bjsdgtlpkf", 1, 9, 0);
+    test(S("bthpg"), "bjgfmnlkio", 1, 10, 0);
+    test(S("dgsnq"), "lbhepotfsjdqigcnamkr", 1, 0, S::npos);
+    test(S("rmfhp"), "tebangckmpsrqdlfojhi", 1, 1, S::npos);
+    test(S("jfdam"), "joflqbdkhtegimscpanr", 1, 10, 1);
+    test(S("edapb"), "adpmcohetfbsrjinlqkg", 1, 19, 1);
+    test(S("brfsm"), "iacldqjpfnogbsrhmetk", 1, 20, 1);
+    test(S("ndrhl"), "", 2, 0, S::npos);
+    test(S("mrecp"), "otkgb", 2, 0, S::npos);
+    test(S("qlasf"), "cqsjl", 2, 1, S::npos);
+    test(S("smaqd"), "dpifl", 2, 2, S::npos);
+    test(S("hjeni"), "oapht", 2, 4, 0);
+    test(S("ocmfj"), "cifts", 2, 5, 1);
+    test(S("hmftq"), "nmsckbgalo", 2, 0, S::npos);
+    test(S("fklad"), "tpksqhamle", 2, 1, S::npos);
+    test(S("dirnm"), "tpdrchmkji", 2, 5, 2);
+    test(S("hrgdc"), "ijagfkblst", 2, 9, 2);
+    test(S("ifakg"), "kpocsignjb", 2, 10, 0);
+    test(S("ebrgd"), "pecqtkjsnbdrialgmohf", 2, 0, S::npos);
+    test(S("rcjml"), "aiortphfcmkjebgsndql", 2, 1, S::npos);
+    test(S("peqmt"), "sdbkeamglhipojqftrcn", 2, 10, 1);
+    test(S("frehn"), "ljqncehgmfktroapidbs", 2, 19, 2);
+    test(S("tqolf"), "rtcfodilamkbenjghqps", 2, 20, 2);
+    test(S("cjgao"), "", 4, 0, S::npos);
+    test(S("kjplq"), "mabns", 4, 0, S::npos);
+    test(S("herni"), "bdnrp", 4, 1, S::npos);
+    test(S("tadrb"), "scidp", 4, 2, S::npos);
+    test(S("pkfeo"), "agbjl", 4, 4, S::npos);
+    test(S("hoser"), "jfmpr", 4, 5, 4);
+    test(S("kgrsp"), "rbpefghsmj", 4, 0, S::npos);
+    test(S("pgejb"), "apsfntdoqc", 4, 1, S::npos);
+    test(S("thlnq"), "ndkjeisgcl", 4, 5, 3);
+    test(S("nbmit"), "rnfpqatdeo", 4, 9, 4);
+    test(S("jgmib"), "bntjlqrfik", 4, 10, 4);
+    test(S("ncrfj"), "kcrtmpolnaqejghsfdbi", 4, 0, S::npos);
+    test(S("ncsik"), "lobheanpkmqidsrtcfgj", 4, 1, S::npos);
+    test(S("sgbfh"), "athdkljcnreqbgpmisof", 4, 10, 4);
+    test(S("dktbn"), "qkdmjialrscpbhefgont", 4, 19, 4);
+    test(S("fthqm"), "dmasojntqleribkgfchp", 4, 20, 4);
+    test(S("klopi"), "", 5, 0, S::npos);
+    test(S("dajhn"), "psthd", 5, 0, S::npos);
+    test(S("jbgno"), "rpmjd", 5, 1, S::npos);
+    test(S("hkjae"), "dfsmk", 5, 2, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S("gbhqo"), "skqne", 5, 4, 3);
+    test(S("ktdor"), "kipnf", 5, 5, 0);
+    test(S("ldprn"), "hmrnqdgifl", 5, 0, S::npos);
+    test(S("egmjk"), "fsmjcdairn", 5, 1, S::npos);
+    test(S("armql"), "pcdgltbrfj", 5, 5, 4);
+    test(S("cdhjo"), "aekfctpirg", 5, 9, 0);
+    test(S("jcons"), "ledihrsgpf", 5, 10, 4);
+    test(S("cbrkp"), "mqcklahsbtirgopefndj", 5, 0, S::npos);
+    test(S("fhgna"), "kmlthaoqgecrnpdbjfis", 5, 1, S::npos);
+    test(S("ejfcd"), "sfhbamcdptojlkrenqgi", 5, 10, 4);
+    test(S("kqjhe"), "pbniofmcedrkhlstgaqj", 5, 19, 4);
+    test(S("pbdjl"), "mongjratcskbhqiepfdl", 5, 20, 4);
+    test(S("gajqn"), "", 6, 0, S::npos);
+    test(S("stedk"), "hrnat", 6, 0, S::npos);
+    test(S("tjkaf"), "gsqdt", 6, 1, S::npos);
+    test(S("dthpe"), "bspkd", 6, 2, S::npos);
+    test(S("klhde"), "ohcmb", 6, 4, 2);
+    test(S("bhlki"), "heatr", 6, 5, 1);
+    test(S("lqmoh"), "pmblckedfn", 6, 0, S::npos);
+    test(S("mtqin"), "aceqmsrbik", 6, 1, S::npos);
+    test(S("dpqbr"), "lmbtdehjrn", 6, 5, 3);
+    test(S("kdhmo"), "teqmcrlgib", 6, 9, 3);
+    test(S("jblqp"), "njolbmspac", 6, 10, 4);
+    test(S("qmjgl"), "pofnhidklamecrbqjgst", 6, 0, S::npos);
+    test(S("rothp"), "jbhckmtgrqnosafedpli", 6, 1, S::npos);
+    test(S("ghknq"), "dobntpmqklicsahgjerf", 6, 10, 4);
+    test(S("eopfi"), "tpdshainjkbfoemlrgcq", 6, 19, 4);
+    test(S("dsnmg"), "oldpfgeakrnitscbjmqh", 6, 20, 4);
+    test(S("jnkrfhotgl"), "", 0, 0, S::npos);
+    test(S("dltjfngbko"), "rqegt", 0, 0, S::npos);
+    test(S("bmjlpkiqde"), "dashm", 0, 1, S::npos);
+    test(S("skrflobnqm"), "jqirk", 0, 2, S::npos);
+    test(S("jkpldtshrm"), "rckeg", 0, 4, S::npos);
+    test(S("ghasdbnjqo"), "jscie", 0, 5, S::npos);
+    test(S("igrkhpbqjt"), "efsphndliq", 0, 0, S::npos);
+    test(S("ikthdgcamf"), "gdicosleja", 0, 1, S::npos);
+    test(S("pcofgeniam"), "qcpjibosfl", 0, 5, 0);
+    test(S("rlfjgesqhc"), "lrhmefnjcq", 0, 9, 0);
+    test(S("itphbqsker"), "dtablcrseo", 0, 10, S::npos);
+    test(S("skjafcirqm"), "apckjsftedbhgomrnilq", 0, 0, S::npos);
+    test(S("tcqomarsfd"), "pcbrgflehjtiadnsokqm", 0, 1, S::npos);
+    test(S("rocfeldqpk"), "nsiadegjklhobrmtqcpf", 0, 10, S::npos);
+    test(S("cfpegndlkt"), "cpmajdqnolikhgsbretf", 0, 19, 0);
+    test(S("fqbtnkeasj"), "jcflkntmgiqrphdosaeb", 0, 20, 0);
+    test(S("shbcqnmoar"), "", 1, 0, S::npos);
+    test(S("bdoshlmfin"), "ontrs", 1, 0, S::npos);
+    test(S("khfrebnsgq"), "pfkna", 1, 1, S::npos);
+    test(S("getcrsaoji"), "ekosa", 1, 2, 1);
+    test(S("fjiknedcpq"), "anqhk", 1, 4, S::npos);
+    test(S("tkejgnafrm"), "jekca", 1, 5, 1);
+    test(S("jnakolqrde"), "ikemsjgacf", 1, 0, S::npos);
+    test(S("lcjptsmgbe"), "arolgsjkhm", 1, 1, S::npos);
+    test(S("itfsmcjorl"), "oftkbldhre", 1, 5, 1);
+    test(S("omchkfrjea"), "gbkqdoeftl", 1, 9, 0);
+    test(S("cigfqkated"), "sqcflrgtim", 1, 10, 1);
+    test(S("tscenjikml"), "fmhbkislrjdpanogqcet", 1, 0, S::npos);
+    test(S("qcpaemsinf"), "rnioadktqlgpbcjsmhef", 1, 1, S::npos);
+    test(S("gltkojeipd"), "oakgtnldpsefihqmjcbr", 1, 10, 1);
+    test(S("qistfrgnmp"), "gbnaelosidmcjqktfhpr", 1, 19, 1);
+    test(S("bdnpfcqaem"), "akbripjhlosndcmqgfet", 1, 20, 1);
+    test(S("ectnhskflp"), "", 5, 0, S::npos);
+    test(S("fgtianblpq"), "pijag", 5, 0, S::npos);
+    test(S("mfeqklirnh"), "jrckd", 5, 1, S::npos);
+    test(S("astedncjhk"), "qcloh", 5, 2, S::npos);
+    test(S("fhlqgcajbr"), "thlmp", 5, 4, 2);
+    test(S("epfhocmdng"), "qidmo", 5, 5, 4);
+    test(S("apcnsibger"), "lnegpsjqrd", 5, 0, S::npos);
+    test(S("aqkocrbign"), "rjqdablmfs", 5, 1, 5);
+    test(S("ijsmdtqgce"), "enkgpbsjaq", 5, 5, S::npos);
+    test(S("clobgsrken"), "kdsgoaijfh", 5, 9, 5);
+    test(S("jbhcfposld"), "trfqgmckbe", 5, 10, 4);
+    test(S("oqnpblhide"), "igetsracjfkdnpoblhqm", 5, 0, S::npos);
+    test(S("lroeasctif"), "nqctfaogirshlekbdjpm", 5, 1, S::npos);
+    test(S("bpjlgmiedh"), "csehfgomljdqinbartkp", 5, 10, 5);
+    test(S("pamkeoidrj"), "qahoegcmplkfsjbdnitr", 5, 19, 5);
+    test(S("espogqbthk"), "dpteiajrqmsognhlfbkc", 5, 20, 5);
+    test(S("shoiedtcjb"), "", 9, 0, S::npos);
+    test(S("ebcinjgads"), "tqbnh", 9, 0, S::npos);
+    test(S("dqmregkcfl"), "akmle", 9, 1, S::npos);
+    test(S("ngcrieqajf"), "iqfkm", 9, 2, 6);
+    test(S("qosmilgnjb"), "tqjsr", 9, 4, 8);
+    test(S("ikabsjtdfl"), "jplqg", 9, 5, 9);
+    test(S("ersmicafdh"), "oilnrbcgtj", 9, 0, S::npos);
+    test(S("fdnplotmgh"), "morkglpesn", 9, 1, 7);
+    test(S("fdbicojerm"), "dmicerngat", 9, 5, 9);
+    test(S("mbtafndjcq"), "radgeskbtc", 9, 9, 6);
+    test(S("mlenkpfdtc"), "ljikprsmqo", 9, 10, 5);
+    test(S("ahlcifdqgs"), "trqihkcgsjamfdbolnpe", 9, 0, S::npos);
+    test(S("bgjemaltks"), "lqmthbsrekajgnofcipd", 9, 1, 6);
+    test(S("pdhslbqrfc"), "jtalmedribkgqsopcnfh", 9, 10, 7);
+    test(S("dirhtsnjkc"), "spqfoiclmtagejbndkrh", 9, 19, 9);
+    test(S("dlroktbcja"), "nmotklspigjrdhcfaebq", 9, 20, 9);
+    test(S("ncjpmaekbs"), "", 10, 0, S::npos);
+    test(S("hlbosgmrak"), "hpmsd", 10, 0, S::npos);
+    test(S("pqfhsgilen"), "qnpor", 10, 1, 1);
+    test(S("gqtjsbdckh"), "otdma", 10, 2, 2);
+    test(S("cfkqpjlegi"), "efhjg", 10, 4, 7);
+    test(S("beanrfodgj"), "odpte", 10, 5, 7);
+    test(S("adtkqpbjfi"), "bctdgfmolr", 10, 0, S::npos);
+    test(S("iomkfthagj"), "oaklidrbqg", 10, 1, 1);
+}
+
+template <class S>
+void test2()
+{
+    test(S("sdpcilonqj"), "dnjfsagktr", 10, 5, 9);
+    test(S("gtfbdkqeml"), "nejaktmiqg", 10, 9, 8);
+    test(S("bmeqgcdorj"), "pjqonlebsf", 10, 10, 9);
+    test(S("etqlcanmob"), "dshmnbtolcjepgaikfqr", 10, 0, S::npos);
+    test(S("roqmkbdtia"), "iogfhpabtjkqlrnemcds", 10, 1, 8);
+    test(S("kadsithljf"), "ngridfabjsecpqltkmoh", 10, 10, 9);
+    test(S("sgtkpbfdmh"), "athmknplcgofrqejsdib", 10, 19, 9);
+    test(S("qgmetnabkl"), "ldobhmqcafnjtkeisgrp", 10, 20, 9);
+    test(S("cqjohampgd"), "", 11, 0, S::npos);
+    test(S("hobitmpsan"), "aocjb", 11, 0, S::npos);
+    test(S("tjehkpsalm"), "jbrnk", 11, 1, 1);
+    test(S("ngfbojitcl"), "tqedg", 11, 2, 7);
+    test(S("rcfkdbhgjo"), "nqskp", 11, 4, 3);
+    test(S("qghptonrea"), "eaqkl", 11, 5, 9);
+    test(S("hnprfgqjdl"), "reaoicljqm", 11, 0, S::npos);
+    test(S("hlmgabenti"), "lsftgajqpm", 11, 1, 1);
+    test(S("ofcjanmrbs"), "rlpfogmits", 11, 5, 7);
+    test(S("jqedtkornm"), "shkncmiaqj", 11, 9, 9);
+    test(S("rfedlasjmg"), "fpnatrhqgs", 11, 10, 9);
+    test(S("talpqjsgkm"), "sjclemqhnpdbgikarfot", 11, 0, S::npos);
+    test(S("lrkcbtqpie"), "otcmedjikgsfnqbrhpla", 11, 1, S::npos);
+    test(S("cipogdskjf"), "bonsaefdqiprkhlgtjcm", 11, 10, 9);
+    test(S("nqedcojahi"), "egpscmahijlfnkrodqtb", 11, 19, 9);
+    test(S("hefnrkmctj"), "kmqbfepjthgilscrndoa", 11, 20, 9);
+    test(S("atqirnmekfjolhpdsgcb"), "", 0, 0, S::npos);
+    test(S("echfkmlpribjnqsaogtd"), "prboq", 0, 0, S::npos);
+    test(S("qnhiftdgcleajbpkrosm"), "fjcqh", 0, 1, S::npos);
+    test(S("chamfknorbedjitgslpq"), "fmosa", 0, 2, S::npos);
+    test(S("njhqpibfmtlkaecdrgso"), "qdbok", 0, 4, S::npos);
+    test(S("ebnghfsqkprmdcljoiat"), "amslg", 0, 5, S::npos);
+    test(S("letjomsgihfrpqbkancd"), "smpltjneqb", 0, 0, S::npos);
+    test(S("nblgoipcrqeaktshjdmf"), "flitskrnge", 0, 1, S::npos);
+    test(S("cehkbngtjoiflqapsmrd"), "pgqihmlbef", 0, 5, S::npos);
+    test(S("mignapfoklbhcqjetdrs"), "cfpdqjtgsb", 0, 9, S::npos);
+    test(S("ceatbhlsqjgpnokfrmdi"), "htpsiaflom", 0, 10, S::npos);
+    test(S("ocihkjgrdelpfnmastqb"), "kpjfiaceghsrdtlbnomq", 0, 0, S::npos);
+    test(S("noelgschdtbrjfmiqkap"), "qhtbomidljgafneksprc", 0, 1, S::npos);
+    test(S("dkclqfombepritjnghas"), "nhtjobkcefldimpsaqgr", 0, 10, S::npos);
+    test(S("miklnresdgbhqcojftap"), "prabcjfqnoeskilmtgdh", 0, 19, 0);
+    test(S("htbcigojaqmdkfrnlsep"), "dtrgmchilkasqoebfpjn", 0, 20, 0);
+    test(S("febhmqtjanokscdirpgl"), "", 1, 0, S::npos);
+    test(S("loakbsqjpcrdhftniegm"), "sqome", 1, 0, S::npos);
+    test(S("reagphsqflbitdcjmkno"), "smfte", 1, 1, S::npos);
+    test(S("jitlfrqemsdhkopncabg"), "ciboh", 1, 2, 1);
+    test(S("mhtaepscdnrjqgbkifol"), "haois", 1, 4, 1);
+    test(S("tocesrfmnglpbjihqadk"), "abfki", 1, 5, S::npos);
+    test(S("lpfmctjrhdagneskbqoi"), "frdkocntmq", 1, 0, S::npos);
+    test(S("lsmqaepkdhncirbtjfgo"), "oasbpedlnr", 1, 1, S::npos);
+    test(S("epoiqmtldrabnkjhcfsg"), "kltqmhgand", 1, 5, S::npos);
+    test(S("emgasrilpknqojhtbdcf"), "gdtfjchpmr", 1, 9, 1);
+    test(S("hnfiagdpcklrjetqbsom"), "ponmcqblet", 1, 10, 1);
+    test(S("nsdfebgajhmtricpoklq"), "sgphqdnofeiklatbcmjr", 1, 0, S::npos);
+    test(S("atjgfsdlpobmeiqhncrk"), "ljqprsmigtfoneadckbh", 1, 1, S::npos);
+    test(S("sitodfgnrejlahcbmqkp"), "ligeojhafnkmrcsqtbdp", 1, 10, 1);
+    test(S("fraghmbiceknltjpqosd"), "lsimqfnjarbopedkhcgt", 1, 19, 1);
+    test(S("pmafenlhqtdbkirjsogc"), "abedmfjlghniorcqptks", 1, 20, 1);
+    test(S("pihgmoeqtnakrjslcbfd"), "", 10, 0, S::npos);
+    test(S("gjdkeprctqblnhiafsom"), "hqtoa", 10, 0, S::npos);
+    test(S("mkpnblfdsahrcqijteog"), "cahif", 10, 1, S::npos);
+    test(S("gckarqnelodfjhmbptis"), "kehis", 10, 2, 7);
+    test(S("gqpskidtbclomahnrjfe"), "kdlmh", 10, 4, 10);
+    test(S("pkldjsqrfgitbhmaecno"), "paeql", 10, 5, 6);
+    test(S("aftsijrbeklnmcdqhgop"), "aghoqiefnb", 10, 0, S::npos);
+    test(S("mtlgdrhafjkbiepqnsoc"), "jrbqaikpdo", 10, 1, 9);
+    test(S("pqgirnaefthokdmbsclj"), "smjonaeqcl", 10, 5, 5);
+    test(S("kpdbgjmtherlsfcqoina"), "eqbdrkcfah", 10, 9, 10);
+    test(S("jrlbothiknqmdgcfasep"), "kapmsienhf", 10, 10, 9);
+    test(S("mjogldqferckabinptsh"), "jpqotrlenfcsbhkaimdg", 10, 0, S::npos);
+    test(S("apoklnefbhmgqcdrisjt"), "jlbmhnfgtcqprikeados", 10, 1, S::npos);
+    test(S("ifeopcnrjbhkdgatmqls"), "stgbhfmdaljnpqoicker", 10, 10, 10);
+    test(S("ckqhaiesmjdnrgolbtpf"), "oihcetflbjagdsrkmqpn", 10, 19, 10);
+    test(S("bnlgapfimcoterskqdjh"), "adtclebmnpjsrqfkigoh", 10, 20, 10);
+    test(S("kgdlrobpmjcthqsafeni"), "", 19, 0, S::npos);
+    test(S("dfkechomjapgnslbtqir"), "beafg", 19, 0, S::npos);
+    test(S("rloadknfbqtgmhcsipje"), "iclat", 19, 1, 16);
+    test(S("mgjhkolrnadqbpetcifs"), "rkhnf", 19, 2, 7);
+    test(S("cmlfakiojdrgtbsphqen"), "clshq", 19, 4, 16);
+    test(S("kghbfipeomsntdalrqjc"), "dtcoj", 19, 5, 19);
+    test(S("eldiqckrnmtasbghjfpo"), "rqosnjmfth", 19, 0, S::npos);
+    test(S("abqjcfedgotihlnspkrm"), "siatdfqglh", 19, 1, 15);
+    test(S("qfbadrtjsimkolcenhpg"), "mrlshtpgjq", 19, 5, 17);
+    test(S("abseghclkjqifmtodrnp"), "adlcskgqjt", 19, 9, 16);
+    test(S("ibmsnlrjefhtdokacqpg"), "drshcjknaf", 19, 10, 16);
+    test(S("mrkfciqjebaponsthldg"), "etsaqroinghpkjdlfcbm", 19, 0, S::npos);
+    test(S("mjkticdeoqshpalrfbgn"), "sgepdnkqliambtrocfhj", 19, 1, 10);
+    test(S("rqnoclbdejgiphtfsakm"), "nlmcjaqgbsortfdihkpe", 19, 10, 19);
+    test(S("plkqbhmtfaeodjcrsing"), "racfnpmosldibqkghjet", 19, 19, 19);
+    test(S("oegalhmstjrfickpbndq"), "fjhdsctkqeiolagrnmbp", 19, 20, 19);
+    test(S("rdtgjcaohpblniekmsfq"), "", 20, 0, S::npos);
+    test(S("ofkqbnjetrmsaidphglc"), "ejanp", 20, 0, S::npos);
+    test(S("grkpahljcftesdmonqib"), "odife", 20, 1, 15);
+    test(S("jimlgbhfqkteospardcn"), "okaqd", 20, 2, 12);
+    test(S("gftenihpmslrjkqadcob"), "lcdbi", 20, 4, 19);
+    test(S("bmhldogtckrfsanijepq"), "fsqbj", 20, 5, 19);
+    test(S("nfqkrpjdesabgtlcmoih"), "bigdomnplq", 20, 0, S::npos);
+    test(S("focalnrpiqmdkstehbjg"), "apiblotgcd", 20, 1, 3);
+    test(S("rhqdspkmebiflcotnjga"), "acfhdenops", 20, 5, 19);
+    test(S("rahdtmsckfboqlpniegj"), "jopdeamcrk", 20, 9, 19);
+    test(S("fbkeiopclstmdqranjhg"), "trqncbkgmh", 20, 10, 19);
+    test(S("lifhpdgmbconstjeqark"), "tomglrkencbsfjqpihda", 20, 0, S::npos);
+}
+
+template <class S>
+void test3()
+{
+    test(S("pboqganrhedjmltsicfk"), "gbkhdnpoietfcmrslajq", 20, 1, 4);
+    test(S("klchabsimetjnqgorfpd"), "rtfnmbsglkjaichoqedp", 20, 10, 17);
+    test(S("sirfgmjqhctndbklaepo"), "ohkmdpfqbsacrtjnlgei", 20, 19, 19);
+    test(S("rlbdsiceaonqjtfpghkm"), "dlbrteoisgphmkncajfq", 20, 20, 19);
+    test(S("ecgdanriptblhjfqskom"), "", 21, 0, S::npos);
+    test(S("fdmiarlpgcskbhoteqjn"), "sjrlo", 21, 0, S::npos);
+    test(S("rlbstjqopignecmfadkh"), "qjpor", 21, 1, 6);
+    test(S("grjpqmbshektdolcafni"), "odhfn", 21, 2, 13);
+    test(S("sakfcohtqnibprjmlged"), "qtfin", 21, 4, 10);
+    test(S("mjtdglasihqpocebrfkn"), "hpqfo", 21, 5, 17);
+    test(S("okaplfrntghqbmeicsdj"), "fabmertkos", 21, 0, S::npos);
+    test(S("sahngemrtcjidqbklfpo"), "brqtgkmaej", 21, 1, 14);
+    test(S("dlmsipcnekhbgoaftqjr"), "nfrdeihsgl", 21, 5, 19);
+    test(S("ahegrmqnoiklpfsdbcjt"), "hlfrosekpi", 21, 9, 14);
+    test(S("hdsjbnmlegtkqripacof"), "atgbkrjdsm", 21, 10, 16);
+    test(S("pcnedrfjihqbalkgtoms"), "blnrptjgqmaifsdkhoec", 21, 0, S::npos);
+    test(S("qjidealmtpskrbfhocng"), "ctpmdahebfqjgknloris", 21, 1, 17);
+    test(S("qeindtagmokpfhsclrbj"), "apnkeqthrmlbfodiscgj", 21, 10, 17);
+    test(S("kpfegbjhsrnodltqciam"), "jdgictpframeoqlsbknh", 21, 19, 19);
+    test(S("hnbrcplsjfgiktoedmaq"), "qprlsfojamgndekthibc", 21, 20, 19);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    test2<S>();
+    test3<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find_last_of( "",      0, 0) == SV::npos, "" );
+    static_assert (sv1.find_last_of( "irkhs", 0, 5) == SV::npos, "" );
+    static_assert (sv2.find_last_of( "",      0, 0) == SV::npos, "" );
+    static_assert (sv2.find_last_of( "gfsrt", 5, 5) == SV::npos, "" );
+    static_assert (sv2.find_last_of( "lecar", 5, 5) == 4, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_last_of_string_view_size.pass.cpp b/test/experimental/string.view/string.view.find/find_last_of_string_view_size.pass.cpp
new file mode 100644
index 0000000..6fd3772
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_last_of_string_view_size.pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// size_type find_last_of(const basic_string& str, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
+{
+    assert(s.find_last_of(str, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x < s.size());
+}
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type x)
+{
+    assert(s.find_last_of(str) == x);
+    if (x != S::npos)
+        assert(x < s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), S(""), 0, S::npos);
+    test(S(""), S("laenf"), 0, S::npos);
+    test(S(""), S("pqlnkmbdjo"), 0, S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), 0, S::npos);
+    test(S(""), S(""), 1, S::npos);
+    test(S(""), S("bjaht"), 1, S::npos);
+    test(S(""), S("hjlcmgpket"), 1, S::npos);
+    test(S(""), S("htaobedqikfplcgjsmrn"), 1, S::npos);
+    test(S("fodgq"), S(""), 0, S::npos);
+    test(S("qanej"), S("dfkap"), 0, S::npos);
+    test(S("clbao"), S("ihqrfebgad"), 0, S::npos);
+    test(S("mekdn"), S("ngtjfcalbseiqrphmkdo"), 0, 0);
+    test(S("srdfq"), S(""), 1, S::npos);
+    test(S("oemth"), S("ikcrq"), 1, S::npos);
+    test(S("cdaih"), S("dmajblfhsg"), 1, 1);
+    test(S("qohtk"), S("oqftjhdmkgsblacenirp"), 1, 1);
+    test(S("cshmd"), S(""), 2, S::npos);
+    test(S("lhcdo"), S("oebqi"), 2, S::npos);
+    test(S("qnsoh"), S("kojhpmbsfe"), 2, 2);
+    test(S("pkrof"), S("acbsjqogpltdkhinfrem"), 2, 2);
+    test(S("fmtsp"), S(""), 4, S::npos);
+    test(S("khbpm"), S("aobjd"), 4, 2);
+    test(S("pbsji"), S("pcbahntsje"), 4, 3);
+    test(S("mprdj"), S("fhepcrntkoagbmldqijs"), 4, 4);
+    test(S("eqmpa"), S(""), 5, S::npos);
+    test(S("omigs"), S("kocgb"), 5, 3);
+    test(S("onmje"), S("fbslrjiqkm"), 5, 3);
+    test(S("oqmrj"), S("jeidpcmalhfnqbgtrsko"), 5, 4);
+    test(S("schfa"), S(""), 6, S::npos);
+    test(S("igdsc"), S("qngpd"), 6, 2);
+    test(S("brqgo"), S("rodhqklgmb"), 6, 4);
+    test(S("tnrph"), S("thdjgafrlbkoiqcspmne"), 6, 4);
+    test(S("hcjitbfapl"), S(""), 0, S::npos);
+    test(S("daiprenocl"), S("ashjd"), 0, 0);
+    test(S("litpcfdghe"), S("mgojkldsqh"), 0, 0);
+    test(S("aidjksrolc"), S("imqnaghkfrdtlopbjesc"), 0, 0);
+    test(S("qpghtfbaji"), S(""), 1, S::npos);
+    test(S("gfshlcmdjr"), S("nadkh"), 1, S::npos);
+    test(S("nkodajteqp"), S("ofdrqmkebl"), 1, 1);
+    test(S("gbmetiprqd"), S("bdfjqgatlksriohemnpc"), 1, 1);
+    test(S("crnklpmegd"), S(""), 5, S::npos);
+    test(S("jsbtafedoc"), S("prqgn"), 5, S::npos);
+    test(S("qnmodrtkeb"), S("pejafmnokr"), 5, 5);
+    test(S("cpebqsfmnj"), S("odnqkgijrhabfmcestlp"), 5, 5);
+    test(S("lmofqdhpki"), S(""), 9, S::npos);
+    test(S("hnefkqimca"), S("rtjpa"), 9, 9);
+    test(S("drtasbgmfp"), S("ktsrmnqagd"), 9, 7);
+    test(S("lsaijeqhtr"), S("rtdhgcisbnmoaqkfpjle"), 9, 9);
+    test(S("elgofjmbrq"), S(""), 10, S::npos);
+    test(S("mjqdgalkpc"), S("dplqa"), 10, 8);
+    test(S("kthqnfcerm"), S("dkacjoptns"), 10, 6);
+    test(S("dfsjhanorc"), S("hqfimtrgnbekpdcsjalo"), 10, 9);
+    test(S("eqsgalomhb"), S(""), 11, S::npos);
+    test(S("akiteljmoh"), S("lofbc"), 11, 8);
+    test(S("hlbdfreqjo"), S("astoegbfpn"), 11, 9);
+    test(S("taqobhlerg"), S("pdgreqomsncafklhtibj"), 11, 9);
+    test(S("snafbdlghrjkpqtoceim"), S(""), 0, S::npos);
+    test(S("aemtbrgcklhndjisfpoq"), S("lbtqd"), 0, S::npos);
+    test(S("pnracgfkjdiholtbqsem"), S("tboimldpjh"), 0, 0);
+    test(S("dicfltehbsgrmojnpkaq"), S("slcerthdaiqjfnobgkpm"), 0, 0);
+    test(S("jlnkraeodhcspfgbqitm"), S(""), 1, S::npos);
+    test(S("lhosrngtmfjikbqpcade"), S("aqibs"), 1, S::npos);
+    test(S("rbtaqjhgkneisldpmfoc"), S("gtfblmqinc"), 1, 1);
+    test(S("gpifsqlrdkbonjtmheca"), S("mkqpbtdalgniorhfescj"), 1, 1);
+    test(S("hdpkobnsalmcfijregtq"), S(""), 10, S::npos);
+    test(S("jtlshdgqaiprkbcoenfm"), S("pblas"), 10, 10);
+    test(S("fkdrbqltsgmcoiphneaj"), S("arosdhcfme"), 10, 10);
+    test(S("crsplifgtqedjohnabmk"), S("blkhjeogicatqfnpdmsr"), 10, 10);
+    test(S("niptglfbosehkamrdqcj"), S(""), 19, S::npos);
+    test(S("copqdhstbingamjfkler"), S("djkqc"), 19, 16);
+    test(S("mrtaefilpdsgocnhqbjk"), S("lgokshjtpb"), 19, 19);
+    test(S("kojatdhlcmigpbfrqnes"), S("bqjhtkfepimcnsgrlado"), 19, 19);
+    test(S("eaintpchlqsbdgrkjofm"), S(""), 20, S::npos);
+    test(S("gjnhidfsepkrtaqbmclo"), S("nocfa"), 20, 19);
+    test(S("spocfaktqdbiejlhngmr"), S("bgtajmiedc"), 20, 18);
+    test(S("rphmlekgfscndtaobiqj"), S("lsckfnqgdahejiopbtmr"), 20, 19);
+    test(S("liatsqdoegkmfcnbhrpj"), S(""), 21, S::npos);
+    test(S("binjagtfldkrspcomqeh"), S("gfsrt"), 21, 12);
+    test(S("latkmisecnorjbfhqpdg"), S("pfsocbhjtm"), 21, 17);
+    test(S("lecfratdjkhnsmqpoigb"), S("tpflmdnoicjgkberhqsa"), 21, 19);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), S(""), S::npos);
+    test(S(""), S("laenf"), S::npos);
+    test(S(""), S("pqlnkmbdjo"), S::npos);
+    test(S(""), S("qkamfogpnljdcshbreti"), S::npos);
+    test(S("nhmko"), S(""), S::npos);
+    test(S("lahfb"), S("irkhs"), 2);
+    test(S("gmfhd"), S("kantesmpgj"), 1);
+    test(S("odaft"), S("oknlrstdpiqmjbaghcfe"), 4);
+    test(S("eolhfgpjqk"), S(""), S::npos);
+    test(S("nbatdlmekr"), S("bnrpe"), 9);
+    test(S("jdmciepkaq"), S("jtdaefblso"), 8);
+    test(S("hkbgspoflt"), S("oselktgbcapndfjihrmq"), 9);
+    test(S("gprdcokbnjhlsfmtieqa"), S(""), S::npos);
+    test(S("qjghlnftcaismkropdeb"), S("bjaht"), 19);
+    test(S("pnalfrdtkqcmojiesbhg"), S("hjlcmgpket"), 19);
+    test(S("pniotcfrhqsmgdkjbael"), S("htaobedqikfplcgjsmrn"), 19);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+}
diff --git a/test/experimental/string.view/string.view.find/find_pointer_size.pass.cpp b/test/experimental/string.view/string.view.find/find_pointer_size.pass.cpp
new file mode 100644
index 0000000..5ebe414
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_pointer_size.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// constexpr size_type find(const charT* s, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.find(str, pos) == x);
+    if (x != S::npos)
+    {
+        typename S::size_type n = S::traits_type::length(str);
+        assert(pos <= x && x + n <= s.size());
+    }
+}
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type x)
+{
+    assert(s.find(str) == x);
+    if (x != S::npos)
+    {
+        typename S::size_type n = S::traits_type::length(str);
+        assert(0 <= x && x + n <= s.size());
+    }
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0);
+    test(S(""), "abcde", 0, S::npos);
+    test(S(""), "abcdeabcde", 0, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, S::npos);
+    test(S(""), "", 1, S::npos);
+    test(S(""), "abcde", 1, S::npos);
+    test(S(""), "abcdeabcde", 1, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, S::npos);
+    test(S("abcde"), "", 0, 0);
+    test(S("abcde"), "abcde", 0, 0);
+    test(S("abcde"), "abcdeabcde", 0, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, S::npos);
+    test(S("abcde"), "", 1, 1);
+    test(S("abcde"), "abcde", 1, S::npos);
+    test(S("abcde"), "abcdeabcde", 1, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, S::npos);
+    test(S("abcde"), "", 2, 2);
+    test(S("abcde"), "abcde", 2, S::npos);
+    test(S("abcde"), "abcdeabcde", 2, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, S::npos);
+    test(S("abcde"), "", 4, 4);
+    test(S("abcde"), "abcde", 4, S::npos);
+    test(S("abcde"), "abcdeabcde", 4, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, S::npos);
+    test(S("abcde"), "", 5, 5);
+    test(S("abcde"), "abcde", 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 5, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, S::npos);
+    test(S("abcde"), "", 6, S::npos);
+    test(S("abcde"), "abcde", 6, S::npos);
+    test(S("abcde"), "abcdeabcde", 6, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, S::npos);
+    test(S("abcdeabcde"), "", 0, 0);
+    test(S("abcdeabcde"), "abcde", 0, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, S::npos);
+    test(S("abcdeabcde"), "", 1, 1);
+    test(S("abcdeabcde"), "abcde", 1, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 1, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, S::npos);
+    test(S("abcdeabcde"), "", 5, 5);
+    test(S("abcdeabcde"), "abcde", 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, S::npos);
+    test(S("abcdeabcde"), "", 9, 9);
+    test(S("abcdeabcde"), "abcde", 9, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 9, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, S::npos);
+    test(S("abcdeabcde"), "", 10, 10);
+    test(S("abcdeabcde"), "abcde", 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, S::npos);
+    test(S("abcdeabcde"), "", 11, S::npos);
+    test(S("abcdeabcde"), "abcde", 11, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 11, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 1, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 19, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 20, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 21, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), "", 0);
+    test(S(""), "abcde", S::npos);
+    test(S(""), "abcdeabcde", S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", S::npos);
+    test(S("abcde"), "", 0);
+    test(S("abcde"), "abcde", 0);
+    test(S("abcde"), "abcdeabcde", S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", S::npos);
+    test(S("abcdeabcde"), "", 0);
+    test(S("abcdeabcde"), "abcde", 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find( "") == 0, "" );
+    static_assert (sv1.find( "abcde") == SV::npos, "" );
+    static_assert (sv2.find( "") == 0, "" );
+    static_assert (sv2.find( "abcde") == 0, "" );
+    static_assert (sv2.find( "abcde", 1) == SV::npos, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_pointer_size_size.pass.cpp b/test/experimental/string.view/string.view.find/find_pointer_size_size.pass.cpp
new file mode 100644
index 0000000..382cbaf
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_pointer_size_size.pass.cpp
@@ -0,0 +1,393 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find(const charT* s, size_type pos, size_type n) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type n, typename S::size_type x)
+{
+    assert(s.find(str, pos, n) == x);
+    if (x != S::npos)
+        assert(pos <= x && x + n <= s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0, 0);
+    test(S(""), "abcde", 0, 0, 0);
+    test(S(""), "abcde", 0, 1, S::npos);
+    test(S(""), "abcde", 0, 2, S::npos);
+    test(S(""), "abcde", 0, 4, S::npos);
+    test(S(""), "abcde", 0, 5, S::npos);
+    test(S(""), "abcdeabcde", 0, 0, 0);
+    test(S(""), "abcdeabcde", 0, 1, S::npos);
+    test(S(""), "abcdeabcde", 0, 5, S::npos);
+    test(S(""), "abcdeabcde", 0, 9, S::npos);
+    test(S(""), "abcdeabcde", 0, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 1, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 19, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 20, S::npos);
+    test(S(""), "", 1, 0, S::npos);
+    test(S(""), "abcde", 1, 0, S::npos);
+    test(S(""), "abcde", 1, 1, S::npos);
+    test(S(""), "abcde", 1, 2, S::npos);
+    test(S(""), "abcde", 1, 4, S::npos);
+    test(S(""), "abcde", 1, 5, S::npos);
+    test(S(""), "abcdeabcde", 1, 0, S::npos);
+    test(S(""), "abcdeabcde", 1, 1, S::npos);
+    test(S(""), "abcdeabcde", 1, 5, S::npos);
+    test(S(""), "abcdeabcde", 1, 9, S::npos);
+    test(S(""), "abcdeabcde", 1, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 0, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 1, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 19, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 20, S::npos);
+    test(S("abcde"), "", 0, 0, 0);
+    test(S("abcde"), "abcde", 0, 0, 0);
+    test(S("abcde"), "abcde", 0, 1, 0);
+    test(S("abcde"), "abcde", 0, 2, 0);
+    test(S("abcde"), "abcde", 0, 4, 0);
+    test(S("abcde"), "abcde", 0, 5, 0);
+    test(S("abcde"), "abcdeabcde", 0, 0, 0);
+    test(S("abcde"), "abcdeabcde", 0, 1, 0);
+    test(S("abcde"), "abcdeabcde", 0, 5, 0);
+    test(S("abcde"), "abcdeabcde", 0, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 0, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 1, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos);
+    test(S("abcde"), "", 1, 0, 1);
+    test(S("abcde"), "abcde", 1, 0, 1);
+    test(S("abcde"), "abcde", 1, 1, S::npos);
+    test(S("abcde"), "abcde", 1, 2, S::npos);
+    test(S("abcde"), "abcde", 1, 4, S::npos);
+    test(S("abcde"), "abcde", 1, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 1, 0, 1);
+    test(S("abcde"), "abcdeabcde", 1, 1, S::npos);
+    test(S("abcde"), "abcdeabcde", 1, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 1, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 1, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 0, 1);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 1, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos);
+    test(S("abcde"), "", 2, 0, 2);
+    test(S("abcde"), "abcde", 2, 0, 2);
+    test(S("abcde"), "abcde", 2, 1, S::npos);
+    test(S("abcde"), "abcde", 2, 2, S::npos);
+    test(S("abcde"), "abcde", 2, 4, S::npos);
+    test(S("abcde"), "abcde", 2, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 2, 0, 2);
+    test(S("abcde"), "abcdeabcde", 2, 1, S::npos);
+    test(S("abcde"), "abcdeabcde", 2, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 2, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 2, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 0, 2);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 1, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 20, S::npos);
+    test(S("abcde"), "", 4, 0, 4);
+    test(S("abcde"), "abcde", 4, 0, 4);
+    test(S("abcde"), "abcde", 4, 1, S::npos);
+    test(S("abcde"), "abcde", 4, 2, S::npos);
+    test(S("abcde"), "abcde", 4, 4, S::npos);
+    test(S("abcde"), "abcde", 4, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 4, 0, 4);
+    test(S("abcde"), "abcdeabcde", 4, 1, S::npos);
+    test(S("abcde"), "abcdeabcde", 4, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 4, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 4, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 0, 4);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 1, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 20, S::npos);
+    test(S("abcde"), "", 5, 0, 5);
+    test(S("abcde"), "abcde", 5, 0, 5);
+    test(S("abcde"), "abcde", 5, 1, S::npos);
+    test(S("abcde"), "abcde", 5, 2, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S("abcde"), "abcde", 5, 4, S::npos);
+    test(S("abcde"), "abcde", 5, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 5, 0, 5);
+    test(S("abcde"), "abcdeabcde", 5, 1, S::npos);
+    test(S("abcde"), "abcdeabcde", 5, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 5, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 5, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 0, 5);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 1, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos);
+    test(S("abcde"), "", 6, 0, S::npos);
+    test(S("abcde"), "abcde", 6, 0, S::npos);
+    test(S("abcde"), "abcde", 6, 1, S::npos);
+    test(S("abcde"), "abcde", 6, 2, S::npos);
+    test(S("abcde"), "abcde", 6, 4, S::npos);
+    test(S("abcde"), "abcde", 6, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 6, 0, S::npos);
+    test(S("abcde"), "abcdeabcde", 6, 1, S::npos);
+    test(S("abcde"), "abcdeabcde", 6, 5, S::npos);
+    test(S("abcde"), "abcdeabcde", 6, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 6, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 0, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 1, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 20, S::npos);
+    test(S("abcdeabcde"), "", 0, 0, 0);
+    test(S("abcdeabcde"), "abcde", 0, 0, 0);
+    test(S("abcdeabcde"), "abcde", 0, 1, 0);
+    test(S("abcdeabcde"), "abcde", 0, 2, 0);
+    test(S("abcdeabcde"), "abcde", 0, 4, 0);
+    test(S("abcdeabcde"), "abcde", 0, 5, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 0, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 1, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 5, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 9, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos);
+    test(S("abcdeabcde"), "", 1, 0, 1);
+    test(S("abcdeabcde"), "abcde", 1, 0, 1);
+    test(S("abcdeabcde"), "abcde", 1, 1, 5);
+    test(S("abcdeabcde"), "abcde", 1, 2, 5);
+    test(S("abcdeabcde"), "abcde", 1, 4, 5);
+    test(S("abcdeabcde"), "abcde", 1, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 0, 1);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 9, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos);
+    test(S("abcdeabcde"), "", 5, 0, 5);
+    test(S("abcdeabcde"), "abcde", 5, 0, 5);
+    test(S("abcdeabcde"), "abcde", 5, 1, 5);
+    test(S("abcdeabcde"), "abcde", 5, 2, 5);
+    test(S("abcdeabcde"), "abcde", 5, 4, 5);
+    test(S("abcdeabcde"), "abcde", 5, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 0, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 9, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 0, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos);
+    test(S("abcdeabcde"), "", 9, 0, 9);
+    test(S("abcdeabcde"), "abcde", 9, 0, 9);
+    test(S("abcdeabcde"), "abcde", 9, 1, S::npos);
+    test(S("abcdeabcde"), "abcde", 9, 2, S::npos);
+    test(S("abcdeabcde"), "abcde", 9, 4, S::npos);
+    test(S("abcdeabcde"), "abcde", 9, 5, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 0, 9);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 1, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 5, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 9, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 0, 9);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 1, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 20, S::npos);
+    test(S("abcdeabcde"), "", 10, 0, 10);
+    test(S("abcdeabcde"), "abcde", 10, 0, 10);
+    test(S("abcdeabcde"), "abcde", 10, 1, S::npos);
+    test(S("abcdeabcde"), "abcde", 10, 2, S::npos);
+    test(S("abcdeabcde"), "abcde", 10, 4, S::npos);
+    test(S("abcdeabcde"), "abcde", 10, 5, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 0, 10);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 1, S::npos);
+}
+
+template <class S>
+void test2()
+{
+    test(S("abcdeabcde"), "abcdeabcde", 10, 5, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 9, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, S::npos);
+    test(S("abcdeabcde"), "", 11, 0, S::npos);
+    test(S("abcdeabcde"), "abcde", 11, 0, S::npos);
+    test(S("abcdeabcde"), "abcde", 11, 1, S::npos);
+    test(S("abcdeabcde"), "abcde", 11, 2, S::npos);
+    test(S("abcdeabcde"), "abcde", 11, 4, S::npos);
+    test(S("abcdeabcde"), "abcde", 11, 5, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 0, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 1, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 5, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 9, S::npos);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 0, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 1, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 10, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 2, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 4, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 5, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 5, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 9, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 1, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 2, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 4, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 5, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 1, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 5, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 9, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 10, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, 5);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 1, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 2, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 4, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 5, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 1, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 5, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 9, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 2, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 4, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 5, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 5, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 9, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 20, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 2, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 4, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 5, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 5, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 9, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 0, 20);
+}
+
+template <class S>
+void test3()
+{
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 21, 0, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 0, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 2, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 4, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 5, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 0, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 5, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 9, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 0, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 20, S::npos);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    test2<S>();
+    test3<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find( "",      0, 0 ) == 0, "" );
+    static_assert (sv1.find( "abcde", 0, 0 ) == 0, "" );
+    static_assert (sv1.find( "abcde", 0, 1 ) == SV::npos, "" );
+    static_assert (sv2.find( "",      0, 0 ) == 0, "" );
+    static_assert (sv2.find( "abcde", 0, 0 ) == 0, "" );
+    static_assert (sv2.find( "abcde", 0, 1 ) == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/find_string_view_size.pass.cpp b/test/experimental/string.view/string.view.find/find_string_view_size.pass.cpp
new file mode 100644
index 0000000..84132ac
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/find_string_view_size.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type find(const basic_string_view& str, size_type pos = 0) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
+{
+    assert(s.find(str, pos) == x);
+    if (x != S::npos)
+        assert(pos <= x && x + str.size() <= s.size());
+}
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type x)
+{
+    assert(s.find(str) == x);
+    if (x != S::npos)
+        assert(0 <= x && x + str.size() <= s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), S(""), 0, 0);
+    test(S(""), S("abcde"), 0, S::npos);
+    test(S(""), S("abcdeabcde"), 0, S::npos);
+    test(S(""), S("abcdeabcdeabcdeabcde"), 0, S::npos);
+    test(S(""), S(""), 1, S::npos);
+    test(S(""), S("abcde"), 1, S::npos);
+    test(S(""), S("abcdeabcde"), 1, S::npos);
+    test(S(""), S("abcdeabcdeabcdeabcde"), 1, S::npos);
+    test(S("abcde"), S(""), 0, 0);
+    test(S("abcde"), S("abcde"), 0, 0);
+    test(S("abcde"), S("abcdeabcde"), 0, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos);
+    test(S("abcde"), S(""), 1, 1);
+    test(S("abcde"), S("abcde"), 1, S::npos);
+    test(S("abcde"), S("abcdeabcde"), 1, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos);
+    test(S("abcde"), S(""), 2, 2);
+    test(S("abcde"), S("abcde"), 2, S::npos);
+    test(S("abcde"), S("abcdeabcde"), 2, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 2, S::npos);
+    test(S("abcde"), S(""), 4, 4);
+    test(S("abcde"), S("abcde"), 4, S::npos);
+    test(S("abcde"), S("abcdeabcde"), 4, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 4, S::npos);
+    test(S("abcde"), S(""), 5, 5);
+    test(S("abcde"), S("abcde"), 5, S::npos);
+    test(S("abcde"), S("abcdeabcde"), 5, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos);
+    test(S("abcde"), S(""), 6, S::npos);
+    test(S("abcde"), S("abcde"), 6, S::npos);
+    test(S("abcde"), S("abcdeabcde"), 6, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 6, S::npos);
+    test(S("abcdeabcde"), S(""), 0, 0);
+    test(S("abcdeabcde"), S("abcde"), 0, 0);
+    test(S("abcdeabcde"), S("abcdeabcde"), 0, 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos);
+    test(S("abcdeabcde"), S(""), 1, 1);
+    test(S("abcdeabcde"), S("abcde"), 1, 5);
+    test(S("abcdeabcde"), S("abcdeabcde"), 1, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos);
+    test(S("abcdeabcde"), S(""), 5, 5);
+    test(S("abcdeabcde"), S("abcde"), 5, 5);
+    test(S("abcdeabcde"), S("abcdeabcde"), 5, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos);
+    test(S("abcdeabcde"), S(""), 9, 9);
+    test(S("abcdeabcde"), S("abcde"), 9, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcde"), 9, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 9, S::npos);
+    test(S("abcdeabcde"), S(""), 10, 10);
+    test(S("abcdeabcde"), S("abcde"), 10, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcde"), 10, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, S::npos);
+    test(S("abcdeabcde"), S(""), 11, S::npos);
+    test(S("abcdeabcde"), S("abcde"), 11, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcde"), 11, S::npos);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 11, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 1, 1);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 1, 5);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 1, 5);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 19, 19);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 19, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 20, 20);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 21, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 21, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 21, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 21, S::npos);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), S(""), 0);
+    test(S(""), S("abcde"), S::npos);
+    test(S(""), S("abcdeabcde"), S::npos);
+    test(S(""), S("abcdeabcdeabcdeabcde"), S::npos);
+    test(S("abcde"), S(""), 0);
+    test(S("abcde"), S("abcde"), 0);
+    test(S("abcde"), S("abcdeabcde"), S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), S::npos);
+    test(S("abcdeabcde"), S(""), 0);
+    test(S("abcdeabcde"), S("abcde"), 0);
+    test(S("abcdeabcde"), S("abcdeabcde"), 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.find(sv1) == 0, "" );
+    static_assert (sv1.find(sv2) == SV::npos, "" );
+    static_assert (sv2.find(sv1) == 0, "" );
+    static_assert (sv2.find(sv2) == 0, "" );
+    static_assert (sv2.find(sv2, 1 ) == SV::npos, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/rfind_char_size.pass.cpp b/test/experimental/string.view/string.view.find/rfind_char_size.pass.cpp
new file mode 100644
index 0000000..9014d88
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/rfind_char_size.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+// constexpr size_type rfind(charT c, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.rfind(c, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x + 1 <= s.size());
+}
+
+template <class S>
+void
+test(const S& s, typename S::value_type c, typename S::size_type x)
+{
+    assert(s.rfind(c) == x);
+    if (x != S::npos)
+        assert(x + 1 <= s.size());
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test(S(""), 'b', 0, S::npos);
+    test(S(""), 'b', 1, S::npos);
+    test(S("abcde"), 'b', 0, S::npos);
+    test(S("abcde"), 'b', 1, 1);
+    test(S("abcde"), 'b', 2, 1);
+    test(S("abcde"), 'b', 4, 1);
+    test(S("abcde"), 'b', 5, 1);
+    test(S("abcde"), 'b', 6, 1);
+    test(S("abcdeabcde"), 'b', 0, S::npos);
+    test(S("abcdeabcde"), 'b', 1, 1);
+    test(S("abcdeabcde"), 'b', 5, 1);
+    test(S("abcdeabcde"), 'b', 9, 6);
+    test(S("abcdeabcde"), 'b', 10, 6);
+    test(S("abcdeabcde"), 'b', 11, 6);
+    test(S("abcdeabcdeabcdeabcde"), 'b', 0, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), 'b', 1, 1);
+    test(S("abcdeabcdeabcdeabcde"), 'b', 10, 6);
+    test(S("abcdeabcdeabcdeabcde"), 'b', 19, 16);
+    test(S("abcdeabcdeabcdeabcde"), 'b', 20, 16);
+    test(S("abcdeabcdeabcdeabcde"), 'b', 21, 16);
+
+    test(S(""), 'b', S::npos);
+    test(S("abcde"), 'b', 1);
+    test(S("abcdeabcde"), 'b', 6);
+    test(S("abcdeabcdeabcdeabcde"), 'b', 16);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.rfind( 'b', 0 ) == SV::npos, "" );
+    static_assert (sv1.rfind( 'b', 1 ) == SV::npos, "" );
+    static_assert (sv2.rfind( 'b', 0 ) == SV::npos, "" );
+    static_assert (sv2.rfind( 'b', 1 ) == 1, "" );
+    static_assert (sv2.rfind( 'b', 2 ) == 1, "" );
+    static_assert (sv2.rfind( 'b', 3 ) == 1, "" );
+    static_assert (sv2.rfind( 'b', 4 ) == 1, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/rfind_pointer_size.pass.cpp b/test/experimental/string.view/string.view.find/rfind_pointer_size.pass.cpp
new file mode 100644
index 0000000..0559d31
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/rfind_pointer_size.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+// constexpr size_type rfind(const charT* s, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+     typename S::size_type x)
+{
+    assert(s.rfind(str, pos) == x);
+    if (x != S::npos)
+    {
+        typename S::size_type n = S::traits_type::length(str);
+        assert(x <= pos && x + n <= s.size());
+    }
+}
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type x)
+{
+    assert(s.rfind(str) == x);
+    if (x != S::npos)
+    {
+        typename S::size_type pos = s.size();
+        typename S::size_type n = S::traits_type::length(str);
+        assert(x <= pos && x + n <= s.size());
+    }
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0);
+    test(S(""), "abcde", 0, S::npos);
+    test(S(""), "abcdeabcde", 0, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, S::npos);
+    test(S(""), "", 1, 0);
+    test(S(""), "abcde", 1, S::npos);
+    test(S(""), "abcdeabcde", 1, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, S::npos);
+    test(S("abcde"), "", 0, 0);
+    test(S("abcde"), "abcde", 0, 0);
+    test(S("abcde"), "abcdeabcde", 0, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, S::npos);
+    test(S("abcde"), "", 1, 1);
+    test(S("abcde"), "abcde", 1, 0);
+    test(S("abcde"), "abcdeabcde", 1, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, S::npos);
+    test(S("abcde"), "", 2, 2);
+    test(S("abcde"), "abcde", 2, 0);
+    test(S("abcde"), "abcdeabcde", 2, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, S::npos);
+    test(S("abcde"), "", 4, 4);
+    test(S("abcde"), "abcde", 4, 0);
+    test(S("abcde"), "abcdeabcde", 4, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, S::npos);
+    test(S("abcde"), "", 5, 5);
+    test(S("abcde"), "abcde", 5, 0);
+    test(S("abcde"), "abcdeabcde", 5, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, S::npos);
+    test(S("abcde"), "", 6, 5);
+    test(S("abcde"), "abcde", 6, 0);
+    test(S("abcde"), "abcdeabcde", 6, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, S::npos);
+    test(S("abcdeabcde"), "", 0, 0);
+    test(S("abcdeabcde"), "abcde", 0, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, S::npos);
+    test(S("abcdeabcde"), "", 1, 1);
+    test(S("abcdeabcde"), "abcde", 1, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, S::npos);
+    test(S("abcdeabcde"), "", 5, 5);
+    test(S("abcdeabcde"), "abcde", 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, S::npos);
+    test(S("abcdeabcde"), "", 9, 9);
+    test(S("abcdeabcde"), "abcde", 9, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, S::npos);
+    test(S("abcdeabcde"), "", 10, 10);
+    test(S("abcdeabcde"), "abcde", 10, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, S::npos);
+    test(S("abcdeabcde"), "", 11, 10);
+    test(S("abcdeabcde"), "abcde", 11, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 1, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 19, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 20, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 21, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 0);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), "", 0);
+    test(S(""), "abcde", S::npos);
+    test(S(""), "abcdeabcde", S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", S::npos);
+    test(S("abcde"), "", 5);
+    test(S("abcde"), "abcde", 0);
+    test(S("abcde"), "abcdeabcde", S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", S::npos);
+    test(S("abcdeabcde"), "", 10);
+    test(S("abcdeabcde"), "abcde", 5);
+    test(S("abcdeabcde"), "abcdeabcde", 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.rfind( "") == 0, "" );
+    static_assert (sv1.rfind( "abcde") == SV::npos, "" );
+    static_assert (sv2.rfind( "") == 5, "" );
+    static_assert (sv2.rfind( "abcde") == 0, "" );
+    static_assert (sv2.rfind( "abcde", 1) == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/rfind_pointer_size_size.pass.cpp b/test/experimental/string.view/string.view.find/rfind_pointer_size_size.pass.cpp
new file mode 100644
index 0000000..9116e3a
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/rfind_pointer_size_size.pass.cpp
@@ -0,0 +1,392 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+// constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const typename S::value_type* str, typename S::size_type pos,
+      typename S::size_type n, typename S::size_type x)
+{
+    assert(s.rfind(str, pos, n) == x);
+    if (x != S::npos)
+        assert(x <= pos && x + n <= s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), "", 0, 0, 0);
+    test(S(""), "abcde", 0, 0, 0);
+    test(S(""), "abcde", 0, 1, S::npos);
+    test(S(""), "abcde", 0, 2, S::npos);
+    test(S(""), "abcde", 0, 4, S::npos);
+    test(S(""), "abcde", 0, 5, S::npos);
+    test(S(""), "abcdeabcde", 0, 0, 0);
+    test(S(""), "abcdeabcde", 0, 1, S::npos);
+    test(S(""), "abcdeabcde", 0, 5, S::npos);
+    test(S(""), "abcdeabcde", 0, 9, S::npos);
+    test(S(""), "abcdeabcde", 0, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 1, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 19, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 0, 20, S::npos);
+    test(S(""), "", 1, 0, 0);
+    test(S(""), "abcde", 1, 0, 0);
+    test(S(""), "abcde", 1, 1, S::npos);
+    test(S(""), "abcde", 1, 2, S::npos);
+    test(S(""), "abcde", 1, 4, S::npos);
+    test(S(""), "abcde", 1, 5, S::npos);
+    test(S(""), "abcdeabcde", 1, 0, 0);
+    test(S(""), "abcdeabcde", 1, 1, S::npos);
+    test(S(""), "abcdeabcde", 1, 5, S::npos);
+    test(S(""), "abcdeabcde", 1, 9, S::npos);
+    test(S(""), "abcdeabcde", 1, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 0, 0);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 1, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 10, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 19, S::npos);
+    test(S(""), "abcdeabcdeabcdeabcde", 1, 20, S::npos);
+    test(S("abcde"), "", 0, 0, 0);
+    test(S("abcde"), "abcde", 0, 0, 0);
+    test(S("abcde"), "abcde", 0, 1, 0);
+    test(S("abcde"), "abcde", 0, 2, 0);
+    test(S("abcde"), "abcde", 0, 4, 0);
+    test(S("abcde"), "abcde", 0, 5, 0);
+    test(S("abcde"), "abcdeabcde", 0, 0, 0);
+    test(S("abcde"), "abcdeabcde", 0, 1, 0);
+    test(S("abcde"), "abcdeabcde", 0, 5, 0);
+    test(S("abcde"), "abcdeabcde", 0, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 0, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 1, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos);
+    test(S("abcde"), "", 1, 0, 1);
+    test(S("abcde"), "abcde", 1, 0, 1);
+    test(S("abcde"), "abcde", 1, 1, 0);
+    test(S("abcde"), "abcde", 1, 2, 0);
+    test(S("abcde"), "abcde", 1, 4, 0);
+    test(S("abcde"), "abcde", 1, 5, 0);
+    test(S("abcde"), "abcdeabcde", 1, 0, 1);
+    test(S("abcde"), "abcdeabcde", 1, 1, 0);
+    test(S("abcde"), "abcdeabcde", 1, 5, 0);
+    test(S("abcde"), "abcdeabcde", 1, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 1, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 0, 1);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 1, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos);
+    test(S("abcde"), "", 2, 0, 2);
+    test(S("abcde"), "abcde", 2, 0, 2);
+    test(S("abcde"), "abcde", 2, 1, 0);
+    test(S("abcde"), "abcde", 2, 2, 0);
+    test(S("abcde"), "abcde", 2, 4, 0);
+    test(S("abcde"), "abcde", 2, 5, 0);
+    test(S("abcde"), "abcdeabcde", 2, 0, 2);
+    test(S("abcde"), "abcdeabcde", 2, 1, 0);
+    test(S("abcde"), "abcdeabcde", 2, 5, 0);
+    test(S("abcde"), "abcdeabcde", 2, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 2, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 0, 2);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 1, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 2, 20, S::npos);
+    test(S("abcde"), "", 4, 0, 4);
+    test(S("abcde"), "abcde", 4, 0, 4);
+    test(S("abcde"), "abcde", 4, 1, 0);
+    test(S("abcde"), "abcde", 4, 2, 0);
+    test(S("abcde"), "abcde", 4, 4, 0);
+    test(S("abcde"), "abcde", 4, 5, 0);
+    test(S("abcde"), "abcdeabcde", 4, 0, 4);
+    test(S("abcde"), "abcdeabcde", 4, 1, 0);
+    test(S("abcde"), "abcdeabcde", 4, 5, 0);
+    test(S("abcde"), "abcdeabcde", 4, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 4, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 0, 4);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 1, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 4, 20, S::npos);
+    test(S("abcde"), "", 5, 0, 5);
+    test(S("abcde"), "abcde", 5, 0, 5);
+    test(S("abcde"), "abcde", 5, 1, 0);
+    test(S("abcde"), "abcde", 5, 2, 0);
+}
+
+template <class S>
+void test1()
+{
+    test(S("abcde"), "abcde", 5, 4, 0);
+    test(S("abcde"), "abcde", 5, 5, 0);
+    test(S("abcde"), "abcdeabcde", 5, 0, 5);
+    test(S("abcde"), "abcdeabcde", 5, 1, 0);
+    test(S("abcde"), "abcdeabcde", 5, 5, 0);
+    test(S("abcde"), "abcdeabcde", 5, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 5, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 0, 5);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 1, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos);
+    test(S("abcde"), "", 6, 0, 5);
+    test(S("abcde"), "abcde", 6, 0, 5);
+    test(S("abcde"), "abcde", 6, 1, 0);
+    test(S("abcde"), "abcde", 6, 2, 0);
+    test(S("abcde"), "abcde", 6, 4, 0);
+    test(S("abcde"), "abcde", 6, 5, 0);
+    test(S("abcde"), "abcdeabcde", 6, 0, 5);
+    test(S("abcde"), "abcdeabcde", 6, 1, 0);
+    test(S("abcde"), "abcdeabcde", 6, 5, 0);
+    test(S("abcde"), "abcdeabcde", 6, 9, S::npos);
+    test(S("abcde"), "abcdeabcde", 6, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 0, 5);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 1, 0);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 10, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 19, S::npos);
+    test(S("abcde"), "abcdeabcdeabcdeabcde", 6, 20, S::npos);
+    test(S("abcdeabcde"), "", 0, 0, 0);
+    test(S("abcdeabcde"), "abcde", 0, 0, 0);
+    test(S("abcdeabcde"), "abcde", 0, 1, 0);
+    test(S("abcdeabcde"), "abcde", 0, 2, 0);
+    test(S("abcdeabcde"), "abcde", 0, 4, 0);
+    test(S("abcdeabcde"), "abcde", 0, 5, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 0, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 1, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 5, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 9, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 0, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, S::npos);
+    test(S("abcdeabcde"), "", 1, 0, 1);
+    test(S("abcdeabcde"), "abcde", 1, 0, 1);
+    test(S("abcdeabcde"), "abcde", 1, 1, 0);
+    test(S("abcdeabcde"), "abcde", 1, 2, 0);
+    test(S("abcdeabcde"), "abcde", 1, 4, 0);
+    test(S("abcdeabcde"), "abcde", 1, 5, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 0, 1);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 1, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 5, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 9, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 1, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, S::npos);
+    test(S("abcdeabcde"), "", 5, 0, 5);
+    test(S("abcdeabcde"), "abcde", 5, 0, 5);
+    test(S("abcdeabcde"), "abcde", 5, 1, 5);
+    test(S("abcdeabcde"), "abcde", 5, 2, 5);
+    test(S("abcdeabcde"), "abcde", 5, 4, 5);
+    test(S("abcdeabcde"), "abcde", 5, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 0, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 9, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 5, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 0, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 5, 20, S::npos);
+    test(S("abcdeabcde"), "", 9, 0, 9);
+    test(S("abcdeabcde"), "abcde", 9, 0, 9);
+    test(S("abcdeabcde"), "abcde", 9, 1, 5);
+    test(S("abcdeabcde"), "abcde", 9, 2, 5);
+    test(S("abcdeabcde"), "abcde", 9, 4, 5);
+    test(S("abcdeabcde"), "abcde", 9, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 0, 9);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 9, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 9, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 0, 9);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 9, 20, S::npos);
+    test(S("abcdeabcde"), "", 10, 0, 10);
+    test(S("abcdeabcde"), "abcde", 10, 0, 10);
+    test(S("abcdeabcde"), "abcde", 10, 1, 5);
+    test(S("abcdeabcde"), "abcde", 10, 2, 5);
+    test(S("abcdeabcde"), "abcde", 10, 4, 5);
+    test(S("abcdeabcde"), "abcde", 10, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 0, 10);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 1, 5);
+}
+
+template <class S>
+void test2()
+{
+    test(S("abcdeabcde"), "abcdeabcde", 10, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 9, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 10, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, S::npos);
+    test(S("abcdeabcde"), "", 11, 0, 10);
+    test(S("abcdeabcde"), "abcde", 11, 0, 10);
+    test(S("abcdeabcde"), "abcde", 11, 1, 5);
+    test(S("abcdeabcde"), "abcde", 11, 2, 5);
+    test(S("abcdeabcde"), "abcde", 11, 4, 5);
+    test(S("abcdeabcde"), "abcde", 11, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 0, 10);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 5, 5);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 9, 0);
+    test(S("abcdeabcde"), "abcdeabcde", 11, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 0, 10);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 1, 5);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 10, 0);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 19, S::npos);
+    test(S("abcdeabcde"), "abcdeabcdeabcdeabcde", 11, 20, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), "", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 2, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 4, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 0, 5, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 5, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 9, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 0, 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 0, 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 2, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 4, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 1, 5, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 5, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 9, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 1, 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 0, 1);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 1, 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 1, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 2, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 4, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 10, 5, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 1, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 5, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 9, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 10, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 0, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 1, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 10, 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 2, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 4, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 19, 5, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 5, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 9, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 19, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 0, 19);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 19, 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 20, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 2, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 4, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 20, 5, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 5, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 9, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 20, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 0, 20);
+}
+
+template <class S>
+void test3()
+{
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 20, 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), "", 21, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 2, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 4, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcde", 21, 5, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 5, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 9, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcde", 21, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 0, 20);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 1, 15);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), "abcdeabcdeabcdeabcde", 21, 20, 0);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    test2<S>();
+    test3<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.rfind( "",      0, 0 ) == 0, "" );
+    static_assert (sv1.rfind( "abcde", 0, 0 ) == 0, "" );
+    static_assert (sv1.rfind( "abcde", 0, 1 ) == SV::npos, "" );
+    static_assert (sv2.rfind( "",      0, 0 ) == 0, "" );
+    static_assert (sv2.rfind( "abcde", 0, 0 ) == 0, "" );
+    static_assert (sv2.rfind( "abcde", 0, 1 ) == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.find/rfind_string_view_size.pass.cpp b/test/experimental/string.view/string.view.find/rfind_string_view_size.pass.cpp
new file mode 100644
index 0000000..88457c6
--- /dev/null
+++ b/test/experimental/string.view/string.view.find/rfind_string_view_size.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr size_type rfind(const basic_string& str, size_type pos = npos) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x)
+{
+    assert(s.rfind(str, pos) == x);
+    if (x != S::npos)
+        assert(x <= pos && x + str.size() <= s.size());
+}
+
+template <class S>
+void
+test(const S& s, const S& str, typename S::size_type x)
+{
+    assert(s.rfind(str) == x);
+    if (x != S::npos)
+        assert(0 <= x && x + str.size() <= s.size());
+}
+
+template <class S>
+void test0()
+{
+    test(S(""), S(""), 0, 0);
+    test(S(""), S("abcde"), 0, S::npos);
+    test(S(""), S("abcdeabcde"), 0, S::npos);
+    test(S(""), S("abcdeabcdeabcdeabcde"), 0, S::npos);
+    test(S(""), S(""), 1, 0);
+    test(S(""), S("abcde"), 1, S::npos);
+    test(S(""), S("abcdeabcde"), 1, S::npos);
+    test(S(""), S("abcdeabcdeabcdeabcde"), 1, S::npos);
+    test(S("abcde"), S(""), 0, 0);
+    test(S("abcde"), S("abcde"), 0, 0);
+    test(S("abcde"), S("abcdeabcde"), 0, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos);
+    test(S("abcde"), S(""), 1, 1);
+    test(S("abcde"), S("abcde"), 1, 0);
+    test(S("abcde"), S("abcdeabcde"), 1, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos);
+    test(S("abcde"), S(""), 2, 2);
+    test(S("abcde"), S("abcde"), 2, 0);
+    test(S("abcde"), S("abcdeabcde"), 2, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 2, S::npos);
+    test(S("abcde"), S(""), 4, 4);
+    test(S("abcde"), S("abcde"), 4, 0);
+    test(S("abcde"), S("abcdeabcde"), 4, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 4, S::npos);
+    test(S("abcde"), S(""), 5, 5);
+    test(S("abcde"), S("abcde"), 5, 0);
+    test(S("abcde"), S("abcdeabcde"), 5, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos);
+    test(S("abcde"), S(""), 6, 5);
+    test(S("abcde"), S("abcde"), 6, 0);
+    test(S("abcde"), S("abcdeabcde"), 6, S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), 6, S::npos);
+    test(S("abcdeabcde"), S(""), 0, 0);
+    test(S("abcdeabcde"), S("abcde"), 0, 0);
+    test(S("abcdeabcde"), S("abcdeabcde"), 0, 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, S::npos);
+    test(S("abcdeabcde"), S(""), 1, 1);
+    test(S("abcdeabcde"), S("abcde"), 1, 0);
+    test(S("abcdeabcde"), S("abcdeabcde"), 1, 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, S::npos);
+    test(S("abcdeabcde"), S(""), 5, 5);
+    test(S("abcdeabcde"), S("abcde"), 5, 5);
+    test(S("abcdeabcde"), S("abcdeabcde"), 5, 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 5, S::npos);
+    test(S("abcdeabcde"), S(""), 9, 9);
+    test(S("abcdeabcde"), S("abcde"), 9, 5);
+    test(S("abcdeabcde"), S("abcdeabcde"), 9, 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 9, S::npos);
+    test(S("abcdeabcde"), S(""), 10, 10);
+    test(S("abcdeabcde"), S("abcde"), 10, 5);
+    test(S("abcdeabcde"), S("abcdeabcde"), 10, 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, S::npos);
+    test(S("abcdeabcde"), S(""), 11, 10);
+    test(S("abcdeabcde"), S("abcde"), 11, 5);
+    test(S("abcdeabcde"), S("abcdeabcde"), 11, 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), 11, S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0, 0);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 1, 1);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 1, 0);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 10, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 10, 0);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 19, 19);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 19, 15);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 19, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 19, 0);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 20, 20);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 20, 15);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 20, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 20, 0);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 21, 20);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 21, 15);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 21, 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 21, 0);
+}
+
+template <class S>
+void test1()
+{
+    test(S(""), S(""), 0);
+    test(S(""), S("abcde"), S::npos);
+    test(S(""), S("abcdeabcde"), S::npos);
+    test(S(""), S("abcdeabcdeabcdeabcde"), S::npos);
+    test(S("abcde"), S(""), 5);
+    test(S("abcde"), S("abcde"), 0);
+    test(S("abcde"), S("abcdeabcde"), S::npos);
+    test(S("abcde"), S("abcdeabcdeabcdeabcde"), S::npos);
+    test(S("abcdeabcde"), S(""), 10);
+    test(S("abcdeabcde"), S("abcde"), 5);
+    test(S("abcdeabcde"), S("abcdeabcde"), 0);
+    test(S("abcdeabcde"), S("abcdeabcdeabcdeabcde"), S::npos);
+    test(S("abcdeabcdeabcdeabcde"), S(""), 20);
+    test(S("abcdeabcdeabcdeabcde"), S("abcde"), 15);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcde"), 10);
+    test(S("abcdeabcdeabcdeabcde"), S("abcdeabcdeabcdeabcde"), 0);
+}
+
+int main()
+{
+    {
+    typedef std::experimental::string_view S;
+    test0<S>();
+    test1<S>();
+    }
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+
+    static_assert (sv1.rfind(sv1) == 0, "" );
+    static_assert (sv1.rfind(sv2) == SV::npos, "" );
+    static_assert (sv2.rfind(sv1) == 5, "" );
+    static_assert (sv2.rfind(sv2) == 0, "" );
+    static_assert (sv2.rfind(sv2, 1) == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.hash/string_view.pass.cpp b/test/experimental/string.view/string.view.hash/string_view.pass.cpp
new file mode 100644
index 0000000..03e0db2
--- /dev/null
+++ b/test/experimental/string.view/string.view.hash/string_view.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// template <class T>
+// struct hash
+//     : public unary_function<T, size_t>
+// {
+//     size_t operator()(T val) const;
+// };
+
+// Not very portable
+
+#include <experimental/string_view>
+#include <cassert>
+#include <type_traits>
+
+using std::experimental::string_view;
+
+template <class T>
+void
+test()
+{
+    typedef std::hash<T> H;
+    static_assert((std::is_base_of<std::unary_function<T, std::size_t>,
+                                   H>::value), "");
+    H h;
+//     std::string g1 = "1234567890";
+//     std::string g2 = "1234567891";
+    typedef typename T::value_type char_type;
+    char_type g1 [ 10 ];
+    char_type g2 [ 10 ];
+    for ( int i = 0; i < 10; ++i )
+        g1[i] = g2[9-i] = '0' + i;
+    T s1(g1, 10);
+    T s2(g2, 10);
+    assert(h(s1) != h(s2));
+}
+
+int main()
+{
+    test<std::experimental::string_view>();
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+    test<std::experimental::u16string_view>();
+    test<std::experimental::u32string_view>();
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    test<std::experimental::wstring_view>();
+}
diff --git a/test/experimental/string.view/string.view.io/stream_insert.pass.cpp b/test/experimental/string.view/string.view.io/stream_insert.pass.cpp
new file mode 100644
index 0000000..4f3f962
--- /dev/null
+++ b/test/experimental/string.view/string.view.io/stream_insert.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// template<class charT, class traits, class Allocator>
+//   basic_ostream<charT, traits>&
+//   operator<<(basic_ostream<charT, traits>& os,
+//              const basic_string_view<charT,traits> str);
+
+#include <experimental/string_view>
+#include <sstream>
+#include <cassert>
+
+using std::experimental::string_view;
+using std::experimental::wstring_view;
+
+int main()
+{
+    {
+        std::ostringstream out;
+        string_view sv("some text");
+        out << sv;
+        assert(out.good());
+        assert(sv == out.str());
+    }
+    {
+        std::ostringstream out;
+        std::string s("some text");
+        string_view sv(s);
+        out.width(12);
+        out << sv;
+        assert(out.good());
+        assert("   " + s == out.str());
+    }
+    {
+        std::wostringstream out;
+        wstring_view sv(L"some text");
+        out << sv;
+        assert(out.good());
+        assert(sv == out.str());
+    }
+    {
+        std::wostringstream out;
+        std::wstring s(L"some text");
+        wstring_view sv(s);
+        out.width(12);
+        out << sv;
+        assert(out.good());
+        assert(L"   " + s == out.str());
+    }
+}
diff --git a/test/experimental/string.view/string.view.iterators/begin.pass.cpp b/test/experimental/string.view/string.view.iterators/begin.pass.cpp
new file mode 100644
index 0000000..07f3b36
--- /dev/null
+++ b/test/experimental/string.view/string.view.iterators/begin.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr const_iterator begin() const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(S s)
+{
+    const S& cs = s;
+    typename S::iterator b = s.begin();
+    typename S::const_iterator cb1 = cs.begin();
+    typename S::const_iterator cb2 = s.cbegin();
+    if (!s.empty())
+    {
+        assert(   *b ==  s[0]);
+        assert(  &*b == &s[0]);
+        assert( *cb1 ==  s[0]);
+        assert(&*cb1 == &s[0]);
+        assert( *cb2 ==  s[0]);
+        assert(&*cb2 == &s[0]);
+        
+    }
+    assert(  b == cb1);
+    assert(  b == cb2);
+    assert(cb1 == cb2);
+}
+
+
+int main()
+{
+    typedef std::experimental::string_view    string_view;
+    typedef std::experimental::u16string_view u16string_view;
+    typedef std::experimental::u32string_view u32string_view;
+    typedef std::experimental::wstring_view   wstring_view;
+
+    test(string_view   ());
+    test(u16string_view());
+    test(u32string_view());
+    test(wstring_view  ());
+    test(string_view   ( "123"));
+    test(wstring_view  (L"123"));
+#if __cplusplus >= 201103L
+    test(u16string_view{u"123"});
+    test(u32string_view{U"123"});
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr string_view       sv { "123", 3 };
+    constexpr u16string_view u16sv {u"123", 3 };
+    constexpr u32string_view u32sv {U"123", 3 };
+    constexpr wstring_view     wsv {L"123", 3 };
+    
+    static_assert (    *sv.begin() ==    sv[0], "" );
+    static_assert ( *u16sv.begin() == u16sv[0], "" );
+    static_assert ( *u32sv.begin() == u32sv[0], "" );
+    static_assert (   *wsv.begin() ==   wsv[0], "" );
+
+    static_assert (    *sv.cbegin() ==    sv[0], "" );
+    static_assert ( *u16sv.cbegin() == u16sv[0], "" );
+    static_assert ( *u32sv.cbegin() == u32sv[0], "" );
+    static_assert (   *wsv.cbegin() ==   wsv[0], "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.iterators/end.pass.cpp b/test/experimental/string.view/string.view.iterators/end.pass.cpp
new file mode 100644
index 0000000..2ed52b8
--- /dev/null
+++ b/test/experimental/string.view/string.view.iterators/end.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr const_iterator end() const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(S s)
+{
+    const S& cs = s;
+    typename S::iterator e = s.end();
+    typename S::const_iterator ce1 = cs.end();
+    typename S::const_iterator ce2 = s.cend();
+
+    if (s.empty())
+    {
+        assert(  e ==  s.begin());
+        assert(ce1 == cs.begin());
+        assert(ce2 ==  s.begin());
+    }
+    else
+    {
+        assert(  e !=  s.begin());
+        assert(ce1 != cs.begin());
+        assert(ce2 !=  s.begin());
+    }
+    
+    assert(  e -  s.begin() == s.size());
+    assert(ce1 - cs.begin() == cs.size());
+    assert(ce2 - s.cbegin() == s.size());
+
+    assert(  e == ce1);
+    assert(  e == ce2);
+    assert(ce1 == ce2);
+}
+
+
+int main()
+{
+    typedef std::experimental::string_view    string_view;
+    typedef std::experimental::u16string_view u16string_view;
+    typedef std::experimental::u32string_view u32string_view;
+    typedef std::experimental::wstring_view   wstring_view;
+
+    test(string_view   ());
+    test(u16string_view());
+    test(u32string_view());
+    test(wstring_view  ());
+    test(string_view   ( "123"));
+    test(wstring_view  (L"123"));
+#if __cplusplus >= 201103L
+    test(u16string_view{u"123"});
+    test(u32string_view{U"123"});
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr string_view       sv { "123", 3 };
+    constexpr u16string_view u16sv {u"123", 3 };
+    constexpr u32string_view u32sv {U"123", 3 };
+    constexpr wstring_view     wsv {L"123", 3 };
+    
+    static_assert (    sv.begin() !=    sv.end(), "" );
+    static_assert ( u16sv.begin() != u16sv.end(), "" );
+    static_assert ( u32sv.begin() != u32sv.end(), "" );
+    static_assert (   wsv.begin() !=   wsv.end(), "" );
+
+    static_assert (    sv.begin() !=    sv.cend(), "" );
+    static_assert ( u16sv.begin() != u16sv.cend(), "" );
+    static_assert ( u32sv.begin() != u32sv.cend(), "" );
+    static_assert (   wsv.begin() !=   wsv.cend(), "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.iterators/rbegin.pass.cpp b/test/experimental/string.view/string.view.iterators/rbegin.pass.cpp
new file mode 100644
index 0000000..7d1c700
--- /dev/null
+++ b/test/experimental/string.view/string.view.iterators/rbegin.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// const_iterator rbegin() const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(S s)
+{
+    const S& cs = s;
+    typename S::reverse_iterator b = s.rbegin();
+    typename S::const_reverse_iterator cb1 = cs.rbegin();
+    typename S::const_reverse_iterator cb2 = s.crbegin();
+    if (!s.empty())
+    {
+        const size_t last = s.size() - 1;
+        assert(   *b ==  s[last]);
+        assert(  &*b == &s[last]);
+        assert( *cb1 ==  s[last]);
+        assert(&*cb1 == &s[last]);
+        assert( *cb2 ==  s[last]);
+        assert(&*cb2 == &s[last]);
+        
+    }
+    assert(  b == cb1);
+    assert(  b == cb2);
+    assert(cb1 == cb2);
+}
+
+
+int main()
+{
+    typedef std::experimental::string_view    string_view;
+    typedef std::experimental::u16string_view u16string_view;
+    typedef std::experimental::u32string_view u32string_view;
+    typedef std::experimental::wstring_view   wstring_view;
+
+    test(string_view   ());
+    test(u16string_view());
+    test(u32string_view());
+    test(wstring_view  ());
+    test(string_view   ( "123"));
+    test(wstring_view  (L"123"));
+#if __cplusplus >= 201103L
+    test(u16string_view{u"123"});
+    test(u32string_view{U"123"});
+#endif
+}
diff --git a/test/experimental/string.view/string.view.iterators/rend.pass.cpp b/test/experimental/string.view/string.view.iterators/rend.pass.cpp
new file mode 100644
index 0000000..57002f3
--- /dev/null
+++ b/test/experimental/string.view/string.view.iterators/rend.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr const_iterator rend() const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+template <class S>
+void
+test(S s)
+{
+    const S& cs = s;
+    typename S::reverse_iterator e = s.rend();
+    typename S::const_reverse_iterator ce1 = cs.rend();
+    typename S::const_reverse_iterator ce2 = s.crend();
+
+    if (s.empty())
+    {
+        assert(  e ==  s.rbegin());
+        assert(ce1 == cs.rbegin());
+        assert(ce2 ==  s.rbegin());
+    }
+    else
+    {
+        assert(  e !=  s.rbegin());
+        assert(ce1 != cs.rbegin());
+        assert(ce2 !=  s.rbegin());
+    }
+    
+    assert(  e -  s.rbegin() == s.size());
+    assert(ce1 - cs.rbegin() == cs.size());
+    assert(ce2 - s.crbegin() == s.size());
+
+    assert(  e == ce1);
+    assert(  e == ce2);
+    assert(ce1 == ce2);
+}
+
+
+int main()
+{
+    typedef std::experimental::string_view    string_view;
+    typedef std::experimental::u16string_view u16string_view;
+    typedef std::experimental::u32string_view u32string_view;
+    typedef std::experimental::wstring_view   wstring_view;
+    
+    test(string_view   ());
+    test(u16string_view());
+    test(u32string_view());
+    test(wstring_view  ());
+    test(string_view   ( "123"));
+    test(wstring_view  (L"123"));
+#if __cplusplus >= 201103L
+    test(u16string_view{u"123"});
+    test(u32string_view{U"123"});
+#endif
+}
diff --git a/test/experimental/string.view/string.view.modifiers/clear.pass.cpp b/test/experimental/string.view/string.view.modifiers/clear.pass.cpp
new file mode 100644
index 0000000..6a9982e
--- /dev/null
+++ b/test/experimental/string.view/string.view.modifiers/clear.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// void clear() noexcept
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename CharT>
+void test ( const CharT *s, size_t len ) {
+    typedef std::experimental::basic_string_view<CharT> SV;
+    {
+    SV sv1 ( s );
+    assert ( sv1.size() == len );
+    assert ( sv1.data() == s );
+
+    sv1.clear ();
+    assert ( sv1.data() == nullptr );
+    assert ( sv1.size() == 0 );
+    assert ( sv1 == SV());
+    }
+}
+
+#if _LIBCPP_STD_VER > 11
+constexpr size_t test_ce ( size_t n ) {
+    typedef std::experimental::basic_string_view<char> SV;
+    SV sv1{ "ABCDEFGHIJKL", n };
+    sv1.clear();
+    return sv1.size();
+}
+#endif
+
+int main () {
+    test ( "ABCDE", 5 );
+    test ( "a", 1 );
+    test ( "", 0 );
+
+    test ( L"ABCDE", 5 );
+    test ( L"a", 1 );
+    test ( L"", 0 );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDE", 5 );
+    test ( u"a", 1 );
+    test ( u"", 0 );
+
+    test ( U"ABCDE", 5 );
+    test ( U"a", 1 );
+    test ( U"", 0 );
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    static_assert ( test_ce (5) == 0, "" );
+#endif
+
+}
diff --git a/test/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp b/test/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp
new file mode 100644
index 0000000..0a2dd6d
--- /dev/null
+++ b/test/experimental/string.view/string.view.modifiers/remove_prefix.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// void remove_prefix(size_type _n)
+
+#include <experimental/string_view>
+#include <cassert>
+#include <iostream>
+
+template<typename CharT>
+void test ( const CharT *s, size_t len ) {
+    typedef std::experimental::basic_string_view<CharT> SV;
+    {
+    SV sv1 ( s );
+    assert ( sv1.size() == len );
+    assert ( sv1.data() == s );
+
+    if ( len > 0 ) {
+        sv1.remove_prefix ( 1 );
+        assert ( sv1.size() == (len - 1));
+        assert ( sv1.data() == (s + 1));
+        sv1.remove_prefix ( len - 1 );
+    }
+    
+    assert ( sv1.size() == 0 );
+    sv1.remove_prefix ( 0 );
+    assert ( sv1.size() == 0 ); 
+    }
+}
+
+#if _LIBCPP_STD_VER > 11
+constexpr size_t test_ce ( size_t n, size_t k ) {
+    typedef std::experimental::basic_string_view<char> SV;
+    SV sv1{ "ABCDEFGHIJKL", n };
+    sv1.remove_prefix ( k );
+    return sv1.size();
+}
+#endif
+
+int main () {
+    test ( "ABCDE", 5 );
+    test ( "a", 1 );
+    test ( "", 0 );
+
+    test ( L"ABCDE", 5 );
+    test ( L"a", 1 );
+    test ( L"", 0 );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDE", 5 );
+    test ( u"a", 1 );
+    test ( u"", 0 );
+
+    test ( U"ABCDE", 5 );
+    test ( U"a", 1 );
+    test ( U"", 0 );
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert ( test_ce ( 5, 0 ) == 5, "" );
+    static_assert ( test_ce ( 5, 1 ) == 4, "" );
+    static_assert ( test_ce ( 5, 5 ) == 0, "" );
+    static_assert ( test_ce ( 9, 3 ) == 6, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp b/test/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp
new file mode 100644
index 0000000..9dd5988
--- /dev/null
+++ b/test/experimental/string.view/string.view.modifiers/remove_suffix.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// void remove_suffix(size_type _n)
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename CharT>
+void test ( const CharT *s, size_t len ) {
+    typedef std::experimental::basic_string_view<CharT> SV;
+    {
+    SV sv1 ( s );
+    assert ( sv1.size() == len );
+    assert ( sv1.data() == s );
+
+    if ( len > 0 ) {
+        sv1.remove_suffix ( 1 );
+        assert ( sv1.size() == (len - 1));
+        assert ( sv1.data() == s);
+        sv1.remove_suffix ( len - 1 );
+        }
+        
+    assert ( sv1.size() == 0 );
+    sv1.remove_suffix ( 0 );
+    assert ( sv1.size() == 0 ); 
+    }
+
+}
+
+#if _LIBCPP_STD_VER > 11
+constexpr size_t test_ce ( size_t n, size_t k ) {
+    typedef std::experimental::basic_string_view<char> SV;
+    SV sv1{ "ABCDEFGHIJKL", n };
+    sv1.remove_suffix ( k );
+    return sv1.size();
+}
+#endif
+
+int main () {
+    test ( "ABCDE", 5 );
+    test ( "a", 1 );
+    test ( "", 0 );
+
+    test ( L"ABCDE", 5 );
+    test ( L"a", 1 );
+    test ( L"", 0 );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDE", 5 );
+    test ( u"a", 1 );
+    test ( u"", 0 );
+
+    test ( U"ABCDE", 5 );
+    test ( U"a", 1 );
+    test ( U"", 0 );
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert ( test_ce ( 5, 0 ) == 5, "" );
+    static_assert ( test_ce ( 5, 1 ) == 4, "" );
+    static_assert ( test_ce ( 5, 5 ) == 0, "" );
+    static_assert ( test_ce ( 9, 3 ) == 6, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.modifiers/swap.pass.cpp b/test/experimental/string.view/string.view.modifiers/swap.pass.cpp
new file mode 100644
index 0000000..cacb8ed
--- /dev/null
+++ b/test/experimental/string.view/string.view.modifiers/swap.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// void swap(basic_string_view& _other) noexcept
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename CharT>
+void test ( const CharT *s, size_t len ) {
+    typedef std::experimental::basic_string_view<CharT> SV;
+    {
+    SV sv1(s);
+    SV sv2;
+    
+    assert ( sv1.size() == len );
+    assert ( sv1.data() == s );
+    assert ( sv2.size() == 0 );
+
+    sv1.swap ( sv2 );
+    assert ( sv1.size() == 0 );
+    assert ( sv2.size() == len );
+    assert ( sv2.data() == s );
+    }
+
+}
+
+#if _LIBCPP_STD_VER > 11
+constexpr size_t test_ce ( size_t n, size_t k ) {
+    typedef std::experimental::basic_string_view<char> SV;
+    SV sv1{ "ABCDEFGHIJKL", n };
+    SV sv2 { sv1.data(), k };
+    sv1.swap ( sv2 );
+    return sv1.size();
+}
+#endif
+
+
+int main () {
+    test ( "ABCDE", 5 );
+    test ( "a", 1 );
+    test ( "", 0 );
+
+    test ( L"ABCDE", 5 );
+    test ( L"a", 1 );
+    test ( L"", 0 );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDE", 5 );
+    test ( u"a", 1 );
+    test ( u"", 0 );
+
+    test ( U"ABCDE", 5 );
+    test ( U"a", 1 );
+    test ( U"", 0 );
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    static_assert ( test_ce (2, 3) == 3, "" );
+    static_assert ( test_ce (5, 3) == 3, "" );
+    static_assert ( test_ce (0, 1) == 1, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.nonmem/quoted.pass.cpp b/test/experimental/string.view/string.view.nonmem/quoted.pass.cpp
new file mode 100644
index 0000000..c86e961
--- /dev/null
+++ b/test/experimental/string.view/string.view.nonmem/quoted.pass.cpp
@@ -0,0 +1,212 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <iomanip>
+
+// quoted
+
+#include <iomanip>
+#include <sstream>
+#include <experimental/string_view>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+// quoted is C++14 only
+
+bool is_skipws ( const std::istream *is ) {
+    return ( is->flags() & std::ios_base::skipws ) != 0;
+    }
+
+
+bool is_skipws ( const std::wistream *is ) {
+    return ( is->flags() & std::ios_base::skipws ) != 0;
+    }
+
+void round_trip ( const char *p ) {
+    std::stringstream ss;
+    bool skippingws = is_skipws ( &ss );
+    std::experimental::string_view sv {p};
+
+    ss << std::quoted(sv);
+    std::string s;
+    ss >> std::quoted(s);
+    assert ( s == sv );
+    assert ( skippingws == is_skipws ( &ss ));
+    }
+
+void round_trip_ws ( const char *p ) {
+    std::stringstream ss;
+    std::noskipws ( ss );
+    bool skippingws = is_skipws ( &ss );
+    std::experimental::string_view sv {p};
+
+    ss << std::quoted(sv);
+    std::string s;
+    ss >> std::quoted(s);
+    assert ( s == sv );
+    assert ( skippingws == is_skipws ( &ss ));
+    }
+
+void round_trip_d ( const char *p, char delim ) {
+    std::stringstream ss;
+    std::experimental::string_view sv {p};
+
+    ss << std::quoted(sv, delim);
+    std::string s;
+    ss >> std::quoted(s, delim);
+    assert ( s == sv );
+    }
+
+void round_trip_e ( const char *p, char escape ) {
+    std::stringstream ss;
+    std::experimental::string_view sv {p};
+
+    ss << std::quoted(sv, '"', escape );
+    std::string s;
+    ss >> std::quoted(s, '"', escape );
+    assert ( s == sv );
+    }
+
+
+
+std::string quote ( const char *p, char delim='"', char escape='\\' ) {
+    std::stringstream ss;
+    ss << std::quoted(p, delim, escape);
+    std::string s;
+    ss >> s;    // no quote
+    return s;
+}
+
+std::string unquote ( const char *p, char delim='"', char escape='\\' ) {
+    std::stringstream ss;
+    ss << p;
+    std::string s;
+    ss >> std::quoted(s, delim, escape);
+    return s;
+}
+
+
+void round_trip ( const wchar_t *p ) {
+    std::wstringstream ss;
+    bool skippingws = is_skipws ( &ss );
+    std::experimental::wstring_view sv {p};
+
+    ss << std::quoted(sv);
+    std::wstring s;
+    ss >> std::quoted(s);
+    assert ( s == sv );
+    assert ( skippingws == is_skipws ( &ss ));
+    }
+    
+
+void round_trip_ws ( const wchar_t *p ) {
+    std::wstringstream ss;
+    std::noskipws ( ss );
+    bool skippingws = is_skipws ( &ss );
+    std::experimental::wstring_view sv {p};
+
+    ss << std::quoted(sv);
+    std::wstring s;
+    ss >> std::quoted(s);
+    assert ( s == sv );
+    assert ( skippingws == is_skipws ( &ss ));
+    }
+
+void round_trip_d ( const wchar_t *p, wchar_t delim ) {
+    std::wstringstream ss;
+    std::experimental::wstring_view sv {p};
+
+    ss << std::quoted(sv, delim);
+    std::wstring s;
+    ss >> std::quoted(s, delim);
+    assert ( s == sv );
+    }
+
+void round_trip_e ( const wchar_t *p, wchar_t escape ) {
+    std::wstringstream ss;
+    std::experimental::wstring_view sv {p};
+
+    ss << std::quoted(sv, wchar_t('"'), escape );
+    std::wstring s;
+    ss >> std::quoted(s, wchar_t('"'), escape );
+    assert ( s == sv );
+    }
+
+
+std::wstring quote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
+    std::wstringstream ss;
+    std::experimental::wstring_view sv {p};
+
+    ss << std::quoted(sv, delim, escape);
+    std::wstring s;
+    ss >> s;    // no quote
+    return s;
+}
+
+std::wstring unquote ( const wchar_t *p, wchar_t delim='"', wchar_t escape='\\' ) {
+    std::wstringstream ss;
+    std::experimental::wstring_view sv {p};
+
+    ss << sv;
+    std::wstring s;
+    ss >> std::quoted(s, delim, escape);
+    return s;
+}
+
+int main()
+{
+    round_trip    (  "" );
+    round_trip_ws (  "" );
+    round_trip_d  (  "", 'q' );
+    round_trip_e  (  "", 'q' );
+    
+    round_trip    ( L"" );
+    round_trip_ws ( L"" );
+    round_trip_d  ( L"", 'q' );
+    round_trip_e  ( L"", 'q' );
+    
+    round_trip    (  "Hi" );
+    round_trip_ws (  "Hi" );
+    round_trip_d  (  "Hi", '!' );
+    round_trip_e  (  "Hi", '!' );
+    assert ( quote ( "Hi", '!' ) == "!Hi!" );
+    assert ( quote ( "Hi!", '!' ) == R"(!Hi\!!)" );
+    
+    round_trip    ( L"Hi" );
+    round_trip_ws ( L"Hi" );
+    round_trip_d  ( L"Hi", '!' );
+    round_trip_e  ( L"Hi", '!' );
+    assert ( quote ( L"Hi", '!' )  == L"!Hi!" );
+    assert ( quote ( L"Hi!", '!' ) == LR"(!Hi\!!)" );
+    
+    round_trip    (  "Hi Mom" );
+    round_trip_ws (  "Hi Mom" );
+    round_trip    ( L"Hi Mom" );
+    round_trip_ws ( L"Hi Mom" );
+    
+    assert ( quote (  "" )  ==  "\"\"" );
+    assert ( quote ( L"" )  == L"\"\"" );
+    assert ( quote (  "a" ) ==  "\"a\"" );
+    assert ( quote ( L"a" ) == L"\"a\"" );
+
+//  missing end quote - must not hang
+    assert ( unquote (  "\"abc" ) ==  "abc" );
+    assert ( unquote ( L"\"abc" ) == L"abc" );
+    
+    assert ( unquote (  "abc" ) == "abc" ); // no delimiter
+    assert ( unquote ( L"abc" ) == L"abc" ); // no delimiter
+    assert ( unquote (  "abc def" ) ==  "abc" ); // no delimiter
+    assert ( unquote ( L"abc def" ) == L"abc" ); // no delimiter
+
+    assert ( unquote (  "" ) ==  "" ); // nothing there
+    assert ( unquote ( L"" ) == L"" ); // nothing there
+    }
+#else
+int main() {}
+#endif
diff --git a/test/experimental/string.view/string.view.ops/basic_string.pass.cpp b/test/experimental/string.view/string.view.ops/basic_string.pass.cpp
new file mode 100644
index 0000000..64000d6
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/basic_string.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// template<class _Allocator>
+// explicit operator basic_string<_CharT, _Traits, _Allocator>() const
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename CharT>
+void test ( const CharT *s ) {
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    typedef std::basic_string<CharT> string_t;
+    
+    {
+    string_view_t sv1 ( s );
+    string_t      str = (string_t) sv1;
+
+    assert ( sv1.size() == str.size ());
+    assert ( std::char_traits<CharT>::compare ( sv1.data(), str.data(), sv1.size()) == 0 );
+    }
+
+    {
+    string_view_t sv1;
+    string_t      str = (string_t) sv1;
+
+    assert ( sv1.size() == str.size ());
+    assert ( std::char_traits<CharT>::compare ( sv1.data(), str.data(), sv1.size()) == 0 );
+    }
+}
+
+int main () {
+    test ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( "ABCDE");
+    test ( "a" );
+    test ( "" );
+
+    test ( L"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( L"ABCDE" );
+    test ( L"a" );
+    test ( L"" );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( u"ABCDE" );
+    test ( u"a" );
+    test ( u"" );
+
+    test ( U"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( U"ABCDE" );
+    test ( U"a" );
+    test ( U"" );
+#endif
+}
diff --git a/test/experimental/string.view/string.view.ops/compare.pointer.pass.cpp b/test/experimental/string.view/string.view.ops/compare.pointer.pass.cpp
new file mode 100644
index 0000000..6ccec9b
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/compare.pointer.pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr int compare(const charT* s) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); }
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv1, const CharT *s, int expected ) {
+    assert ( sign( sv1.compare(s)) == sign(expected));
+}
+
+template<typename CharT>
+void
+test( const CharT *s1, const CharT *s2, int expected)
+{
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    string_view_t sv1 ( s1 );
+    test1 ( sv1, s2, expected );
+}
+
+int main()
+{
+    {
+    test("", "", 0);
+    test("", "abcde", -5);
+    test("", "abcdefghij", -10);
+    test("", "abcdefghijklmnopqrst", -20);
+    test("abcde", "", 5);
+    test("abcde", "abcde", 0);
+    test("abcde", "abcdefghij", -5);
+    test("abcde", "abcdefghijklmnopqrst", -15);
+    test("abcdefghij", "", 10);
+    test("abcdefghij", "abcde", 5);
+    test("abcdefghij", "abcdefghij", 0);
+    test("abcdefghij", "abcdefghijklmnopqrst", -10);
+    test("abcdefghijklmnopqrst", "", 20);
+    test("abcdefghijklmnopqrst", "abcde", 15);
+    test("abcdefghijklmnopqrst", "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", "abcdefghijklmnopqrst", 0);
+    }
+
+    {
+    test(L"", L"", 0);
+    test(L"", L"abcde", -5);
+    test(L"", L"abcdefghij", -10);
+    test(L"", L"abcdefghijklmnopqrst", -20);
+    test(L"abcde", L"", 5);
+    test(L"abcde", L"abcde", 0);
+    test(L"abcde", L"abcdefghij", -5);
+    test(L"abcde", L"abcdefghijklmnopqrst", -15);
+    test(L"abcdefghij", L"", 10);
+    test(L"abcdefghij", L"abcde", 5);
+    test(L"abcdefghij", L"abcdefghij", 0);
+    test(L"abcdefghij", L"abcdefghijklmnopqrst", -10);
+    test(L"abcdefghijklmnopqrst", L"", 20);
+    test(L"abcdefghijklmnopqrst", L"abcde", 15);
+    test(L"abcdefghijklmnopqrst", L"abcdefghij", 10);
+    test(L"abcdefghijklmnopqrst", L"abcdefghijklmnopqrst", 0);
+    }
+
+#if __cplusplus >= 201103L
+    {
+    test(U"", U"", 0);
+    test(U"", U"abcde", -5);
+    test(U"", U"abcdefghij", -10);
+    test(U"", U"abcdefghijklmnopqrst", -20);
+    test(U"abcde", U"", 5);
+    test(U"abcde", U"abcde", 0);
+    test(U"abcde", U"abcdefghij", -5);
+    test(U"abcde", U"abcdefghijklmnopqrst", -15);
+    test(U"abcdefghij", U"", 10);
+    test(U"abcdefghij", U"abcde", 5);
+    test(U"abcdefghij", U"abcdefghij", 0);
+    test(U"abcdefghij", U"abcdefghijklmnopqrst", -10);
+    test(U"abcdefghijklmnopqrst", U"", 20);
+    test(U"abcdefghijklmnopqrst", U"abcde", 15);
+    test(U"abcdefghijklmnopqrst", U"abcdefghij", 10);
+    test(U"abcdefghijklmnopqrst", U"abcdefghijklmnopqrst", 0);
+    }
+
+    {
+    test(u"", u"", 0);
+    test(u"", u"abcde", -5);
+    test(u"", u"abcdefghij", -10);
+    test(u"", u"abcdefghijklmnopqrst", -20);
+    test(u"abcde", u"", 5);
+    test(u"abcde", u"abcde", 0);
+    test(u"abcde", u"abcdefghij", -5);
+    test(u"abcde", u"abcdefghijklmnopqrst", -15);
+    test(u"abcdefghij", u"", 10);
+    test(u"abcdefghij", u"abcde", 5);
+    test(u"abcdefghij", u"abcdefghij", 0);
+    test(u"abcdefghij", u"abcdefghijklmnopqrst", -10);
+    test(u"abcdefghijklmnopqrst", u"", 20);
+    test(u"abcdefghijklmnopqrst", u"abcde", 15);
+    test(u"abcdefghijklmnopqrst", u"abcdefghij", 10);
+    test(u"abcdefghijklmnopqrst", u"abcdefghijklmnopqrst", 0);
+    }
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+    static_assert ( sv1.compare("") == 0, "" );
+    static_assert ( sv1.compare("abcde") == -1, "" );
+    static_assert ( sv2.compare("") == 1, "" );
+    static_assert ( sv2.compare("abcde") == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp b/test/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp
new file mode 100644
index 0000000..6b20639
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/compare.pointer_size.pass.cpp
@@ -0,0 +1,444 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string_view>
+
+// constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); }
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv1, 
+             size_t pos1, size_t n1, const CharT *s, int expected ) {
+    try {
+        assert(sign(sv1.compare(pos1, n1, s)) == sign(expected));
+        assert(pos1 <= sv1.size());
+    }
+    catch (const std::out_of_range&) { assert(pos1 > sv1.size()); }
+}
+
+template<typename CharT>
+void
+test( const CharT *s1, size_t pos1, size_t n1, const CharT *s2, int expected)
+{
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    string_view_t sv1 ( s1 );
+    test1 ( sv1, pos1, n1, s2, expected );
+}
+
+void test0()
+{
+    test("", 0, 0, "", 0);
+    test("", 0, 0, "abcde", -5);
+    test("", 0, 0, "abcdefghij", -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("", 0, 1, "", 0);
+    test("", 0, 1, "abcde", -5);
+    test("", 0, 1, "abcdefghij", -10);
+    test("", 0, 1, "abcdefghijklmnopqrst", -20);
+    test("", 1, 0, "", 0);
+    test("", 1, 0, "abcde", 0);
+    test("", 1, 0, "abcdefghij", 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0);
+    test("abcde", 0, 0, "", 0);
+    test("abcde", 0, 0, "abcde", -5);
+    test("abcde", 0, 0, "abcdefghij", -10);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 0, 1, "", 1);
+    test("abcde", 0, 1, "abcde", -4);
+    test("abcde", 0, 1, "abcdefghij", -9);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", -19);
+    test("abcde", 0, 2, "", 2);
+    test("abcde", 0, 2, "abcde", -3);
+    test("abcde", 0, 2, "abcdefghij", -8);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", -18);
+    test("abcde", 0, 4, "", 4);
+    test("abcde", 0, 4, "abcde", -1);
+    test("abcde", 0, 4, "abcdefghij", -6);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", -16);
+    test("abcde", 0, 5, "", 5);
+    test("abcde", 0, 5, "abcde", 0);
+    test("abcde", 0, 5, "abcdefghij", -5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", -15);
+    test("abcde", 0, 6, "", 5);
+    test("abcde", 0, 6, "abcde", 0);
+    test("abcde", 0, 6, "abcdefghij", -5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", -15);
+    test("abcde", 1, 0, "", 0);
+    test("abcde", 1, 0, "abcde", -5);
+    test("abcde", 1, 0, "abcdefghij", -10);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 1, 1, "", 1);
+    test("abcde", 1, 1, "abcde", 1);
+    test("abcde", 1, 1, "abcdefghij", 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 2, "", 2);
+    test("abcde", 1, 2, "abcde", 1);
+    test("abcde", 1, 2, "abcdefghij", 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 3, "", 3);
+    test("abcde", 1, 3, "abcde", 1);
+    test("abcde", 1, 3, "abcdefghij", 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 4, "", 4);
+    test("abcde", 1, 4, "abcde", 1);
+    test("abcde", 1, 4, "abcdefghij", 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 5, "", 4);
+    test("abcde", 1, 5, "abcde", 1);
+    test("abcde", 1, 5, "abcdefghij", 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1);
+    test("abcde", 2, 0, "", 0);
+    test("abcde", 2, 0, "abcde", -5);
+    test("abcde", 2, 0, "abcdefghij", -10);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 2, 1, "", 1);
+    test("abcde", 2, 1, "abcde", 2);
+    test("abcde", 2, 1, "abcdefghij", 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 2);
+    test("abcde", 2, 2, "", 2);
+    test("abcde", 2, 2, "abcde", 2);
+    test("abcde", 2, 2, "abcdefghij", 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 2);
+    test("abcde", 2, 3, "", 3);
+    test("abcde", 2, 3, "abcde", 2);
+    test("abcde", 2, 3, "abcdefghij", 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 2);
+    test("abcde", 2, 4, "", 3);
+    test("abcde", 2, 4, "abcde", 2);
+    test("abcde", 2, 4, "abcdefghij", 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 2);
+    test("abcde", 4, 0, "", 0);
+    test("abcde", 4, 0, "abcde", -5);
+    test("abcde", 4, 0, "abcdefghij", -10);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 4, 1, "", 1);
+    test("abcde", 4, 1, "abcde", 4);
+    test("abcde", 4, 1, "abcdefghij", 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 4);
+    test("abcde", 4, 2, "", 1);
+    test("abcde", 4, 2, "abcde", 4);
+    test("abcde", 4, 2, "abcdefghij", 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 4);
+    test("abcde", 5, 0, "", 0);
+    test("abcde", 5, 0, "abcde", -5);
+    test("abcde", 5, 0, "abcdefghij", -10);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 5, 1, "", 0);
+    test("abcde", 5, 1, "abcde", -5);
+    test("abcde", 5, 1, "abcdefghij", -10);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", -20);
+}
+
+void test1()
+{
+    test("abcde", 6, 0, "", 0);
+    test("abcde", 6, 0, "abcde", 0);
+    test("abcde", 6, 0, "abcdefghij", 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0);
+    test("abcdefghij", 0, 0, "", 0);
+    test("abcdefghij", 0, 0, "abcde", -5);
+    test("abcdefghij", 0, 0, "abcdefghij", -10);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 0, 1, "", 1);
+    test("abcdefghij", 0, 1, "abcde", -4);
+    test("abcdefghij", 0, 1, "abcdefghij", -9);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", -19);
+    test("abcdefghij", 0, 5, "", 5);
+    test("abcdefghij", 0, 5, "abcde", 0);
+    test("abcdefghij", 0, 5, "abcdefghij", -5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", -15);
+    test("abcdefghij", 0, 9, "", 9);
+    test("abcdefghij", 0, 9, "abcde", 4);
+    test("abcdefghij", 0, 9, "abcdefghij", -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", -11);
+    test("abcdefghij", 0, 10, "", 10);
+    test("abcdefghij", 0, 10, "abcde", 5);
+    test("abcdefghij", 0, 10, "abcdefghij", 0);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", -10);
+    test("abcdefghij", 0, 11, "", 10);
+    test("abcdefghij", 0, 11, "abcde", 5);
+    test("abcdefghij", 0, 11, "abcdefghij", 0);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", -10);
+    test("abcdefghij", 1, 0, "", 0);
+    test("abcdefghij", 1, 0, "abcde", -5);
+    test("abcdefghij", 1, 0, "abcdefghij", -10);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 1, 1, "", 1);
+    test("abcdefghij", 1, 1, "abcde", 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 4, "", 4);
+    test("abcdefghij", 1, 4, "abcde", 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 8, "", 8);
+    test("abcdefghij", 1, 8, "abcde", 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 9, "", 9);
+    test("abcdefghij", 1, 9, "abcde", 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 10, "", 9);
+    test("abcdefghij", 1, 10, "abcde", 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 5, 0, "", 0);
+    test("abcdefghij", 5, 0, "abcde", -5);
+    test("abcdefghij", 5, 0, "abcdefghij", -10);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 5, 1, "", 1);
+    test("abcdefghij", 5, 1, "abcde", 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 2, "", 2);
+    test("abcdefghij", 5, 2, "abcde", 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 4, "", 4);
+    test("abcdefghij", 5, 4, "abcde", 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 5, "", 5);
+    test("abcdefghij", 5, 5, "abcde", 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 6, "", 5);
+    test("abcdefghij", 5, 6, "abcde", 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 9, 0, "", 0);
+    test("abcdefghij", 9, 0, "abcde", -5);
+    test("abcdefghij", 9, 0, "abcdefghij", -10);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 9, 1, "", 1);
+    test("abcdefghij", 9, 1, "abcde", 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 9);
+    test("abcdefghij", 9, 2, "", 1);
+    test("abcdefghij", 9, 2, "abcde", 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 9);
+    test("abcdefghij", 10, 0, "", 0);
+    test("abcdefghij", 10, 0, "abcde", -5);
+    test("abcdefghij", 10, 0, "abcdefghij", -10);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 10, 1, "", 0);
+    test("abcdefghij", 10, 1, "abcde", -5);
+    test("abcdefghij", 10, 1, "abcdefghij", -10);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 11, 0, "", 0);
+    test("abcdefghij", 11, 0, "abcde", 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0);
+}
+
+void test2()
+{
+    test("abcdefghijklmnopqrst", 0, 0, "", 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 0, 1, "", 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", -19);
+    test("abcdefghijklmnopqrst", 0, 10, "", 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", -10);
+    test("abcdefghijklmnopqrst", 0, 19, "", 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 14);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", -1);
+    test("abcdefghijklmnopqrst", 0, 20, "", 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 15);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0);
+    test("abcdefghijklmnopqrst", 0, 21, "", 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 15);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0);
+    test("abcdefghijklmnopqrst", 1, 0, "", 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 1, 1, "", 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 9, "", 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 18, "", 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 19, "", 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 20, "", 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 10, 0, "", 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 10, 1, "", 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 5, "", 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 9, "", 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 19, 0, "", 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 19, 1, "", 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 19);
+    test("abcdefghijklmnopqrst", 19, 2, "", 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 19);
+    test("abcdefghijklmnopqrst", 20, 0, "", 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 20, 1, "", 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 21, 0, "", 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0);
+}
+
+
+int main()
+{
+    test0();
+    test1();
+    test2();
+
+    {
+    test("", 0, 0, "", 0);
+    test("", 0, 0, "abcde", -5);
+    test("", 0, 0, "abcdefghij", -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 0, 2, "", 5);
+    test("abcde", 0, 6,"abcde", 0);
+    test("abcde", 0, 6, "abcdefghij", -5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", -15);
+    test("abcdefghij", 3, 3, "", 10);
+    test("abcdefghij", 3, 3,"abcde", 5);
+    test("abcdefghij", 3, 3, "def", 0);
+    test("abcdefghij", 0, 4, "abcdefghijklmnopqrst", -10);
+    test("abcdefghijklmnopqrst", 5, 5, "", 20);
+    test("abcdefghijklmnopqrst", 0, 8, "abcde", 15);
+    test("abcdefghijklmnopqrst", 0, 12, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 0, -1, "abcdefghijklmnopqrst", 0);
+    }
+
+    {
+    test(L"", 0, 0, L"", 0);
+    test(L"", 0, 0, L"abcde", -5);
+    test(L"", 0, 0, L"abcdefghij", -10);
+    test(L"", 0, 0, L"abcdefghijklmnopqrst", -20);
+    test(L"abcde", 0, 2, L"", 5);
+    test(L"abcde", 0, 6, L"abcde", 0);
+    test(L"abcde", 0, 6, L"abcdefghij", -5);
+    test(L"abcde", 0, 6, L"abcdefghijklmnopqrst", -15);
+    test(L"abcdefghij", 3, 3, L"", 10);
+    test(L"abcdefghij", 3, 3, L"abcde", 5);
+    test(L"abcdefghij", 3, 3, L"def", 0);
+    test(L"abcdefghij", 0, 4, L"abcdefghijklmnopqrst", -10);
+    test(L"abcdefghijklmnopqrst", 5, 5, L"", 20);
+    test(L"abcdefghijklmnopqrst", 0, 8, L"abcde", 15);
+    test(L"abcdefghijklmnopqrst", 0, 12, L"abcdefghij", 10);
+    test(L"abcdefghijklmnopqrst", 0, -1, L"abcdefghijklmnopqrst", 0);
+    }
+
+#if __cplusplus >= 201103L
+    {
+    test(U"", 0, 0, U"", 0);
+    test(U"", 0, 0, U"abcde", -5);
+    test(U"", 0, 0, U"abcdefghij", -10);
+    test(U"", 0, 0, U"abcdefghijklmnopqrst", -20);
+    test(U"abcde", 0, 2, U"", 5);
+    test(U"abcde", 0, 6, U"abcde", 0);
+    test(U"abcde", 0, 6, U"abcdefghij", -5);
+    test(U"abcde", 0, 6, U"abcdefghijklmnopqrst", -15);
+    test(U"abcdefghij", 3, 3, U"", 10);
+    test(U"abcdefghij", 3, 3, U"abcde", 5);
+    test(U"abcdefghij", 3, 3, U"def", 0);
+    test(U"abcdefghij", 0, 4, U"abcdefghijklmnopqrst", -10);
+    test(U"abcdefghijklmnopqrst", 5, 5, U"", 20);
+    test(U"abcdefghijklmnopqrst", 0, 8, U"abcde", 15);
+    test(U"abcdefghijklmnopqrst", 0, 12, U"abcdefghij", 10);
+    test(U"abcdefghijklmnopqrst", 0, -1, U"abcdefghijklmnopqrst", 0);
+    }
+ 
+    {
+    test(u"", 0, 0, u"", 0);
+    test(u"", 0, 0, u"abcde", -5);
+    test(u"", 0, 0, u"abcdefghij", -10);
+    test(u"", 0, 0, u"abcdefghijklmnopqrst", -20);
+    test(u"abcde", 0, 2, u"", 5);
+    test(u"abcde", 0, 6, u"abcde", 0);
+    test(u"abcde", 0, 6, u"abcdefghij", -5);
+    test(u"abcde", 0, 6, u"abcdefghijklmnopqrst", -15);
+    test(u"abcdefghij", 3, 3, u"", 10);
+    test(u"abcdefghij", 3, 3, u"abcde", 5);
+    test(u"abcdefghij", 3, 3, u"def", 0);
+    test(u"abcdefghij", 0, 4, u"abcdefghijklmnopqrst", -10);
+    test(u"abcdefghijklmnopqrst", 5, 5, u"", 20);
+    test(u"abcdefghijklmnopqrst", 0, 8, u"abcde", 15);
+    test(u"abcdefghijklmnopqrst", 0, 12, u"abcdefghij", 10);
+    test(u"abcdefghijklmnopqrst", 0, -1, u"abcdefghijklmnopqrst", 0);
+    }
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcde", 5 };
+    static_assert ( sv1.compare(0, 0, "") == 0, "" );
+    static_assert ( sv1.compare(0, 0, "abcde") == -1, "" );
+    static_assert ( sv2.compare(0, 2, "") == 1, "" );
+    static_assert ( sv2.compare(0, 6, "abcde") == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp b/test/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp
new file mode 100644
index 0000000..2047862
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/compare.size_size_sv.pass.cpp
@@ -0,0 +1,397 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr int compare(size_type pos1, size_type n1, basic_string_view str) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); }
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1,
+            std::experimental::basic_string_view<CharT> sv2, int expected ) {
+
+    try
+    {
+        assert ( sign( sv1.compare(pos1, n1, sv2)) == sign(expected));
+        assert(pos1 <= sv1.size());
+    }
+    catch (const std::out_of_range&) { assert(pos1 > sv1.size()); }
+}
+
+
+template<typename CharT>
+void test ( const CharT *s1, size_t pos1, size_t n1, const CharT  *s2, int expected ) {
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    
+    string_view_t sv1 ( s1 );
+    string_view_t sv2 ( s2 );
+    test1(sv1, pos1, n1, sv2, expected);
+}
+
+void test0()
+{
+    test("", 0, 0, "", 0);
+    test("", 0, 0, "abcde", -5);
+    test("", 0, 0, "abcdefghij", -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("", 0, 1, "", 0);
+    test("", 0, 1, "abcde", -5);
+    test("", 0, 1, "abcdefghij", -10);
+    test("", 0, 1, "abcdefghijklmnopqrst", -20);
+    test("", 1, 0, "", 0);
+    test("", 1, 0, "abcde", 0);
+    test("", 1, 0, "abcdefghij", 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0);
+    test("abcde", 0, 0, "", 0);
+    test("abcde", 0, 0, "abcde", -5);
+    test("abcde", 0, 0, "abcdefghij", -10);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 0, 1, "", 1);
+    test("abcde", 0, 1, "abcde", -4);
+    test("abcde", 0, 1, "abcdefghij", -9);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", -19);
+    test("abcde", 0, 2, "", 2);
+    test("abcde", 0, 2, "abcde", -3);
+    test("abcde", 0, 2, "abcdefghij", -8);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", -18);
+    test("abcde", 0, 4, "", 4);
+    test("abcde", 0, 4, "abcde", -1);
+    test("abcde", 0, 4, "abcdefghij", -6);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", -16);
+    test("abcde", 0, 5, "", 5);
+    test("abcde", 0, 5, "abcde", 0);
+    test("abcde", 0, 5, "abcdefghij", -5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", -15);
+    test("abcde", 0, 6, "", 5);
+    test("abcde", 0, 6, "abcde", 0);
+    test("abcde", 0, 6, "abcdefghij", -5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", -15);
+    test("abcde", 1, 0, "", 0);
+    test("abcde", 1, 0, "abcde", -5);
+    test("abcde", 1, 0, "abcdefghij", -10);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 1, 1, "", 1);
+    test("abcde", 1, 1, "abcde", 1);
+    test("abcde", 1, 1, "abcdefghij", 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 2, "", 2);
+    test("abcde", 1, 2, "abcde", 1);
+    test("abcde", 1, 2, "abcdefghij", 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 3, "", 3);
+    test("abcde", 1, 3, "abcde", 1);
+    test("abcde", 1, 3, "abcdefghij", 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 4, "", 4);
+    test("abcde", 1, 4, "abcde", 1);
+    test("abcde", 1, 4, "abcdefghij", 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1);
+    test("abcde", 1, 5, "", 4);
+    test("abcde", 1, 5, "abcde", 1);
+    test("abcde", 1, 5, "abcdefghij", 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1);
+    test("abcde", 2, 0, "", 0);
+    test("abcde", 2, 0, "abcde", -5);
+    test("abcde", 2, 0, "abcdefghij", -10);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 2, 1, "", 1);
+    test("abcde", 2, 1, "abcde", 2);
+    test("abcde", 2, 1, "abcdefghij", 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 2);
+    test("abcde", 2, 2, "", 2);
+    test("abcde", 2, 2, "abcde", 2);
+    test("abcde", 2, 2, "abcdefghij", 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 2);
+    test("abcde", 2, 3, "", 3);
+    test("abcde", 2, 3, "abcde", 2);
+    test("abcde", 2, 3, "abcdefghij", 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 2);
+    test("abcde", 2, 4, "", 3);
+    test("abcde", 2, 4, "abcde", 2);
+    test("abcde", 2, 4, "abcdefghij", 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 2);
+    test("abcde", 4, 0, "", 0);
+    test("abcde", 4, 0, "abcde", -5);
+    test("abcde", 4, 0, "abcdefghij", -10);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 4, 1, "", 1);
+    test("abcde", 4, 1, "abcde", 4);
+    test("abcde", 4, 1, "abcdefghij", 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 4);
+    test("abcde", 4, 2, "", 1);
+    test("abcde", 4, 2, "abcde", 4);
+    test("abcde", 4, 2, "abcdefghij", 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 4);
+    test("abcde", 5, 0, "", 0);
+    test("abcde", 5, 0, "abcde", -5);
+    test("abcde", 5, 0, "abcdefghij", -10);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", -20);
+    test("abcde", 5, 1, "", 0);
+    test("abcde", 5, 1, "abcde", -5);
+    test("abcde", 5, 1, "abcdefghij", -10);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", -20);
+}
+
+void test1()
+{
+    test("abcde", 6, 0, "", 0);
+    test("abcde", 6, 0, "abcde", 0);
+    test("abcde", 6, 0, "abcdefghij", 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0);
+    test("abcdefghij", 0, 0, "", 0);
+    test("abcdefghij", 0, 0, "abcde", -5);
+    test("abcdefghij", 0, 0, "abcdefghij", -10);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 0, 1, "", 1);
+    test("abcdefghij", 0, 1, "abcde", -4);
+    test("abcdefghij", 0, 1, "abcdefghij", -9);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", -19);
+    test("abcdefghij", 0, 5, "", 5);
+    test("abcdefghij", 0, 5, "abcde", 0);
+    test("abcdefghij", 0, 5, "abcdefghij", -5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", -15);
+    test("abcdefghij", 0, 9, "", 9);
+    test("abcdefghij", 0, 9, "abcde", 4);
+    test("abcdefghij", 0, 9, "abcdefghij", -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", -11);
+    test("abcdefghij", 0, 10, "", 10);
+    test("abcdefghij", 0, 10, "abcde", 5);
+    test("abcdefghij", 0, 10, "abcdefghij", 0);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", -10);
+    test("abcdefghij", 0, 11, "", 10);
+    test("abcdefghij", 0, 11, "abcde", 5);
+    test("abcdefghij", 0, 11, "abcdefghij", 0);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", -10);
+    test("abcdefghij", 1, 0, "", 0);
+    test("abcdefghij", 1, 0, "abcde", -5);
+    test("abcdefghij", 1, 0, "abcdefghij", -10);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 1, 1, "", 1);
+    test("abcdefghij", 1, 1, "abcde", 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 4, "", 4);
+    test("abcdefghij", 1, 4, "abcde", 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 8, "", 8);
+    test("abcdefghij", 1, 8, "abcde", 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 9, "", 9);
+    test("abcdefghij", 1, 9, "abcde", 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 1, 10, "", 9);
+    test("abcdefghij", 1, 10, "abcde", 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1);
+    test("abcdefghij", 5, 0, "", 0);
+    test("abcdefghij", 5, 0, "abcde", -5);
+    test("abcdefghij", 5, 0, "abcdefghij", -10);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 5, 1, "", 1);
+    test("abcdefghij", 5, 1, "abcde", 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 2, "", 2);
+    test("abcdefghij", 5, 2, "abcde", 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 4, "", 4);
+    test("abcdefghij", 5, 4, "abcde", 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 5, "", 5);
+    test("abcdefghij", 5, 5, "abcde", 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 5, 6, "", 5);
+    test("abcdefghij", 5, 6, "abcde", 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 5);
+    test("abcdefghij", 9, 0, "", 0);
+    test("abcdefghij", 9, 0, "abcde", -5);
+    test("abcdefghij", 9, 0, "abcdefghij", -10);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 9, 1, "", 1);
+    test("abcdefghij", 9, 1, "abcde", 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 9);
+    test("abcdefghij", 9, 2, "", 1);
+    test("abcdefghij", 9, 2, "abcde", 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 9);
+    test("abcdefghij", 10, 0, "", 0);
+    test("abcdefghij", 10, 0, "abcde", -5);
+    test("abcdefghij", 10, 0, "abcdefghij", -10);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 10, 1, "", 0);
+    test("abcdefghij", 10, 1, "abcde", -5);
+    test("abcdefghij", 10, 1, "abcdefghij", -10);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", -20);
+    test("abcdefghij", 11, 0, "", 0);
+    test("abcdefghij", 11, 0, "abcde", 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0);
+}
+
+void test2()
+{
+    test("abcdefghijklmnopqrst", 0, 0, "", 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 0, 1, "", 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", -19);
+    test("abcdefghijklmnopqrst", 0, 10, "", 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", -10);
+    test("abcdefghijklmnopqrst", 0, 19, "", 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 14);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", -1);
+    test("abcdefghijklmnopqrst", 0, 20, "", 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 15);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0);
+    test("abcdefghijklmnopqrst", 0, 21, "", 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 15);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0);
+    test("abcdefghijklmnopqrst", 1, 0, "", 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 1, 1, "", 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 9, "", 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 18, "", 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 19, "", 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 1, 20, "", 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1);
+    test("abcdefghijklmnopqrst", 10, 0, "", 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 10, 1, "", 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 5, "", 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 9, "", 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10);
+    test("abcdefghijklmnopqrst", 19, 0, "", 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 19, 1, "", 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 19);
+    test("abcdefghijklmnopqrst", 19, 2, "", 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 19);
+    test("abcdefghijklmnopqrst", 20, 0, "", 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 20, 1, "", 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", -20);
+    test("abcdefghijklmnopqrst", 21, 0, "", 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0);
+}
+
+
+int main () {
+    test0();
+    test1();
+    test2();
+    
+    {
+    test("abcde", 5, 1, "", 0);
+    test("abcde", 2, 4, "", 3);
+    test("abcde", 2, 4, "abcde", 2);
+    test("ABCde", 2, 4, "abcde", -1);
+    }
+
+    {
+    test(L"abcde", 5, 1, L"", 0);
+    test(L"abcde", 2, 4, L"", 3);
+    test(L"abcde", 2, 4, L"abcde", 2);
+    test(L"ABCde", 2, 4, L"abcde", -1);
+    }
+
+#if __cplusplus >= 201103L
+    {
+    test(u"abcde", 5, 1, u"", 0);
+    test(u"abcde", 2, 4, u"", 3);
+    test(u"abcde", 2, 4, u"abcde", 2);
+    test(u"ABCde", 2, 4, u"abcde", -1);
+    }
+
+    {
+    test(U"abcde", 5, 1, U"", 0);
+    test(U"abcde", 2, 4, U"", 3);
+    test(U"abcde", 2, 4, U"abcde", 2);
+    test(U"ABCde", 2, 4, U"abcde", -1);
+    }
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1 { "abcde", 5 };
+    constexpr SV  sv2 { "abcde", 0 };
+    static_assert ( sv1.compare(5, 1, sv2) == 0, "" );
+    static_assert ( sv1.compare(2, 4, sv2) == 1, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp b/test/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp
new file mode 100644
index 0000000..acb48f5
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/compare.size_size_sv_pointer_size.pass.cpp
@@ -0,0 +1,1349 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr int compare(size_type pos1, size_type n1,
+//             const charT* s, size_type n2) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); }
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1,
+             const CharT *s2, size_t n2,
+             int expected ) {
+
+    try
+    {
+        assert ( sign( sv1.compare(pos1, n1, s2, n2)) == sign(expected));
+        assert(pos1 <= sv1.size());
+    }
+    catch (const std::out_of_range&) { assert(pos1 > sv1.size()); }
+}
+
+
+template<typename CharT>
+void test ( const CharT *s1, size_t pos1, size_t n1, 
+            const CharT *s2, size_t n2, 
+            int expected ) {
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    
+    string_view_t sv1 ( s1 );
+    test1 (sv1, pos1, n1, s2, n2, expected);
+}
+
+
+void test0()
+{
+    test("", 0, 0, "", 0, 0);
+    test("", 0, 0, "abcde", 0, 0);
+    test("", 0, 0, "abcde", 1, -1);
+    test("", 0, 0, "abcde", 2, -2);
+    test("", 0, 0, "abcde", 4, -4);
+    test("", 0, 0, "abcde", 5, -5);
+    test("", 0, 0, "abcdefghij", 0, 0);
+    test("", 0, 0, "abcdefghij", 1, -1);
+    test("", 0, 0, "abcdefghij", 5, -5);
+    test("", 0, 0, "abcdefghij", 9, -9);
+    test("", 0, 0, "abcdefghij", 10, -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("", 0, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("", 0, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("", 0, 1, "", 0, 0);
+    test("", 0, 1, "abcde", 0, 0);
+    test("", 0, 1, "abcde", 1, -1);
+    test("", 0, 1, "abcde", 2, -2);
+    test("", 0, 1, "abcde", 4, -4);
+    test("", 0, 1, "abcde", 5, -5);
+    test("", 0, 1, "abcdefghij", 0, 0);
+    test("", 0, 1, "abcdefghij", 1, -1);
+    test("", 0, 1, "abcdefghij", 5, -5);
+    test("", 0, 1, "abcdefghij", 9, -9);
+    test("", 0, 1, "abcdefghij", 10, -10);
+    test("", 0, 1, "abcdefghijklmnopqrst", 0, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 1, -1);
+    test("", 0, 1, "abcdefghijklmnopqrst", 10, -10);
+    test("", 0, 1, "abcdefghijklmnopqrst", 19, -19);
+    test("", 0, 1, "abcdefghijklmnopqrst", 20, -20);
+    test("", 1, 0, "", 0, 0);
+    test("", 1, 0, "abcde", 0, 0);
+    test("", 1, 0, "abcde", 1, 0);
+    test("", 1, 0, "abcde", 2, 0);
+    test("", 1, 0, "abcde", 4, 0);
+    test("", 1, 0, "abcde", 5, 0);
+    test("", 1, 0, "abcdefghij", 0, 0);
+    test("", 1, 0, "abcdefghij", 1, 0);
+    test("", 1, 0, "abcdefghij", 5, 0);
+    test("", 1, 0, "abcdefghij", 9, 0);
+    test("", 1, 0, "abcdefghij", 10, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 1, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 10, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 19, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 20, 0);
+    test("abcde", 0, 0, "", 0, 0);
+    test("abcde", 0, 0, "abcde", 0, 0);
+    test("abcde", 0, 0, "abcde", 1, -1);
+    test("abcde", 0, 0, "abcde", 2, -2);
+    test("abcde", 0, 0, "abcde", 4, -4);
+    test("abcde", 0, 0, "abcde", 5, -5);
+    test("abcde", 0, 0, "abcdefghij", 0, 0);
+    test("abcde", 0, 0, "abcdefghij", 1, -1);
+    test("abcde", 0, 0, "abcdefghij", 5, -5);
+    test("abcde", 0, 0, "abcdefghij", 9, -9);
+    test("abcde", 0, 0, "abcdefghij", 10, -10);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcde", 0, 1, "", 0, 1);
+    test("abcde", 0, 1, "abcde", 0, 1);
+    test("abcde", 0, 1, "abcde", 1, 0);
+    test("abcde", 0, 1, "abcde", 2, -1);
+    test("abcde", 0, 1, "abcde", 4, -3);
+    test("abcde", 0, 1, "abcde", 5, -4);
+    test("abcde", 0, 1, "abcdefghij", 0, 1);
+    test("abcde", 0, 1, "abcdefghij", 1, 0);
+    test("abcde", 0, 1, "abcdefghij", 5, -4);
+    test("abcde", 0, 1, "abcdefghij", 9, -8);
+    test("abcde", 0, 1, "abcdefghij", 10, -9);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 1, 0);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 10, -9);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 19, -18);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 20, -19);
+    test("abcde", 0, 2, "", 0, 2);
+    test("abcde", 0, 2, "abcde", 0, 2);
+    test("abcde", 0, 2, "abcde", 1, 1);
+    test("abcde", 0, 2, "abcde", 2, 0);
+    test("abcde", 0, 2, "abcde", 4, -2);
+    test("abcde", 0, 2, "abcde", 5, -3);
+    test("abcde", 0, 2, "abcdefghij", 0, 2);
+    test("abcde", 0, 2, "abcdefghij", 1, 1);
+    test("abcde", 0, 2, "abcdefghij", 5, -3);
+    test("abcde", 0, 2, "abcdefghij", 9, -7);
+    test("abcde", 0, 2, "abcdefghij", 10, -8);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 0, 2);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 1, 1);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 10, -8);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 19, -17);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 20, -18);
+    test("abcde", 0, 4, "", 0, 4);
+    test("abcde", 0, 4, "abcde", 0, 4);
+    test("abcde", 0, 4, "abcde", 1, 3);
+    test("abcde", 0, 4, "abcde", 2, 2);
+}
+
+
+void test1()
+{
+    test("abcde", 0, 4, "abcde", 4, 0);
+    test("abcde", 0, 4, "abcde", 5, -1);
+    test("abcde", 0, 4, "abcdefghij", 0, 4);
+    test("abcde", 0, 4, "abcdefghij", 1, 3);
+    test("abcde", 0, 4, "abcdefghij", 5, -1);
+    test("abcde", 0, 4, "abcdefghij", 9, -5);
+    test("abcde", 0, 4, "abcdefghij", 10, -6);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 0, 4);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 1, 3);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 10, -6);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 19, -15);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 20, -16);
+    test("abcde", 0, 5, "", 0, 5);
+    test("abcde", 0, 5, "abcde", 0, 5);
+    test("abcde", 0, 5, "abcde", 1, 4);
+    test("abcde", 0, 5, "abcde", 2, 3);
+    test("abcde", 0, 5, "abcde", 4, 1);
+    test("abcde", 0, 5, "abcde", 5, 0);
+    test("abcde", 0, 5, "abcdefghij", 0, 5);
+    test("abcde", 0, 5, "abcdefghij", 1, 4);
+    test("abcde", 0, 5, "abcdefghij", 5, 0);
+    test("abcde", 0, 5, "abcdefghij", 9, -4);
+    test("abcde", 0, 5, "abcdefghij", 10, -5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 0, 5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 1, 4);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 10, -5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 19, -14);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 20, -15);
+    test("abcde", 0, 6, "", 0, 5);
+    test("abcde", 0, 6, "abcde", 0, 5);
+    test("abcde", 0, 6, "abcde", 1, 4);
+    test("abcde", 0, 6, "abcde", 2, 3);
+    test("abcde", 0, 6, "abcde", 4, 1);
+    test("abcde", 0, 6, "abcde", 5, 0);
+    test("abcde", 0, 6, "abcdefghij", 0, 5);
+    test("abcde", 0, 6, "abcdefghij", 1, 4);
+    test("abcde", 0, 6, "abcdefghij", 5, 0);
+    test("abcde", 0, 6, "abcdefghij", 9, -4);
+    test("abcde", 0, 6, "abcdefghij", 10, -5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 0, 5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 1, 4);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 10, -5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 19, -14);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 20, -15);
+    test("abcde", 1, 0, "", 0, 0);
+    test("abcde", 1, 0, "abcde", 0, 0);
+    test("abcde", 1, 0, "abcde", 1, -1);
+    test("abcde", 1, 0, "abcde", 2, -2);
+    test("abcde", 1, 0, "abcde", 4, -4);
+    test("abcde", 1, 0, "abcde", 5, -5);
+    test("abcde", 1, 0, "abcdefghij", 0, 0);
+    test("abcde", 1, 0, "abcdefghij", 1, -1);
+    test("abcde", 1, 0, "abcdefghij", 5, -5);
+    test("abcde", 1, 0, "abcdefghij", 9, -9);
+    test("abcde", 1, 0, "abcdefghij", 10, -10);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcde", 1, 1, "", 0, 1);
+    test("abcde", 1, 1, "abcde", 0, 1);
+    test("abcde", 1, 1, "abcde", 1, 1);
+    test("abcde", 1, 1, "abcde", 2, 1);
+    test("abcde", 1, 1, "abcde", 4, 1);
+    test("abcde", 1, 1, "abcde", 5, 1);
+    test("abcde", 1, 1, "abcdefghij", 0, 1);
+    test("abcde", 1, 1, "abcdefghij", 1, 1);
+    test("abcde", 1, 1, "abcdefghij", 5, 1);
+    test("abcde", 1, 1, "abcdefghij", 9, 1);
+    test("abcde", 1, 1, "abcdefghij", 10, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 10, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 19, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 20, 1);
+    test("abcde", 1, 2, "", 0, 2);
+    test("abcde", 1, 2, "abcde", 0, 2);
+    test("abcde", 1, 2, "abcde", 1, 1);
+    test("abcde", 1, 2, "abcde", 2, 1);
+    test("abcde", 1, 2, "abcde", 4, 1);
+    test("abcde", 1, 2, "abcde", 5, 1);
+    test("abcde", 1, 2, "abcdefghij", 0, 2);
+    test("abcde", 1, 2, "abcdefghij", 1, 1);
+    test("abcde", 1, 2, "abcdefghij", 5, 1);
+    test("abcde", 1, 2, "abcdefghij", 9, 1);
+    test("abcde", 1, 2, "abcdefghij", 10, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 0, 2);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 10, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 19, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 20, 1);
+    test("abcde", 1, 3, "", 0, 3);
+    test("abcde", 1, 3, "abcde", 0, 3);
+    test("abcde", 1, 3, "abcde", 1, 1);
+    test("abcde", 1, 3, "abcde", 2, 1);
+    test("abcde", 1, 3, "abcde", 4, 1);
+    test("abcde", 1, 3, "abcde", 5, 1);
+    test("abcde", 1, 3, "abcdefghij", 0, 3);
+    test("abcde", 1, 3, "abcdefghij", 1, 1);
+}
+
+
+void test2()
+{
+    test("abcde", 1, 3, "abcdefghij", 5, 1);
+    test("abcde", 1, 3, "abcdefghij", 9, 1);
+    test("abcde", 1, 3, "abcdefghij", 10, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 0, 3);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 10, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 19, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 20, 1);
+    test("abcde", 1, 4, "", 0, 4);
+    test("abcde", 1, 4, "abcde", 0, 4);
+    test("abcde", 1, 4, "abcde", 1, 1);
+    test("abcde", 1, 4, "abcde", 2, 1);
+    test("abcde", 1, 4, "abcde", 4, 1);
+    test("abcde", 1, 4, "abcde", 5, 1);
+    test("abcde", 1, 4, "abcdefghij", 0, 4);
+    test("abcde", 1, 4, "abcdefghij", 1, 1);
+    test("abcde", 1, 4, "abcdefghij", 5, 1);
+    test("abcde", 1, 4, "abcdefghij", 9, 1);
+    test("abcde", 1, 4, "abcdefghij", 10, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 0, 4);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 10, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 19, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 20, 1);
+    test("abcde", 1, 5, "", 0, 4);
+    test("abcde", 1, 5, "abcde", 0, 4);
+    test("abcde", 1, 5, "abcde", 1, 1);
+    test("abcde", 1, 5, "abcde", 2, 1);
+    test("abcde", 1, 5, "abcde", 4, 1);
+    test("abcde", 1, 5, "abcde", 5, 1);
+    test("abcde", 1, 5, "abcdefghij", 0, 4);
+    test("abcde", 1, 5, "abcdefghij", 1, 1);
+    test("abcde", 1, 5, "abcdefghij", 5, 1);
+    test("abcde", 1, 5, "abcdefghij", 9, 1);
+    test("abcde", 1, 5, "abcdefghij", 10, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 0, 4);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 10, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 19, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 20, 1);
+    test("abcde", 2, 0, "", 0, 0);
+    test("abcde", 2, 0, "abcde", 0, 0);
+    test("abcde", 2, 0, "abcde", 1, -1);
+    test("abcde", 2, 0, "abcde", 2, -2);
+    test("abcde", 2, 0, "abcde", 4, -4);
+    test("abcde", 2, 0, "abcde", 5, -5);
+    test("abcde", 2, 0, "abcdefghij", 0, 0);
+    test("abcde", 2, 0, "abcdefghij", 1, -1);
+    test("abcde", 2, 0, "abcdefghij", 5, -5);
+    test("abcde", 2, 0, "abcdefghij", 9, -9);
+    test("abcde", 2, 0, "abcdefghij", 10, -10);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcde", 2, 1, "", 0, 1);
+    test("abcde", 2, 1, "abcde", 0, 1);
+    test("abcde", 2, 1, "abcde", 1, 2);
+    test("abcde", 2, 1, "abcde", 2, 2);
+    test("abcde", 2, 1, "abcde", 4, 2);
+    test("abcde", 2, 1, "abcde", 5, 2);
+    test("abcde", 2, 1, "abcdefghij", 0, 1);
+    test("abcde", 2, 1, "abcdefghij", 1, 2);
+    test("abcde", 2, 1, "abcdefghij", 5, 2);
+    test("abcde", 2, 1, "abcdefghij", 9, 2);
+    test("abcde", 2, 1, "abcdefghij", 10, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 1, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 10, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 19, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 20, 2);
+    test("abcde", 2, 2, "", 0, 2);
+    test("abcde", 2, 2, "abcde", 0, 2);
+    test("abcde", 2, 2, "abcde", 1, 2);
+    test("abcde", 2, 2, "abcde", 2, 2);
+    test("abcde", 2, 2, "abcde", 4, 2);
+    test("abcde", 2, 2, "abcde", 5, 2);
+    test("abcde", 2, 2, "abcdefghij", 0, 2);
+    test("abcde", 2, 2, "abcdefghij", 1, 2);
+    test("abcde", 2, 2, "abcdefghij", 5, 2);
+    test("abcde", 2, 2, "abcdefghij", 9, 2);
+    test("abcde", 2, 2, "abcdefghij", 10, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 0, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 1, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 10, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 19, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 20, 2);
+    test("abcde", 2, 3, "", 0, 3);
+    test("abcde", 2, 3, "abcde", 0, 3);
+    test("abcde", 2, 3, "abcde", 1, 2);
+    test("abcde", 2, 3, "abcde", 2, 2);
+    test("abcde", 2, 3, "abcde", 4, 2);
+    test("abcde", 2, 3, "abcde", 5, 2);
+    test("abcde", 2, 3, "abcdefghij", 0, 3);
+    test("abcde", 2, 3, "abcdefghij", 1, 2);
+    test("abcde", 2, 3, "abcdefghij", 5, 2);
+    test("abcde", 2, 3, "abcdefghij", 9, 2);
+    test("abcde", 2, 3, "abcdefghij", 10, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 0, 3);
+}
+
+
+void test3()
+{
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 1, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 10, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 19, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 20, 2);
+    test("abcde", 2, 4, "", 0, 3);
+    test("abcde", 2, 4, "abcde", 0, 3);
+    test("abcde", 2, 4, "abcde", 1, 2);
+    test("abcde", 2, 4, "abcde", 2, 2);
+    test("abcde", 2, 4, "abcde", 4, 2);
+    test("abcde", 2, 4, "abcde", 5, 2);
+    test("abcde", 2, 4, "abcdefghij", 0, 3);
+    test("abcde", 2, 4, "abcdefghij", 1, 2);
+    test("abcde", 2, 4, "abcdefghij", 5, 2);
+    test("abcde", 2, 4, "abcdefghij", 9, 2);
+    test("abcde", 2, 4, "abcdefghij", 10, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 0, 3);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 1, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 10, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 19, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 20, 2);
+    test("abcde", 4, 0, "", 0, 0);
+    test("abcde", 4, 0, "abcde", 0, 0);
+    test("abcde", 4, 0, "abcde", 1, -1);
+    test("abcde", 4, 0, "abcde", 2, -2);
+    test("abcde", 4, 0, "abcde", 4, -4);
+    test("abcde", 4, 0, "abcde", 5, -5);
+    test("abcde", 4, 0, "abcdefghij", 0, 0);
+    test("abcde", 4, 0, "abcdefghij", 1, -1);
+    test("abcde", 4, 0, "abcdefghij", 5, -5);
+    test("abcde", 4, 0, "abcdefghij", 9, -9);
+    test("abcde", 4, 0, "abcdefghij", 10, -10);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcde", 4, 1, "", 0, 1);
+    test("abcde", 4, 1, "abcde", 0, 1);
+    test("abcde", 4, 1, "abcde", 1, 4);
+    test("abcde", 4, 1, "abcde", 2, 4);
+    test("abcde", 4, 1, "abcde", 4, 4);
+    test("abcde", 4, 1, "abcde", 5, 4);
+    test("abcde", 4, 1, "abcdefghij", 0, 1);
+    test("abcde", 4, 1, "abcdefghij", 1, 4);
+    test("abcde", 4, 1, "abcdefghij", 5, 4);
+    test("abcde", 4, 1, "abcdefghij", 9, 4);
+    test("abcde", 4, 1, "abcdefghij", 10, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 1, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 10, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 19, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 20, 4);
+    test("abcde", 4, 2, "", 0, 1);
+    test("abcde", 4, 2, "abcde", 0, 1);
+    test("abcde", 4, 2, "abcde", 1, 4);
+    test("abcde", 4, 2, "abcde", 2, 4);
+    test("abcde", 4, 2, "abcde", 4, 4);
+    test("abcde", 4, 2, "abcde", 5, 4);
+    test("abcde", 4, 2, "abcdefghij", 0, 1);
+    test("abcde", 4, 2, "abcdefghij", 1, 4);
+    test("abcde", 4, 2, "abcdefghij", 5, 4);
+    test("abcde", 4, 2, "abcdefghij", 9, 4);
+    test("abcde", 4, 2, "abcdefghij", 10, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 0, 1);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 1, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 10, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 19, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 20, 4);
+    test("abcde", 5, 0, "", 0, 0);
+    test("abcde", 5, 0, "abcde", 0, 0);
+    test("abcde", 5, 0, "abcde", 1, -1);
+    test("abcde", 5, 0, "abcde", 2, -2);
+    test("abcde", 5, 0, "abcde", 4, -4);
+    test("abcde", 5, 0, "abcde", 5, -5);
+    test("abcde", 5, 0, "abcdefghij", 0, 0);
+    test("abcde", 5, 0, "abcdefghij", 1, -1);
+    test("abcde", 5, 0, "abcdefghij", 5, -5);
+    test("abcde", 5, 0, "abcdefghij", 9, -9);
+    test("abcde", 5, 0, "abcdefghij", 10, -10);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcde", 5, 1, "", 0, 0);
+    test("abcde", 5, 1, "abcde", 0, 0);
+    test("abcde", 5, 1, "abcde", 1, -1);
+    test("abcde", 5, 1, "abcde", 2, -2);
+    test("abcde", 5, 1, "abcde", 4, -4);
+    test("abcde", 5, 1, "abcde", 5, -5);
+    test("abcde", 5, 1, "abcdefghij", 0, 0);
+    test("abcde", 5, 1, "abcdefghij", 1, -1);
+    test("abcde", 5, 1, "abcdefghij", 5, -5);
+    test("abcde", 5, 1, "abcdefghij", 9, -9);
+    test("abcde", 5, 1, "abcdefghij", 10, -10);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 0, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 1, -1);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 10, -10);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 19, -19);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 20, -20);
+}
+
+
+void test4()
+{
+    test("abcde", 6, 0, "", 0, 0);
+    test("abcde", 6, 0, "abcde", 0, 0);
+    test("abcde", 6, 0, "abcde", 1, 0);
+    test("abcde", 6, 0, "abcde", 2, 0);
+    test("abcde", 6, 0, "abcde", 4, 0);
+    test("abcde", 6, 0, "abcde", 5, 0);
+    test("abcde", 6, 0, "abcdefghij", 0, 0);
+    test("abcde", 6, 0, "abcdefghij", 1, 0);
+    test("abcde", 6, 0, "abcdefghij", 5, 0);
+    test("abcde", 6, 0, "abcdefghij", 9, 0);
+    test("abcde", 6, 0, "abcdefghij", 10, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 1, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 10, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 19, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 20, 0);
+    test("abcdefghij", 0, 0, "", 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 1, -1);
+    test("abcdefghij", 0, 0, "abcde", 2, -2);
+    test("abcdefghij", 0, 0, "abcde", 4, -4);
+    test("abcdefghij", 0, 0, "abcde", 5, -5);
+    test("abcdefghij", 0, 0, "abcdefghij", 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghij", 5, -5);
+    test("abcdefghij", 0, 0, "abcdefghij", 9, -9);
+    test("abcdefghij", 0, 0, "abcdefghij", 10, -10);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghij", 0, 1, "", 0, 1);
+    test("abcdefghij", 0, 1, "abcde", 0, 1);
+    test("abcdefghij", 0, 1, "abcde", 1, 0);
+    test("abcdefghij", 0, 1, "abcde", 2, -1);
+    test("abcdefghij", 0, 1, "abcde", 4, -3);
+    test("abcdefghij", 0, 1, "abcde", 5, -4);
+    test("abcdefghij", 0, 1, "abcdefghij", 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghij", 1, 0);
+    test("abcdefghij", 0, 1, "abcdefghij", 5, -4);
+    test("abcdefghij", 0, 1, "abcdefghij", 9, -8);
+    test("abcdefghij", 0, 1, "abcdefghij", 10, -9);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 1, 0);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 10, -9);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 19, -18);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 20, -19);
+    test("abcdefghij", 0, 5, "", 0, 5);
+    test("abcdefghij", 0, 5, "abcde", 0, 5);
+    test("abcdefghij", 0, 5, "abcde", 1, 4);
+    test("abcdefghij", 0, 5, "abcde", 2, 3);
+    test("abcdefghij", 0, 5, "abcde", 4, 1);
+    test("abcdefghij", 0, 5, "abcde", 5, 0);
+    test("abcdefghij", 0, 5, "abcdefghij", 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghij", 1, 4);
+    test("abcdefghij", 0, 5, "abcdefghij", 5, 0);
+    test("abcdefghij", 0, 5, "abcdefghij", 9, -4);
+    test("abcdefghij", 0, 5, "abcdefghij", 10, -5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 1, 4);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 10, -5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 19, -14);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 20, -15);
+    test("abcdefghij", 0, 9, "", 0, 9);
+    test("abcdefghij", 0, 9, "abcde", 0, 9);
+    test("abcdefghij", 0, 9, "abcde", 1, 8);
+    test("abcdefghij", 0, 9, "abcde", 2, 7);
+    test("abcdefghij", 0, 9, "abcde", 4, 5);
+    test("abcdefghij", 0, 9, "abcde", 5, 4);
+    test("abcdefghij", 0, 9, "abcdefghij", 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghij", 1, 8);
+    test("abcdefghij", 0, 9, "abcdefghij", 5, 4);
+    test("abcdefghij", 0, 9, "abcdefghij", 9, 0);
+    test("abcdefghij", 0, 9, "abcdefghij", 10, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 1, 8);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 10, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 19, -10);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 20, -11);
+    test("abcdefghij", 0, 10, "", 0, 10);
+    test("abcdefghij", 0, 10, "abcde", 0, 10);
+    test("abcdefghij", 0, 10, "abcde", 1, 9);
+    test("abcdefghij", 0, 10, "abcde", 2, 8);
+    test("abcdefghij", 0, 10, "abcde", 4, 6);
+    test("abcdefghij", 0, 10, "abcde", 5, 5);
+    test("abcdefghij", 0, 10, "abcdefghij", 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghij", 1, 9);
+    test("abcdefghij", 0, 10, "abcdefghij", 5, 5);
+    test("abcdefghij", 0, 10, "abcdefghij", 9, 1);
+    test("abcdefghij", 0, 10, "abcdefghij", 10, 0);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 1, 9);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 10, 0);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 19, -9);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 20, -10);
+    test("abcdefghij", 0, 11, "", 0, 10);
+    test("abcdefghij", 0, 11, "abcde", 0, 10);
+    test("abcdefghij", 0, 11, "abcde", 1, 9);
+    test("abcdefghij", 0, 11, "abcde", 2, 8);
+}
+
+
+void test5()
+{
+    test("abcdefghij", 0, 11, "abcde", 4, 6);
+    test("abcdefghij", 0, 11, "abcde", 5, 5);
+    test("abcdefghij", 0, 11, "abcdefghij", 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghij", 1, 9);
+    test("abcdefghij", 0, 11, "abcdefghij", 5, 5);
+    test("abcdefghij", 0, 11, "abcdefghij", 9, 1);
+    test("abcdefghij", 0, 11, "abcdefghij", 10, 0);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 1, 9);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 10, 0);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 19, -9);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 20, -10);
+    test("abcdefghij", 1, 0, "", 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 1, -1);
+    test("abcdefghij", 1, 0, "abcde", 2, -2);
+    test("abcdefghij", 1, 0, "abcde", 4, -4);
+    test("abcdefghij", 1, 0, "abcde", 5, -5);
+    test("abcdefghij", 1, 0, "abcdefghij", 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghij", 5, -5);
+    test("abcdefghij", 1, 0, "abcdefghij", 9, -9);
+    test("abcdefghij", 1, 0, "abcdefghij", 10, -10);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghij", 1, 1, "", 0, 1);
+    test("abcdefghij", 1, 1, "abcde", 0, 1);
+    test("abcdefghij", 1, 1, "abcde", 1, 1);
+    test("abcdefghij", 1, 1, "abcde", 2, 1);
+    test("abcdefghij", 1, 1, "abcde", 4, 1);
+    test("abcdefghij", 1, 1, "abcde", 5, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 1, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 5, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 9, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 10, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghij", 1, 4, "", 0, 4);
+    test("abcdefghij", 1, 4, "abcde", 0, 4);
+    test("abcdefghij", 1, 4, "abcde", 1, 1);
+    test("abcdefghij", 1, 4, "abcde", 2, 1);
+    test("abcdefghij", 1, 4, "abcde", 4, 1);
+    test("abcdefghij", 1, 4, "abcde", 5, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghij", 1, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 5, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 9, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 10, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghij", 1, 8, "", 0, 8);
+    test("abcdefghij", 1, 8, "abcde", 0, 8);
+    test("abcdefghij", 1, 8, "abcde", 1, 1);
+    test("abcdefghij", 1, 8, "abcde", 2, 1);
+    test("abcdefghij", 1, 8, "abcde", 4, 1);
+    test("abcdefghij", 1, 8, "abcde", 5, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghij", 1, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 5, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 9, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 10, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghij", 1, 9, "", 0, 9);
+    test("abcdefghij", 1, 9, "abcde", 0, 9);
+    test("abcdefghij", 1, 9, "abcde", 1, 1);
+    test("abcdefghij", 1, 9, "abcde", 2, 1);
+    test("abcdefghij", 1, 9, "abcde", 4, 1);
+    test("abcdefghij", 1, 9, "abcde", 5, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghij", 1, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 5, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 9, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 10, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghij", 1, 10, "", 0, 9);
+    test("abcdefghij", 1, 10, "abcde", 0, 9);
+    test("abcdefghij", 1, 10, "abcde", 1, 1);
+    test("abcdefghij", 1, 10, "abcde", 2, 1);
+    test("abcdefghij", 1, 10, "abcde", 4, 1);
+    test("abcdefghij", 1, 10, "abcde", 5, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghij", 1, 1);
+}
+
+
+void test6()
+{
+    test("abcdefghij", 1, 10, "abcdefghij", 5, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 9, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 10, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghij", 5, 0, "", 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 1, -1);
+    test("abcdefghij", 5, 0, "abcde", 2, -2);
+    test("abcdefghij", 5, 0, "abcde", 4, -4);
+    test("abcdefghij", 5, 0, "abcde", 5, -5);
+    test("abcdefghij", 5, 0, "abcdefghij", 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghij", 5, -5);
+    test("abcdefghij", 5, 0, "abcdefghij", 9, -9);
+    test("abcdefghij", 5, 0, "abcdefghij", 10, -10);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghij", 5, 1, "", 0, 1);
+    test("abcdefghij", 5, 1, "abcde", 0, 1);
+    test("abcdefghij", 5, 1, "abcde", 1, 5);
+    test("abcdefghij", 5, 1, "abcde", 2, 5);
+    test("abcdefghij", 5, 1, "abcde", 4, 5);
+    test("abcdefghij", 5, 1, "abcde", 5, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghij", 1, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 5, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 9, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 10, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 1, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 10, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 19, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 20, 5);
+    test("abcdefghij", 5, 2, "", 0, 2);
+    test("abcdefghij", 5, 2, "abcde", 0, 2);
+    test("abcdefghij", 5, 2, "abcde", 1, 5);
+    test("abcdefghij", 5, 2, "abcde", 2, 5);
+    test("abcdefghij", 5, 2, "abcde", 4, 5);
+    test("abcdefghij", 5, 2, "abcde", 5, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghij", 1, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 5, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 9, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 10, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 1, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 10, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 19, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 20, 5);
+    test("abcdefghij", 5, 4, "", 0, 4);
+    test("abcdefghij", 5, 4, "abcde", 0, 4);
+    test("abcdefghij", 5, 4, "abcde", 1, 5);
+    test("abcdefghij", 5, 4, "abcde", 2, 5);
+    test("abcdefghij", 5, 4, "abcde", 4, 5);
+    test("abcdefghij", 5, 4, "abcde", 5, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 1, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 5, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 9, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 10, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 1, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 10, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 19, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 20, 5);
+    test("abcdefghij", 5, 5, "", 0, 5);
+    test("abcdefghij", 5, 5, "abcde", 0, 5);
+    test("abcdefghij", 5, 5, "abcde", 1, 5);
+    test("abcdefghij", 5, 5, "abcde", 2, 5);
+    test("abcdefghij", 5, 5, "abcde", 4, 5);
+    test("abcdefghij", 5, 5, "abcde", 5, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 1, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 5, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 9, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 10, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 1, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 10, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 19, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 20, 5);
+    test("abcdefghij", 5, 6, "", 0, 5);
+    test("abcdefghij", 5, 6, "abcde", 0, 5);
+    test("abcdefghij", 5, 6, "abcde", 1, 5);
+    test("abcdefghij", 5, 6, "abcde", 2, 5);
+    test("abcdefghij", 5, 6, "abcde", 4, 5);
+    test("abcdefghij", 5, 6, "abcde", 5, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 1, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 5, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 9, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 10, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 0, 5);
+}
+
+
+void test7()
+{
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 1, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 10, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 19, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 20, 5);
+    test("abcdefghij", 9, 0, "", 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 1, -1);
+    test("abcdefghij", 9, 0, "abcde", 2, -2);
+    test("abcdefghij", 9, 0, "abcde", 4, -4);
+    test("abcdefghij", 9, 0, "abcde", 5, -5);
+    test("abcdefghij", 9, 0, "abcdefghij", 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghij", 5, -5);
+    test("abcdefghij", 9, 0, "abcdefghij", 9, -9);
+    test("abcdefghij", 9, 0, "abcdefghij", 10, -10);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghij", 9, 1, "", 0, 1);
+    test("abcdefghij", 9, 1, "abcde", 0, 1);
+    test("abcdefghij", 9, 1, "abcde", 1, 9);
+    test("abcdefghij", 9, 1, "abcde", 2, 9);
+    test("abcdefghij", 9, 1, "abcde", 4, 9);
+    test("abcdefghij", 9, 1, "abcde", 5, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghij", 1, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 5, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 9, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 10, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 1, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 10, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 19, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 20, 9);
+    test("abcdefghij", 9, 2, "", 0, 1);
+    test("abcdefghij", 9, 2, "abcde", 0, 1);
+    test("abcdefghij", 9, 2, "abcde", 1, 9);
+    test("abcdefghij", 9, 2, "abcde", 2, 9);
+    test("abcdefghij", 9, 2, "abcde", 4, 9);
+    test("abcdefghij", 9, 2, "abcde", 5, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghij", 1, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 5, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 9, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 10, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 1, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 10, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 19, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 20, 9);
+    test("abcdefghij", 10, 0, "", 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 1, -1);
+    test("abcdefghij", 10, 0, "abcde", 2, -2);
+    test("abcdefghij", 10, 0, "abcde", 4, -4);
+    test("abcdefghij", 10, 0, "abcde", 5, -5);
+    test("abcdefghij", 10, 0, "abcdefghij", 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghij", 5, -5);
+    test("abcdefghij", 10, 0, "abcdefghij", 9, -9);
+    test("abcdefghij", 10, 0, "abcdefghij", 10, -10);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghij", 10, 1, "", 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 1, -1);
+    test("abcdefghij", 10, 1, "abcde", 2, -2);
+    test("abcdefghij", 10, 1, "abcde", 4, -4);
+    test("abcdefghij", 10, 1, "abcde", 5, -5);
+    test("abcdefghij", 10, 1, "abcdefghij", 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghij", 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghij", 5, -5);
+    test("abcdefghij", 10, 1, "abcdefghij", 9, -9);
+    test("abcdefghij", 10, 1, "abcdefghij", 10, -10);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghij", 11, 0, "", 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 1, 0);
+    test("abcdefghij", 11, 0, "abcde", 2, 0);
+    test("abcdefghij", 11, 0, "abcde", 4, 0);
+    test("abcdefghij", 11, 0, "abcde", 5, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 5, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 9, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 10, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 10, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 19, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 20, 0);
+}
+
+void test8()
+{
+    test("abcdefghijklmnopqrst", 0, 0, "", 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 2, -2);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 4, -4);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 5, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 5, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 9, -9);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 10, -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghijklmnopqrst", 0, 1, "", 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 1, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 2, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 4, -3);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 5, -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 1, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 5, -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 9, -8);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 10, -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 1, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 10, -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 19, -18);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 20, -19);
+    test("abcdefghijklmnopqrst", 0, 10, "", 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 1, 9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 2, 8);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 4, 6);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 5, 5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 1, 9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 5, 5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 9, 1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 10, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 1, 9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 10, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 19, -9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 20, -10);
+    test("abcdefghijklmnopqrst", 0, 19, "", 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 1, 18);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 2, 17);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 4, 15);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 5, 14);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 1, 18);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 5, 14);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 9, 10);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 10, 9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 1, 18);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 10, 9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 19, 0);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 20, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 1, 19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 2, 18);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 4, 16);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 5, 15);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 1, 19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 5, 15);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 9, 11);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 10, 10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 1, 19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 10, 10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 20, 0);
+    test("abcdefghijklmnopqrst", 0, 21, "", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 1, 19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 2, 18);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 4, 16);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 5, 15);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 1, 19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 5, 15);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 9, 11);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 10, 10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 1, 19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 10, 10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 20, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "", 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 2, -2);
+}
+
+
+void test9()
+{
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 4, -4);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 5, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 5, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 9, -9);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 10, -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghijklmnopqrst", 1, 1, "", 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 2, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 4, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 9, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "", 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 2, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 4, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 9, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "", 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 2, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 4, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 9, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 2, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 4, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 9, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 2, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 4, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 5, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 9, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 10, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 19, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 20, 1);
+    test("abcdefghijklmnopqrst", 10, 0, "", 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 2, -2);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 4, -4);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 5, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 1, -1);
+}
+
+
+void test10()
+{
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 5, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 9, -9);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 10, -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghijklmnopqrst", 10, 1, "", 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 2, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 4, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 9, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 19, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 20, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "", 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 2, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 4, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 9, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 19, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 20, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "", 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 2, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 4, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 9, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 19, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 20, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 2, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 4, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 9, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 19, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 20, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 2, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 4, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 5, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 9, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 19, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 20, 10);
+    test("abcdefghijklmnopqrst", 19, 0, "", 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 2, -2);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 4, -4);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 5, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 5, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 9, -9);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 10, -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 0, 0);
+}
+
+
+void test11()
+{
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghijklmnopqrst", 19, 1, "", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 1, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 2, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 4, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 5, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 1, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 5, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 9, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 10, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 1, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 10, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 19, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 20, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 1, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 2, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 4, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 5, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 1, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 5, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 9, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 10, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 1, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 10, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 19, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 20, 19);
+    test("abcdefghijklmnopqrst", 20, 0, "", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 2, -2);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 4, -4);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 5, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 5, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 9, -9);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 10, -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghijklmnopqrst", 20, 1, "", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 2, -2);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 4, -4);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 5, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 5, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 9, -9);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 10, -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 10, -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 19, -19);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 20, -20);
+    test("abcdefghijklmnopqrst", 21, 0, "", 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 4, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 5, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 5, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 9, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 10, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 10, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 19, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 20, 0);
+    }
+
+
+int main () {
+    test0();
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+    test6();
+    test7();
+    test8();
+    test9();
+    test10();
+    test11();
+    
+    {
+    test("", 0, 0, "abcde", 0, 0);
+    test("", 0, 0, "abcde", 1, -1);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 10, -10);
+    }
+
+    {
+    test(L"", 0, 0, L"abcde", 0, 0);
+    test(L"", 0, 0, L"abcde", 1, -1);
+    test(L"abcdefghijklmnopqrst", 21, 0, L"abcde", 0, 0);
+    test(L"abcdefghijklmnopqrst", 21, 0, L"abcde", 1, 0);
+    test(L"abcdefghijklmnopqrst", 10, 0, L"abcdefghij", 10, -10);
+    }
+
+#if __cplusplus >= 201103L
+    {
+    test(U"", 0, 0, U"abcde", 0, 0);
+    test(U"", 0, 0, U"abcde", 1, -1);
+    test(U"abcdefghijklmnopqrst", 21, 0, U"abcde", 0, 0);
+    test(U"abcdefghijklmnopqrst", 21, 0, U"abcde", 1, 0);
+    test(U"abcdefghijklmnopqrst", 10, 0, U"abcdefghij", 10, -10);
+    }
+
+    {
+    test(U"", 0, 0, U"abcde", 0, 0);
+    test(U"", 0, 0, U"abcde", 1, -1);
+    test(U"abcdefghijklmnopqrst", 21, 0, U"abcde", 0, 0);
+    test(U"abcdefghijklmnopqrst", 21, 0, U"abcde", 1, 0);
+    test(U"abcdefghijklmnopqrst", 10, 0, U"abcdefghij", 10, -10);
+    }
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1;
+    constexpr SV  sv2 { "abcdefghijklmnopqrst", 21 };
+    static_assert ( sv1.compare(0, 0, "abcde", 0) == 0, "" );
+    static_assert ( sv1.compare(0, 0, "abcde", 1) == -1, "" );
+    static_assert ( sv2.compare(0, 0, "abcde", 1, 0) == 0, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp b/test/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp
new file mode 100644
index 0000000..33407ef
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/compare.size_size_sv_size_size.pass.cpp
@@ -0,0 +1,5843 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr int compare(size_type pos1, size_type n1, basic_string_view str,
+//             size_type pos2, size_type n2) const;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); }
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv1, size_t pos1, size_t n1,
+             std::experimental::basic_string_view<CharT> sv2, size_t pos2, size_t n2,
+             int expected ) {
+
+    try
+    {
+        assert ( sign( sv1.compare(pos1, n1, sv2, pos2, n2)) == sign(expected));
+        assert(pos1 <= sv1.size());
+        assert(pos2 <= sv2.size());
+    }
+    catch (const std::out_of_range&) { assert(pos1 > sv1.size() || pos2 > sv2.size()); }
+}
+
+
+template<typename CharT>
+void test ( const CharT *s1, size_t pos1, size_t n1, 
+            const CharT *s2, size_t pos2, size_t n2, 
+            int expected ) {
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    
+    string_view_t sv1 ( s1 );
+    string_view_t sv2 ( s2 );
+    test1(sv1, pos1, n1, sv2, pos2, n2, expected);
+}
+
+void test0()
+{
+    test("", 0, 0, "", 0, 0, 0);
+    test("", 0, 0, "", 0, 1, 0);
+    test("", 0, 0, "", 1, 0, 0);
+    test("", 0, 0, "abcde", 0, 0, 0);
+    test("", 0, 0, "abcde", 0, 1, -1);
+    test("", 0, 0, "abcde", 0, 2, -2);
+    test("", 0, 0, "abcde", 0, 4, -4);
+    test("", 0, 0, "abcde", 0, 5, -5);
+    test("", 0, 0, "abcde", 0, 6, -5);
+    test("", 0, 0, "abcde", 1, 0, 0);
+    test("", 0, 0, "abcde", 1, 1, -1);
+    test("", 0, 0, "abcde", 1, 2, -2);
+    test("", 0, 0, "abcde", 1, 3, -3);
+    test("", 0, 0, "abcde", 1, 4, -4);
+    test("", 0, 0, "abcde", 1, 5, -4);
+    test("", 0, 0, "abcde", 2, 0, 0);
+    test("", 0, 0, "abcde", 2, 1, -1);
+    test("", 0, 0, "abcde", 2, 2, -2);
+    test("", 0, 0, "abcde", 2, 3, -3);
+    test("", 0, 0, "abcde", 2, 4, -3);
+    test("", 0, 0, "abcde", 4, 0, 0);
+    test("", 0, 0, "abcde", 4, 1, -1);
+    test("", 0, 0, "abcde", 4, 2, -1);
+    test("", 0, 0, "abcde", 5, 0, 0);
+    test("", 0, 0, "abcde", 5, 1, 0);
+    test("", 0, 0, "abcde", 6, 0, 0);
+    test("", 0, 0, "abcdefghij", 0, 0, 0);
+    test("", 0, 0, "abcdefghij", 0, 1, -1);
+    test("", 0, 0, "abcdefghij", 0, 5, -5);
+    test("", 0, 0, "abcdefghij", 0, 9, -9);
+    test("", 0, 0, "abcdefghij", 0, 10, -10);
+    test("", 0, 0, "abcdefghij", 0, 11, -10);
+    test("", 0, 0, "abcdefghij", 1, 0, 0);
+    test("", 0, 0, "abcdefghij", 1, 1, -1);
+    test("", 0, 0, "abcdefghij", 1, 4, -4);
+    test("", 0, 0, "abcdefghij", 1, 8, -8);
+    test("", 0, 0, "abcdefghij", 1, 9, -9);
+    test("", 0, 0, "abcdefghij", 1, 10, -9);
+    test("", 0, 0, "abcdefghij", 5, 0, 0);
+    test("", 0, 0, "abcdefghij", 5, 1, -1);
+    test("", 0, 0, "abcdefghij", 5, 2, -2);
+    test("", 0, 0, "abcdefghij", 5, 4, -4);
+    test("", 0, 0, "abcdefghij", 5, 5, -5);
+    test("", 0, 0, "abcdefghij", 5, 6, -5);
+    test("", 0, 0, "abcdefghij", 9, 0, 0);
+    test("", 0, 0, "abcdefghij", 9, 1, -1);
+    test("", 0, 0, "abcdefghij", 9, 2, -1);
+    test("", 0, 0, "abcdefghij", 10, 0, 0);
+    test("", 0, 0, "abcdefghij", 10, 1, 0);
+    test("", 0, 0, "abcdefghij", 11, 0, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("", 0, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("", 0, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("", 0, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("", 0, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("", 0, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("", 0, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("", 0, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("", 0, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("", 0, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("", 0, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("", 0, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("", 0, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("", 0, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("", 0, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("", 0, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("", 0, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("", 0, 1, "", 0, 0, 0);
+    test("", 0, 1, "", 0, 1, 0);
+    test("", 0, 1, "", 1, 0, 0);
+    test("", 0, 1, "abcde", 0, 0, 0);
+    test("", 0, 1, "abcde", 0, 1, -1);
+    test("", 0, 1, "abcde", 0, 2, -2);
+    test("", 0, 1, "abcde", 0, 4, -4);
+    test("", 0, 1, "abcde", 0, 5, -5);
+    test("", 0, 1, "abcde", 0, 6, -5);
+    test("", 0, 1, "abcde", 1, 0, 0);
+    test("", 0, 1, "abcde", 1, 1, -1);
+    test("", 0, 1, "abcde", 1, 2, -2);
+    test("", 0, 1, "abcde", 1, 3, -3);
+    test("", 0, 1, "abcde", 1, 4, -4);
+    test("", 0, 1, "abcde", 1, 5, -4);
+    test("", 0, 1, "abcde", 2, 0, 0);
+    test("", 0, 1, "abcde", 2, 1, -1);
+    test("", 0, 1, "abcde", 2, 2, -2);
+    test("", 0, 1, "abcde", 2, 3, -3);
+    test("", 0, 1, "abcde", 2, 4, -3);
+    test("", 0, 1, "abcde", 4, 0, 0);
+    test("", 0, 1, "abcde", 4, 1, -1);
+    test("", 0, 1, "abcde", 4, 2, -1);
+    test("", 0, 1, "abcde", 5, 0, 0);
+    test("", 0, 1, "abcde", 5, 1, 0);
+    test("", 0, 1, "abcde", 6, 0, 0);
+}
+
+void test1()
+{
+    test("", 0, 1, "abcdefghij", 0, 0, 0);
+    test("", 0, 1, "abcdefghij", 0, 1, -1);
+    test("", 0, 1, "abcdefghij", 0, 5, -5);
+    test("", 0, 1, "abcdefghij", 0, 9, -9);
+    test("", 0, 1, "abcdefghij", 0, 10, -10);
+    test("", 0, 1, "abcdefghij", 0, 11, -10);
+    test("", 0, 1, "abcdefghij", 1, 0, 0);
+    test("", 0, 1, "abcdefghij", 1, 1, -1);
+    test("", 0, 1, "abcdefghij", 1, 4, -4);
+    test("", 0, 1, "abcdefghij", 1, 8, -8);
+    test("", 0, 1, "abcdefghij", 1, 9, -9);
+    test("", 0, 1, "abcdefghij", 1, 10, -9);
+    test("", 0, 1, "abcdefghij", 5, 0, 0);
+    test("", 0, 1, "abcdefghij", 5, 1, -1);
+    test("", 0, 1, "abcdefghij", 5, 2, -2);
+    test("", 0, 1, "abcdefghij", 5, 4, -4);
+    test("", 0, 1, "abcdefghij", 5, 5, -5);
+    test("", 0, 1, "abcdefghij", 5, 6, -5);
+    test("", 0, 1, "abcdefghij", 9, 0, 0);
+    test("", 0, 1, "abcdefghij", 9, 1, -1);
+    test("", 0, 1, "abcdefghij", 9, 2, -1);
+    test("", 0, 1, "abcdefghij", 10, 0, 0);
+    test("", 0, 1, "abcdefghij", 10, 1, 0);
+    test("", 0, 1, "abcdefghij", 11, 0, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("", 0, 1, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("", 0, 1, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("", 0, 1, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("", 0, 1, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("", 0, 1, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("", 0, 1, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("", 0, 1, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("", 0, 1, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("", 0, 1, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("", 0, 1, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("", 0, 1, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("", 0, 1, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("", 0, 1, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("", 0, 1, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("", 0, 1, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("", 0, 1, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("", 0, 1, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("", 0, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("", 1, 0, "", 0, 0, 0);
+    test("", 1, 0, "", 0, 1, 0);
+    test("", 1, 0, "", 1, 0, 0);
+    test("", 1, 0, "abcde", 0, 0, 0);
+    test("", 1, 0, "abcde", 0, 1, 0);
+    test("", 1, 0, "abcde", 0, 2, 0);
+    test("", 1, 0, "abcde", 0, 4, 0);
+    test("", 1, 0, "abcde", 0, 5, 0);
+    test("", 1, 0, "abcde", 0, 6, 0);
+    test("", 1, 0, "abcde", 1, 0, 0);
+    test("", 1, 0, "abcde", 1, 1, 0);
+    test("", 1, 0, "abcde", 1, 2, 0);
+    test("", 1, 0, "abcde", 1, 3, 0);
+    test("", 1, 0, "abcde", 1, 4, 0);
+    test("", 1, 0, "abcde", 1, 5, 0);
+    test("", 1, 0, "abcde", 2, 0, 0);
+    test("", 1, 0, "abcde", 2, 1, 0);
+    test("", 1, 0, "abcde", 2, 2, 0);
+    test("", 1, 0, "abcde", 2, 3, 0);
+    test("", 1, 0, "abcde", 2, 4, 0);
+    test("", 1, 0, "abcde", 4, 0, 0);
+    test("", 1, 0, "abcde", 4, 1, 0);
+    test("", 1, 0, "abcde", 4, 2, 0);
+    test("", 1, 0, "abcde", 5, 0, 0);
+    test("", 1, 0, "abcde", 5, 1, 0);
+    test("", 1, 0, "abcde", 6, 0, 0);
+    test("", 1, 0, "abcdefghij", 0, 0, 0);
+    test("", 1, 0, "abcdefghij", 0, 1, 0);
+    test("", 1, 0, "abcdefghij", 0, 5, 0);
+    test("", 1, 0, "abcdefghij", 0, 9, 0);
+    test("", 1, 0, "abcdefghij", 0, 10, 0);
+    test("", 1, 0, "abcdefghij", 0, 11, 0);
+    test("", 1, 0, "abcdefghij", 1, 0, 0);
+    test("", 1, 0, "abcdefghij", 1, 1, 0);
+    test("", 1, 0, "abcdefghij", 1, 4, 0);
+    test("", 1, 0, "abcdefghij", 1, 8, 0);
+    test("", 1, 0, "abcdefghij", 1, 9, 0);
+    test("", 1, 0, "abcdefghij", 1, 10, 0);
+    test("", 1, 0, "abcdefghij", 5, 0, 0);
+    test("", 1, 0, "abcdefghij", 5, 1, 0);
+    test("", 1, 0, "abcdefghij", 5, 2, 0);
+    test("", 1, 0, "abcdefghij", 5, 4, 0);
+    test("", 1, 0, "abcdefghij", 5, 5, 0);
+    test("", 1, 0, "abcdefghij", 5, 6, 0);
+    test("", 1, 0, "abcdefghij", 9, 0, 0);
+    test("", 1, 0, "abcdefghij", 9, 1, 0);
+    test("", 1, 0, "abcdefghij", 9, 2, 0);
+    test("", 1, 0, "abcdefghij", 10, 0, 0);
+    test("", 1, 0, "abcdefghij", 10, 1, 0);
+    test("", 1, 0, "abcdefghij", 11, 0, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0, 1, 0);
+}
+
+void test2()
+{
+    test("", 1, 0, "abcdefghijklmnopqrst", 0, 10, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0, 19, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0, 20, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 0, 21, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 1, 1, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 1, 9, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 1, 18, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 1, 19, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 1, 20, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 10, 1, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 10, 5, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 10, 9, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 10, 10, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 10, 11, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 19, 1, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 19, 2, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("", 1, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 0, 0, "", 0, 0, 0);
+    test("abcde", 0, 0, "", 0, 1, 0);
+    test("abcde", 0, 0, "", 1, 0, 0);
+    test("abcde", 0, 0, "abcde", 0, 0, 0);
+    test("abcde", 0, 0, "abcde", 0, 1, -1);
+    test("abcde", 0, 0, "abcde", 0, 2, -2);
+    test("abcde", 0, 0, "abcde", 0, 4, -4);
+    test("abcde", 0, 0, "abcde", 0, 5, -5);
+    test("abcde", 0, 0, "abcde", 0, 6, -5);
+    test("abcde", 0, 0, "abcde", 1, 0, 0);
+    test("abcde", 0, 0, "abcde", 1, 1, -1);
+    test("abcde", 0, 0, "abcde", 1, 2, -2);
+    test("abcde", 0, 0, "abcde", 1, 3, -3);
+    test("abcde", 0, 0, "abcde", 1, 4, -4);
+    test("abcde", 0, 0, "abcde", 1, 5, -4);
+    test("abcde", 0, 0, "abcde", 2, 0, 0);
+    test("abcde", 0, 0, "abcde", 2, 1, -1);
+    test("abcde", 0, 0, "abcde", 2, 2, -2);
+    test("abcde", 0, 0, "abcde", 2, 3, -3);
+    test("abcde", 0, 0, "abcde", 2, 4, -3);
+    test("abcde", 0, 0, "abcde", 4, 0, 0);
+    test("abcde", 0, 0, "abcde", 4, 1, -1);
+    test("abcde", 0, 0, "abcde", 4, 2, -1);
+    test("abcde", 0, 0, "abcde", 5, 0, 0);
+    test("abcde", 0, 0, "abcde", 5, 1, 0);
+    test("abcde", 0, 0, "abcde", 6, 0, 0);
+    test("abcde", 0, 0, "abcdefghij", 0, 0, 0);
+    test("abcde", 0, 0, "abcdefghij", 0, 1, -1);
+    test("abcde", 0, 0, "abcdefghij", 0, 5, -5);
+    test("abcde", 0, 0, "abcdefghij", 0, 9, -9);
+    test("abcde", 0, 0, "abcdefghij", 0, 10, -10);
+    test("abcde", 0, 0, "abcdefghij", 0, 11, -10);
+    test("abcde", 0, 0, "abcdefghij", 1, 0, 0);
+    test("abcde", 0, 0, "abcdefghij", 1, 1, -1);
+    test("abcde", 0, 0, "abcdefghij", 1, 4, -4);
+    test("abcde", 0, 0, "abcdefghij", 1, 8, -8);
+    test("abcde", 0, 0, "abcdefghij", 1, 9, -9);
+    test("abcde", 0, 0, "abcdefghij", 1, 10, -9);
+    test("abcde", 0, 0, "abcdefghij", 5, 0, 0);
+    test("abcde", 0, 0, "abcdefghij", 5, 1, -1);
+    test("abcde", 0, 0, "abcdefghij", 5, 2, -2);
+    test("abcde", 0, 0, "abcdefghij", 5, 4, -4);
+    test("abcde", 0, 0, "abcdefghij", 5, 5, -5);
+    test("abcde", 0, 0, "abcdefghij", 5, 6, -5);
+    test("abcde", 0, 0, "abcdefghij", 9, 0, 0);
+    test("abcde", 0, 0, "abcdefghij", 9, 1, -1);
+    test("abcde", 0, 0, "abcdefghij", 9, 2, -1);
+    test("abcde", 0, 0, "abcdefghij", 10, 0, 0);
+    test("abcde", 0, 0, "abcdefghij", 10, 1, 0);
+    test("abcde", 0, 0, "abcdefghij", 11, 0, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcde", 0, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 0, 1, "", 0, 0, 1);
+    test("abcde", 0, 1, "", 0, 1, 1);
+    test("abcde", 0, 1, "", 1, 0, 0);
+    test("abcde", 0, 1, "abcde", 0, 0, 1);
+}
+
+void test3()
+{
+    test("abcde", 0, 1, "abcde", 0, 1, 0);
+    test("abcde", 0, 1, "abcde", 0, 2, -1);
+    test("abcde", 0, 1, "abcde", 0, 4, -3);
+    test("abcde", 0, 1, "abcde", 0, 5, -4);
+    test("abcde", 0, 1, "abcde", 0, 6, -4);
+    test("abcde", 0, 1, "abcde", 1, 0, 1);
+    test("abcde", 0, 1, "abcde", 1, 1, -1);
+    test("abcde", 0, 1, "abcde", 1, 2, -1);
+    test("abcde", 0, 1, "abcde", 1, 3, -1);
+    test("abcde", 0, 1, "abcde", 1, 4, -1);
+    test("abcde", 0, 1, "abcde", 1, 5, -1);
+    test("abcde", 0, 1, "abcde", 2, 0, 1);
+    test("abcde", 0, 1, "abcde", 2, 1, -2);
+    test("abcde", 0, 1, "abcde", 2, 2, -2);
+    test("abcde", 0, 1, "abcde", 2, 3, -2);
+    test("abcde", 0, 1, "abcde", 2, 4, -2);
+    test("abcde", 0, 1, "abcde", 4, 0, 1);
+    test("abcde", 0, 1, "abcde", 4, 1, -4);
+    test("abcde", 0, 1, "abcde", 4, 2, -4);
+    test("abcde", 0, 1, "abcde", 5, 0, 1);
+    test("abcde", 0, 1, "abcde", 5, 1, 1);
+    test("abcde", 0, 1, "abcde", 6, 0, 0);
+    test("abcde", 0, 1, "abcdefghij", 0, 0, 1);
+    test("abcde", 0, 1, "abcdefghij", 0, 1, 0);
+    test("abcde", 0, 1, "abcdefghij", 0, 5, -4);
+    test("abcde", 0, 1, "abcdefghij", 0, 9, -8);
+    test("abcde", 0, 1, "abcdefghij", 0, 10, -9);
+    test("abcde", 0, 1, "abcdefghij", 0, 11, -9);
+    test("abcde", 0, 1, "abcdefghij", 1, 0, 1);
+    test("abcde", 0, 1, "abcdefghij", 1, 1, -1);
+    test("abcde", 0, 1, "abcdefghij", 1, 4, -1);
+    test("abcde", 0, 1, "abcdefghij", 1, 8, -1);
+    test("abcde", 0, 1, "abcdefghij", 1, 9, -1);
+    test("abcde", 0, 1, "abcdefghij", 1, 10, -1);
+    test("abcde", 0, 1, "abcdefghij", 5, 0, 1);
+    test("abcde", 0, 1, "abcdefghij", 5, 1, -5);
+    test("abcde", 0, 1, "abcdefghij", 5, 2, -5);
+    test("abcde", 0, 1, "abcdefghij", 5, 4, -5);
+    test("abcde", 0, 1, "abcdefghij", 5, 5, -5);
+    test("abcde", 0, 1, "abcdefghij", 5, 6, -5);
+    test("abcde", 0, 1, "abcdefghij", 9, 0, 1);
+    test("abcde", 0, 1, "abcdefghij", 9, 1, -9);
+    test("abcde", 0, 1, "abcdefghij", 9, 2, -9);
+    test("abcde", 0, 1, "abcdefghij", 10, 0, 1);
+    test("abcde", 0, 1, "abcdefghij", 10, 1, 1);
+    test("abcde", 0, 1, "abcdefghij", 11, 0, 0);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 0, 1, 0);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 0, 10, -9);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 0, 19, -18);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 0, 20, -19);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 0, 21, -19);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcde", 0, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 0, 2, "", 0, 0, 2);
+    test("abcde", 0, 2, "", 0, 1, 2);
+    test("abcde", 0, 2, "", 1, 0, 0);
+    test("abcde", 0, 2, "abcde", 0, 0, 2);
+    test("abcde", 0, 2, "abcde", 0, 1, 1);
+    test("abcde", 0, 2, "abcde", 0, 2, 0);
+    test("abcde", 0, 2, "abcde", 0, 4, -2);
+    test("abcde", 0, 2, "abcde", 0, 5, -3);
+    test("abcde", 0, 2, "abcde", 0, 6, -3);
+    test("abcde", 0, 2, "abcde", 1, 0, 2);
+    test("abcde", 0, 2, "abcde", 1, 1, -1);
+    test("abcde", 0, 2, "abcde", 1, 2, -1);
+    test("abcde", 0, 2, "abcde", 1, 3, -1);
+    test("abcde", 0, 2, "abcde", 1, 4, -1);
+    test("abcde", 0, 2, "abcde", 1, 5, -1);
+    test("abcde", 0, 2, "abcde", 2, 0, 2);
+    test("abcde", 0, 2, "abcde", 2, 1, -2);
+    test("abcde", 0, 2, "abcde", 2, 2, -2);
+    test("abcde", 0, 2, "abcde", 2, 3, -2);
+    test("abcde", 0, 2, "abcde", 2, 4, -2);
+    test("abcde", 0, 2, "abcde", 4, 0, 2);
+    test("abcde", 0, 2, "abcde", 4, 1, -4);
+    test("abcde", 0, 2, "abcde", 4, 2, -4);
+    test("abcde", 0, 2, "abcde", 5, 0, 2);
+    test("abcde", 0, 2, "abcde", 5, 1, 2);
+    test("abcde", 0, 2, "abcde", 6, 0, 0);
+    test("abcde", 0, 2, "abcdefghij", 0, 0, 2);
+    test("abcde", 0, 2, "abcdefghij", 0, 1, 1);
+    test("abcde", 0, 2, "abcdefghij", 0, 5, -3);
+    test("abcde", 0, 2, "abcdefghij", 0, 9, -7);
+}
+
+void test4()
+{
+    test("abcde", 0, 2, "abcdefghij", 0, 10, -8);
+    test("abcde", 0, 2, "abcdefghij", 0, 11, -8);
+    test("abcde", 0, 2, "abcdefghij", 1, 0, 2);
+    test("abcde", 0, 2, "abcdefghij", 1, 1, -1);
+    test("abcde", 0, 2, "abcdefghij", 1, 4, -1);
+    test("abcde", 0, 2, "abcdefghij", 1, 8, -1);
+    test("abcde", 0, 2, "abcdefghij", 1, 9, -1);
+    test("abcde", 0, 2, "abcdefghij", 1, 10, -1);
+    test("abcde", 0, 2, "abcdefghij", 5, 0, 2);
+    test("abcde", 0, 2, "abcdefghij", 5, 1, -5);
+    test("abcde", 0, 2, "abcdefghij", 5, 2, -5);
+    test("abcde", 0, 2, "abcdefghij", 5, 4, -5);
+    test("abcde", 0, 2, "abcdefghij", 5, 5, -5);
+    test("abcde", 0, 2, "abcdefghij", 5, 6, -5);
+    test("abcde", 0, 2, "abcdefghij", 9, 0, 2);
+    test("abcde", 0, 2, "abcdefghij", 9, 1, -9);
+    test("abcde", 0, 2, "abcdefghij", 9, 2, -9);
+    test("abcde", 0, 2, "abcdefghij", 10, 0, 2);
+    test("abcde", 0, 2, "abcdefghij", 10, 1, 2);
+    test("abcde", 0, 2, "abcdefghij", 11, 0, 0);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 0, 0, 2);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 0, 10, -8);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 0, 19, -17);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 0, 20, -18);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 0, 21, -18);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 1, 0, 2);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 10, 0, 2);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 19, 0, 2);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 20, 0, 2);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 20, 1, 2);
+    test("abcde", 0, 2, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 0, 4, "", 0, 0, 4);
+    test("abcde", 0, 4, "", 0, 1, 4);
+    test("abcde", 0, 4, "", 1, 0, 0);
+    test("abcde", 0, 4, "abcde", 0, 0, 4);
+    test("abcde", 0, 4, "abcde", 0, 1, 3);
+    test("abcde", 0, 4, "abcde", 0, 2, 2);
+    test("abcde", 0, 4, "abcde", 0, 4, 0);
+    test("abcde", 0, 4, "abcde", 0, 5, -1);
+    test("abcde", 0, 4, "abcde", 0, 6, -1);
+    test("abcde", 0, 4, "abcde", 1, 0, 4);
+    test("abcde", 0, 4, "abcde", 1, 1, -1);
+    test("abcde", 0, 4, "abcde", 1, 2, -1);
+    test("abcde", 0, 4, "abcde", 1, 3, -1);
+    test("abcde", 0, 4, "abcde", 1, 4, -1);
+    test("abcde", 0, 4, "abcde", 1, 5, -1);
+    test("abcde", 0, 4, "abcde", 2, 0, 4);
+    test("abcde", 0, 4, "abcde", 2, 1, -2);
+    test("abcde", 0, 4, "abcde", 2, 2, -2);
+    test("abcde", 0, 4, "abcde", 2, 3, -2);
+    test("abcde", 0, 4, "abcde", 2, 4, -2);
+    test("abcde", 0, 4, "abcde", 4, 0, 4);
+    test("abcde", 0, 4, "abcde", 4, 1, -4);
+    test("abcde", 0, 4, "abcde", 4, 2, -4);
+    test("abcde", 0, 4, "abcde", 5, 0, 4);
+    test("abcde", 0, 4, "abcde", 5, 1, 4);
+    test("abcde", 0, 4, "abcde", 6, 0, 0);
+    test("abcde", 0, 4, "abcdefghij", 0, 0, 4);
+    test("abcde", 0, 4, "abcdefghij", 0, 1, 3);
+    test("abcde", 0, 4, "abcdefghij", 0, 5, -1);
+    test("abcde", 0, 4, "abcdefghij", 0, 9, -5);
+    test("abcde", 0, 4, "abcdefghij", 0, 10, -6);
+    test("abcde", 0, 4, "abcdefghij", 0, 11, -6);
+    test("abcde", 0, 4, "abcdefghij", 1, 0, 4);
+    test("abcde", 0, 4, "abcdefghij", 1, 1, -1);
+    test("abcde", 0, 4, "abcdefghij", 1, 4, -1);
+    test("abcde", 0, 4, "abcdefghij", 1, 8, -1);
+    test("abcde", 0, 4, "abcdefghij", 1, 9, -1);
+    test("abcde", 0, 4, "abcdefghij", 1, 10, -1);
+    test("abcde", 0, 4, "abcdefghij", 5, 0, 4);
+    test("abcde", 0, 4, "abcdefghij", 5, 1, -5);
+    test("abcde", 0, 4, "abcdefghij", 5, 2, -5);
+    test("abcde", 0, 4, "abcdefghij", 5, 4, -5);
+    test("abcde", 0, 4, "abcdefghij", 5, 5, -5);
+    test("abcde", 0, 4, "abcdefghij", 5, 6, -5);
+    test("abcde", 0, 4, "abcdefghij", 9, 0, 4);
+    test("abcde", 0, 4, "abcdefghij", 9, 1, -9);
+    test("abcde", 0, 4, "abcdefghij", 9, 2, -9);
+    test("abcde", 0, 4, "abcdefghij", 10, 0, 4);
+    test("abcde", 0, 4, "abcdefghij", 10, 1, 4);
+    test("abcde", 0, 4, "abcdefghij", 11, 0, 0);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 0, 0, 4);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 0, 1, 3);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 0, 10, -6);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 0, 19, -15);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 0, 20, -16);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 0, 21, -16);
+}
+
+void test5()
+{
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 1, 0, 4);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 10, 0, 4);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 19, 0, 4);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 20, 0, 4);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 20, 1, 4);
+    test("abcde", 0, 4, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 0, 5, "", 0, 0, 5);
+    test("abcde", 0, 5, "", 0, 1, 5);
+    test("abcde", 0, 5, "", 1, 0, 0);
+    test("abcde", 0, 5, "abcde", 0, 0, 5);
+    test("abcde", 0, 5, "abcde", 0, 1, 4);
+    test("abcde", 0, 5, "abcde", 0, 2, 3);
+    test("abcde", 0, 5, "abcde", 0, 4, 1);
+    test("abcde", 0, 5, "abcde", 0, 5, 0);
+    test("abcde", 0, 5, "abcde", 0, 6, 0);
+    test("abcde", 0, 5, "abcde", 1, 0, 5);
+    test("abcde", 0, 5, "abcde", 1, 1, -1);
+    test("abcde", 0, 5, "abcde", 1, 2, -1);
+    test("abcde", 0, 5, "abcde", 1, 3, -1);
+    test("abcde", 0, 5, "abcde", 1, 4, -1);
+    test("abcde", 0, 5, "abcde", 1, 5, -1);
+    test("abcde", 0, 5, "abcde", 2, 0, 5);
+    test("abcde", 0, 5, "abcde", 2, 1, -2);
+    test("abcde", 0, 5, "abcde", 2, 2, -2);
+    test("abcde", 0, 5, "abcde", 2, 3, -2);
+    test("abcde", 0, 5, "abcde", 2, 4, -2);
+    test("abcde", 0, 5, "abcde", 4, 0, 5);
+    test("abcde", 0, 5, "abcde", 4, 1, -4);
+    test("abcde", 0, 5, "abcde", 4, 2, -4);
+    test("abcde", 0, 5, "abcde", 5, 0, 5);
+    test("abcde", 0, 5, "abcde", 5, 1, 5);
+    test("abcde", 0, 5, "abcde", 6, 0, 0);
+    test("abcde", 0, 5, "abcdefghij", 0, 0, 5);
+    test("abcde", 0, 5, "abcdefghij", 0, 1, 4);
+    test("abcde", 0, 5, "abcdefghij", 0, 5, 0);
+    test("abcde", 0, 5, "abcdefghij", 0, 9, -4);
+    test("abcde", 0, 5, "abcdefghij", 0, 10, -5);
+    test("abcde", 0, 5, "abcdefghij", 0, 11, -5);
+    test("abcde", 0, 5, "abcdefghij", 1, 0, 5);
+    test("abcde", 0, 5, "abcdefghij", 1, 1, -1);
+    test("abcde", 0, 5, "abcdefghij", 1, 4, -1);
+    test("abcde", 0, 5, "abcdefghij", 1, 8, -1);
+    test("abcde", 0, 5, "abcdefghij", 1, 9, -1);
+    test("abcde", 0, 5, "abcdefghij", 1, 10, -1);
+    test("abcde", 0, 5, "abcdefghij", 5, 0, 5);
+    test("abcde", 0, 5, "abcdefghij", 5, 1, -5);
+    test("abcde", 0, 5, "abcdefghij", 5, 2, -5);
+    test("abcde", 0, 5, "abcdefghij", 5, 4, -5);
+    test("abcde", 0, 5, "abcdefghij", 5, 5, -5);
+    test("abcde", 0, 5, "abcdefghij", 5, 6, -5);
+    test("abcde", 0, 5, "abcdefghij", 9, 0, 5);
+    test("abcde", 0, 5, "abcdefghij", 9, 1, -9);
+    test("abcde", 0, 5, "abcdefghij", 9, 2, -9);
+    test("abcde", 0, 5, "abcdefghij", 10, 0, 5);
+    test("abcde", 0, 5, "abcdefghij", 10, 1, 5);
+    test("abcde", 0, 5, "abcdefghij", 11, 0, 0);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 0, 0, 5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 0, 1, 4);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 0, 10, -5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 0, 19, -14);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 0, 20, -15);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 0, 21, -15);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 1, 0, 5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 10, 0, 5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 19, 0, 5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 20, 0, 5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 20, 1, 5);
+    test("abcde", 0, 5, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 0, 6, "", 0, 0, 5);
+    test("abcde", 0, 6, "", 0, 1, 5);
+    test("abcde", 0, 6, "", 1, 0, 0);
+    test("abcde", 0, 6, "abcde", 0, 0, 5);
+    test("abcde", 0, 6, "abcde", 0, 1, 4);
+    test("abcde", 0, 6, "abcde", 0, 2, 3);
+    test("abcde", 0, 6, "abcde", 0, 4, 1);
+    test("abcde", 0, 6, "abcde", 0, 5, 0);
+}
+
+void test6()
+{
+    test("abcde", 0, 6, "abcde", 0, 6, 0);
+    test("abcde", 0, 6, "abcde", 1, 0, 5);
+    test("abcde", 0, 6, "abcde", 1, 1, -1);
+    test("abcde", 0, 6, "abcde", 1, 2, -1);
+    test("abcde", 0, 6, "abcde", 1, 3, -1);
+    test("abcde", 0, 6, "abcde", 1, 4, -1);
+    test("abcde", 0, 6, "abcde", 1, 5, -1);
+    test("abcde", 0, 6, "abcde", 2, 0, 5);
+    test("abcde", 0, 6, "abcde", 2, 1, -2);
+    test("abcde", 0, 6, "abcde", 2, 2, -2);
+    test("abcde", 0, 6, "abcde", 2, 3, -2);
+    test("abcde", 0, 6, "abcde", 2, 4, -2);
+    test("abcde", 0, 6, "abcde", 4, 0, 5);
+    test("abcde", 0, 6, "abcde", 4, 1, -4);
+    test("abcde", 0, 6, "abcde", 4, 2, -4);
+    test("abcde", 0, 6, "abcde", 5, 0, 5);
+    test("abcde", 0, 6, "abcde", 5, 1, 5);
+    test("abcde", 0, 6, "abcde", 6, 0, 0);
+    test("abcde", 0, 6, "abcdefghij", 0, 0, 5);
+    test("abcde", 0, 6, "abcdefghij", 0, 1, 4);
+    test("abcde", 0, 6, "abcdefghij", 0, 5, 0);
+    test("abcde", 0, 6, "abcdefghij", 0, 9, -4);
+    test("abcde", 0, 6, "abcdefghij", 0, 10, -5);
+    test("abcde", 0, 6, "abcdefghij", 0, 11, -5);
+    test("abcde", 0, 6, "abcdefghij", 1, 0, 5);
+    test("abcde", 0, 6, "abcdefghij", 1, 1, -1);
+    test("abcde", 0, 6, "abcdefghij", 1, 4, -1);
+    test("abcde", 0, 6, "abcdefghij", 1, 8, -1);
+    test("abcde", 0, 6, "abcdefghij", 1, 9, -1);
+    test("abcde", 0, 6, "abcdefghij", 1, 10, -1);
+    test("abcde", 0, 6, "abcdefghij", 5, 0, 5);
+    test("abcde", 0, 6, "abcdefghij", 5, 1, -5);
+    test("abcde", 0, 6, "abcdefghij", 5, 2, -5);
+    test("abcde", 0, 6, "abcdefghij", 5, 4, -5);
+    test("abcde", 0, 6, "abcdefghij", 5, 5, -5);
+    test("abcde", 0, 6, "abcdefghij", 5, 6, -5);
+    test("abcde", 0, 6, "abcdefghij", 9, 0, 5);
+    test("abcde", 0, 6, "abcdefghij", 9, 1, -9);
+    test("abcde", 0, 6, "abcdefghij", 9, 2, -9);
+    test("abcde", 0, 6, "abcdefghij", 10, 0, 5);
+    test("abcde", 0, 6, "abcdefghij", 10, 1, 5);
+    test("abcde", 0, 6, "abcdefghij", 11, 0, 0);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 0, 0, 5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 0, 1, 4);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 0, 10, -5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 0, 19, -14);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 0, 20, -15);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 0, 21, -15);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 1, 0, 5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 10, 0, 5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 19, 0, 5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 20, 0, 5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 20, 1, 5);
+    test("abcde", 0, 6, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 1, 0, "", 0, 0, 0);
+    test("abcde", 1, 0, "", 0, 1, 0);
+    test("abcde", 1, 0, "", 1, 0, 0);
+    test("abcde", 1, 0, "abcde", 0, 0, 0);
+    test("abcde", 1, 0, "abcde", 0, 1, -1);
+    test("abcde", 1, 0, "abcde", 0, 2, -2);
+    test("abcde", 1, 0, "abcde", 0, 4, -4);
+    test("abcde", 1, 0, "abcde", 0, 5, -5);
+    test("abcde", 1, 0, "abcde", 0, 6, -5);
+    test("abcde", 1, 0, "abcde", 1, 0, 0);
+    test("abcde", 1, 0, "abcde", 1, 1, -1);
+    test("abcde", 1, 0, "abcde", 1, 2, -2);
+    test("abcde", 1, 0, "abcde", 1, 3, -3);
+    test("abcde", 1, 0, "abcde", 1, 4, -4);
+    test("abcde", 1, 0, "abcde", 1, 5, -4);
+    test("abcde", 1, 0, "abcde", 2, 0, 0);
+    test("abcde", 1, 0, "abcde", 2, 1, -1);
+    test("abcde", 1, 0, "abcde", 2, 2, -2);
+    test("abcde", 1, 0, "abcde", 2, 3, -3);
+    test("abcde", 1, 0, "abcde", 2, 4, -3);
+    test("abcde", 1, 0, "abcde", 4, 0, 0);
+    test("abcde", 1, 0, "abcde", 4, 1, -1);
+    test("abcde", 1, 0, "abcde", 4, 2, -1);
+    test("abcde", 1, 0, "abcde", 5, 0, 0);
+    test("abcde", 1, 0, "abcde", 5, 1, 0);
+    test("abcde", 1, 0, "abcde", 6, 0, 0);
+    test("abcde", 1, 0, "abcdefghij", 0, 0, 0);
+    test("abcde", 1, 0, "abcdefghij", 0, 1, -1);
+    test("abcde", 1, 0, "abcdefghij", 0, 5, -5);
+    test("abcde", 1, 0, "abcdefghij", 0, 9, -9);
+    test("abcde", 1, 0, "abcdefghij", 0, 10, -10);
+    test("abcde", 1, 0, "abcdefghij", 0, 11, -10);
+    test("abcde", 1, 0, "abcdefghij", 1, 0, 0);
+    test("abcde", 1, 0, "abcdefghij", 1, 1, -1);
+}
+
+void test7()
+{
+    test("abcde", 1, 0, "abcdefghij", 1, 4, -4);
+    test("abcde", 1, 0, "abcdefghij", 1, 8, -8);
+    test("abcde", 1, 0, "abcdefghij", 1, 9, -9);
+    test("abcde", 1, 0, "abcdefghij", 1, 10, -9);
+    test("abcde", 1, 0, "abcdefghij", 5, 0, 0);
+    test("abcde", 1, 0, "abcdefghij", 5, 1, -1);
+    test("abcde", 1, 0, "abcdefghij", 5, 2, -2);
+    test("abcde", 1, 0, "abcdefghij", 5, 4, -4);
+    test("abcde", 1, 0, "abcdefghij", 5, 5, -5);
+    test("abcde", 1, 0, "abcdefghij", 5, 6, -5);
+    test("abcde", 1, 0, "abcdefghij", 9, 0, 0);
+    test("abcde", 1, 0, "abcdefghij", 9, 1, -1);
+    test("abcde", 1, 0, "abcdefghij", 9, 2, -1);
+    test("abcde", 1, 0, "abcdefghij", 10, 0, 0);
+    test("abcde", 1, 0, "abcdefghij", 10, 1, 0);
+    test("abcde", 1, 0, "abcdefghij", 11, 0, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcde", 1, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 1, 1, "", 0, 0, 1);
+    test("abcde", 1, 1, "", 0, 1, 1);
+    test("abcde", 1, 1, "", 1, 0, 0);
+    test("abcde", 1, 1, "abcde", 0, 0, 1);
+    test("abcde", 1, 1, "abcde", 0, 1, 1);
+    test("abcde", 1, 1, "abcde", 0, 2, 1);
+    test("abcde", 1, 1, "abcde", 0, 4, 1);
+    test("abcde", 1, 1, "abcde", 0, 5, 1);
+    test("abcde", 1, 1, "abcde", 0, 6, 1);
+    test("abcde", 1, 1, "abcde", 1, 0, 1);
+    test("abcde", 1, 1, "abcde", 1, 1, 0);
+    test("abcde", 1, 1, "abcde", 1, 2, -1);
+    test("abcde", 1, 1, "abcde", 1, 3, -2);
+    test("abcde", 1, 1, "abcde", 1, 4, -3);
+    test("abcde", 1, 1, "abcde", 1, 5, -3);
+    test("abcde", 1, 1, "abcde", 2, 0, 1);
+    test("abcde", 1, 1, "abcde", 2, 1, -1);
+    test("abcde", 1, 1, "abcde", 2, 2, -1);
+    test("abcde", 1, 1, "abcde", 2, 3, -1);
+    test("abcde", 1, 1, "abcde", 2, 4, -1);
+    test("abcde", 1, 1, "abcde", 4, 0, 1);
+    test("abcde", 1, 1, "abcde", 4, 1, -3);
+    test("abcde", 1, 1, "abcde", 4, 2, -3);
+    test("abcde", 1, 1, "abcde", 5, 0, 1);
+    test("abcde", 1, 1, "abcde", 5, 1, 1);
+    test("abcde", 1, 1, "abcde", 6, 0, 0);
+    test("abcde", 1, 1, "abcdefghij", 0, 0, 1);
+    test("abcde", 1, 1, "abcdefghij", 0, 1, 1);
+    test("abcde", 1, 1, "abcdefghij", 0, 5, 1);
+    test("abcde", 1, 1, "abcdefghij", 0, 9, 1);
+    test("abcde", 1, 1, "abcdefghij", 0, 10, 1);
+    test("abcde", 1, 1, "abcdefghij", 0, 11, 1);
+    test("abcde", 1, 1, "abcdefghij", 1, 0, 1);
+    test("abcde", 1, 1, "abcdefghij", 1, 1, 0);
+    test("abcde", 1, 1, "abcdefghij", 1, 4, -3);
+    test("abcde", 1, 1, "abcdefghij", 1, 8, -7);
+    test("abcde", 1, 1, "abcdefghij", 1, 9, -8);
+    test("abcde", 1, 1, "abcdefghij", 1, 10, -8);
+    test("abcde", 1, 1, "abcdefghij", 5, 0, 1);
+    test("abcde", 1, 1, "abcdefghij", 5, 1, -4);
+    test("abcde", 1, 1, "abcdefghij", 5, 2, -4);
+    test("abcde", 1, 1, "abcdefghij", 5, 4, -4);
+    test("abcde", 1, 1, "abcdefghij", 5, 5, -4);
+    test("abcde", 1, 1, "abcdefghij", 5, 6, -4);
+    test("abcde", 1, 1, "abcdefghij", 9, 0, 1);
+    test("abcde", 1, 1, "abcdefghij", 9, 1, -8);
+    test("abcde", 1, 1, "abcdefghij", 9, 2, -8);
+    test("abcde", 1, 1, "abcdefghij", 10, 0, 1);
+    test("abcde", 1, 1, "abcdefghij", 10, 1, 1);
+    test("abcde", 1, 1, "abcdefghij", 11, 0, 0);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1, 1, 0);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1, 9, -8);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1, 18, -17);
+}
+
+void test8()
+{
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1, 19, -18);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 1, 20, -18);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcde", 1, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 1, 2, "", 0, 0, 2);
+    test("abcde", 1, 2, "", 0, 1, 2);
+    test("abcde", 1, 2, "", 1, 0, 0);
+    test("abcde", 1, 2, "abcde", 0, 0, 2);
+    test("abcde", 1, 2, "abcde", 0, 1, 1);
+    test("abcde", 1, 2, "abcde", 0, 2, 1);
+    test("abcde", 1, 2, "abcde", 0, 4, 1);
+    test("abcde", 1, 2, "abcde", 0, 5, 1);
+    test("abcde", 1, 2, "abcde", 0, 6, 1);
+    test("abcde", 1, 2, "abcde", 1, 0, 2);
+    test("abcde", 1, 2, "abcde", 1, 1, 1);
+    test("abcde", 1, 2, "abcde", 1, 2, 0);
+    test("abcde", 1, 2, "abcde", 1, 3, -1);
+    test("abcde", 1, 2, "abcde", 1, 4, -2);
+    test("abcde", 1, 2, "abcde", 1, 5, -2);
+    test("abcde", 1, 2, "abcde", 2, 0, 2);
+    test("abcde", 1, 2, "abcde", 2, 1, -1);
+    test("abcde", 1, 2, "abcde", 2, 2, -1);
+    test("abcde", 1, 2, "abcde", 2, 3, -1);
+    test("abcde", 1, 2, "abcde", 2, 4, -1);
+    test("abcde", 1, 2, "abcde", 4, 0, 2);
+    test("abcde", 1, 2, "abcde", 4, 1, -3);
+    test("abcde", 1, 2, "abcde", 4, 2, -3);
+    test("abcde", 1, 2, "abcde", 5, 0, 2);
+    test("abcde", 1, 2, "abcde", 5, 1, 2);
+    test("abcde", 1, 2, "abcde", 6, 0, 0);
+    test("abcde", 1, 2, "abcdefghij", 0, 0, 2);
+    test("abcde", 1, 2, "abcdefghij", 0, 1, 1);
+    test("abcde", 1, 2, "abcdefghij", 0, 5, 1);
+    test("abcde", 1, 2, "abcdefghij", 0, 9, 1);
+    test("abcde", 1, 2, "abcdefghij", 0, 10, 1);
+    test("abcde", 1, 2, "abcdefghij", 0, 11, 1);
+    test("abcde", 1, 2, "abcdefghij", 1, 0, 2);
+    test("abcde", 1, 2, "abcdefghij", 1, 1, 1);
+    test("abcde", 1, 2, "abcdefghij", 1, 4, -2);
+    test("abcde", 1, 2, "abcdefghij", 1, 8, -6);
+    test("abcde", 1, 2, "abcdefghij", 1, 9, -7);
+    test("abcde", 1, 2, "abcdefghij", 1, 10, -7);
+    test("abcde", 1, 2, "abcdefghij", 5, 0, 2);
+    test("abcde", 1, 2, "abcdefghij", 5, 1, -4);
+    test("abcde", 1, 2, "abcdefghij", 5, 2, -4);
+    test("abcde", 1, 2, "abcdefghij", 5, 4, -4);
+    test("abcde", 1, 2, "abcdefghij", 5, 5, -4);
+    test("abcde", 1, 2, "abcdefghij", 5, 6, -4);
+    test("abcde", 1, 2, "abcdefghij", 9, 0, 2);
+    test("abcde", 1, 2, "abcdefghij", 9, 1, -8);
+    test("abcde", 1, 2, "abcdefghij", 9, 2, -8);
+    test("abcde", 1, 2, "abcdefghij", 10, 0, 2);
+    test("abcde", 1, 2, "abcdefghij", 10, 1, 2);
+    test("abcde", 1, 2, "abcdefghij", 11, 0, 0);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 0, 0, 2);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1, 0, 2);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1, 1, 1);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1, 9, -7);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1, 18, -16);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1, 19, -17);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 1, 20, -17);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 10, 0, 2);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 19, 0, 2);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 20, 0, 2);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 20, 1, 2);
+    test("abcde", 1, 2, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 1, 3, "", 0, 0, 3);
+    test("abcde", 1, 3, "", 0, 1, 3);
+    test("abcde", 1, 3, "", 1, 0, 0);
+    test("abcde", 1, 3, "abcde", 0, 0, 3);
+    test("abcde", 1, 3, "abcde", 0, 1, 1);
+    test("abcde", 1, 3, "abcde", 0, 2, 1);
+    test("abcde", 1, 3, "abcde", 0, 4, 1);
+    test("abcde", 1, 3, "abcde", 0, 5, 1);
+    test("abcde", 1, 3, "abcde", 0, 6, 1);
+    test("abcde", 1, 3, "abcde", 1, 0, 3);
+    test("abcde", 1, 3, "abcde", 1, 1, 2);
+    test("abcde", 1, 3, "abcde", 1, 2, 1);
+}
+
+void test9()
+{
+    test("abcde", 1, 3, "abcde", 1, 3, 0);
+    test("abcde", 1, 3, "abcde", 1, 4, -1);
+    test("abcde", 1, 3, "abcde", 1, 5, -1);
+    test("abcde", 1, 3, "abcde", 2, 0, 3);
+    test("abcde", 1, 3, "abcde", 2, 1, -1);
+    test("abcde", 1, 3, "abcde", 2, 2, -1);
+    test("abcde", 1, 3, "abcde", 2, 3, -1);
+    test("abcde", 1, 3, "abcde", 2, 4, -1);
+    test("abcde", 1, 3, "abcde", 4, 0, 3);
+    test("abcde", 1, 3, "abcde", 4, 1, -3);
+    test("abcde", 1, 3, "abcde", 4, 2, -3);
+    test("abcde", 1, 3, "abcde", 5, 0, 3);
+    test("abcde", 1, 3, "abcde", 5, 1, 3);
+    test("abcde", 1, 3, "abcde", 6, 0, 0);
+    test("abcde", 1, 3, "abcdefghij", 0, 0, 3);
+    test("abcde", 1, 3, "abcdefghij", 0, 1, 1);
+    test("abcde", 1, 3, "abcdefghij", 0, 5, 1);
+    test("abcde", 1, 3, "abcdefghij", 0, 9, 1);
+    test("abcde", 1, 3, "abcdefghij", 0, 10, 1);
+    test("abcde", 1, 3, "abcdefghij", 0, 11, 1);
+    test("abcde", 1, 3, "abcdefghij", 1, 0, 3);
+    test("abcde", 1, 3, "abcdefghij", 1, 1, 2);
+    test("abcde", 1, 3, "abcdefghij", 1, 4, -1);
+    test("abcde", 1, 3, "abcdefghij", 1, 8, -5);
+    test("abcde", 1, 3, "abcdefghij", 1, 9, -6);
+    test("abcde", 1, 3, "abcdefghij", 1, 10, -6);
+    test("abcde", 1, 3, "abcdefghij", 5, 0, 3);
+    test("abcde", 1, 3, "abcdefghij", 5, 1, -4);
+    test("abcde", 1, 3, "abcdefghij", 5, 2, -4);
+    test("abcde", 1, 3, "abcdefghij", 5, 4, -4);
+    test("abcde", 1, 3, "abcdefghij", 5, 5, -4);
+    test("abcde", 1, 3, "abcdefghij", 5, 6, -4);
+    test("abcde", 1, 3, "abcdefghij", 9, 0, 3);
+    test("abcde", 1, 3, "abcdefghij", 9, 1, -8);
+    test("abcde", 1, 3, "abcdefghij", 9, 2, -8);
+    test("abcde", 1, 3, "abcdefghij", 10, 0, 3);
+    test("abcde", 1, 3, "abcdefghij", 10, 1, 3);
+    test("abcde", 1, 3, "abcdefghij", 11, 0, 0);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 0, 0, 3);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1, 0, 3);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1, 1, 2);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1, 9, -6);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1, 18, -15);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1, 19, -16);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 1, 20, -16);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 10, 0, 3);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 19, 0, 3);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 20, 0, 3);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 20, 1, 3);
+    test("abcde", 1, 3, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 1, 4, "", 0, 0, 4);
+    test("abcde", 1, 4, "", 0, 1, 4);
+    test("abcde", 1, 4, "", 1, 0, 0);
+    test("abcde", 1, 4, "abcde", 0, 0, 4);
+    test("abcde", 1, 4, "abcde", 0, 1, 1);
+    test("abcde", 1, 4, "abcde", 0, 2, 1);
+    test("abcde", 1, 4, "abcde", 0, 4, 1);
+    test("abcde", 1, 4, "abcde", 0, 5, 1);
+    test("abcde", 1, 4, "abcde", 0, 6, 1);
+    test("abcde", 1, 4, "abcde", 1, 0, 4);
+    test("abcde", 1, 4, "abcde", 1, 1, 3);
+    test("abcde", 1, 4, "abcde", 1, 2, 2);
+    test("abcde", 1, 4, "abcde", 1, 3, 1);
+    test("abcde", 1, 4, "abcde", 1, 4, 0);
+    test("abcde", 1, 4, "abcde", 1, 5, 0);
+    test("abcde", 1, 4, "abcde", 2, 0, 4);
+    test("abcde", 1, 4, "abcde", 2, 1, -1);
+    test("abcde", 1, 4, "abcde", 2, 2, -1);
+    test("abcde", 1, 4, "abcde", 2, 3, -1);
+    test("abcde", 1, 4, "abcde", 2, 4, -1);
+    test("abcde", 1, 4, "abcde", 4, 0, 4);
+    test("abcde", 1, 4, "abcde", 4, 1, -3);
+    test("abcde", 1, 4, "abcde", 4, 2, -3);
+    test("abcde", 1, 4, "abcde", 5, 0, 4);
+    test("abcde", 1, 4, "abcde", 5, 1, 4);
+    test("abcde", 1, 4, "abcde", 6, 0, 0);
+    test("abcde", 1, 4, "abcdefghij", 0, 0, 4);
+    test("abcde", 1, 4, "abcdefghij", 0, 1, 1);
+    test("abcde", 1, 4, "abcdefghij", 0, 5, 1);
+    test("abcde", 1, 4, "abcdefghij", 0, 9, 1);
+    test("abcde", 1, 4, "abcdefghij", 0, 10, 1);
+    test("abcde", 1, 4, "abcdefghij", 0, 11, 1);
+    test("abcde", 1, 4, "abcdefghij", 1, 0, 4);
+    test("abcde", 1, 4, "abcdefghij", 1, 1, 3);
+    test("abcde", 1, 4, "abcdefghij", 1, 4, 0);
+    test("abcde", 1, 4, "abcdefghij", 1, 8, -4);
+    test("abcde", 1, 4, "abcdefghij", 1, 9, -5);
+    test("abcde", 1, 4, "abcdefghij", 1, 10, -5);
+}
+
+void test10()
+{
+    test("abcde", 1, 4, "abcdefghij", 5, 0, 4);
+    test("abcde", 1, 4, "abcdefghij", 5, 1, -4);
+    test("abcde", 1, 4, "abcdefghij", 5, 2, -4);
+    test("abcde", 1, 4, "abcdefghij", 5, 4, -4);
+    test("abcde", 1, 4, "abcdefghij", 5, 5, -4);
+    test("abcde", 1, 4, "abcdefghij", 5, 6, -4);
+    test("abcde", 1, 4, "abcdefghij", 9, 0, 4);
+    test("abcde", 1, 4, "abcdefghij", 9, 1, -8);
+    test("abcde", 1, 4, "abcdefghij", 9, 2, -8);
+    test("abcde", 1, 4, "abcdefghij", 10, 0, 4);
+    test("abcde", 1, 4, "abcdefghij", 10, 1, 4);
+    test("abcde", 1, 4, "abcdefghij", 11, 0, 0);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 0, 0, 4);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1, 0, 4);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1, 1, 3);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1, 9, -5);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1, 18, -14);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1, 19, -15);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 1, 20, -15);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 10, 0, 4);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 19, 0, 4);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 20, 0, 4);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 20, 1, 4);
+    test("abcde", 1, 4, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 1, 5, "", 0, 0, 4);
+    test("abcde", 1, 5, "", 0, 1, 4);
+    test("abcde", 1, 5, "", 1, 0, 0);
+    test("abcde", 1, 5, "abcde", 0, 0, 4);
+    test("abcde", 1, 5, "abcde", 0, 1, 1);
+    test("abcde", 1, 5, "abcde", 0, 2, 1);
+    test("abcde", 1, 5, "abcde", 0, 4, 1);
+    test("abcde", 1, 5, "abcde", 0, 5, 1);
+    test("abcde", 1, 5, "abcde", 0, 6, 1);
+    test("abcde", 1, 5, "abcde", 1, 0, 4);
+    test("abcde", 1, 5, "abcde", 1, 1, 3);
+    test("abcde", 1, 5, "abcde", 1, 2, 2);
+    test("abcde", 1, 5, "abcde", 1, 3, 1);
+    test("abcde", 1, 5, "abcde", 1, 4, 0);
+    test("abcde", 1, 5, "abcde", 1, 5, 0);
+    test("abcde", 1, 5, "abcde", 2, 0, 4);
+    test("abcde", 1, 5, "abcde", 2, 1, -1);
+    test("abcde", 1, 5, "abcde", 2, 2, -1);
+    test("abcde", 1, 5, "abcde", 2, 3, -1);
+    test("abcde", 1, 5, "abcde", 2, 4, -1);
+    test("abcde", 1, 5, "abcde", 4, 0, 4);
+    test("abcde", 1, 5, "abcde", 4, 1, -3);
+    test("abcde", 1, 5, "abcde", 4, 2, -3);
+    test("abcde", 1, 5, "abcde", 5, 0, 4);
+    test("abcde", 1, 5, "abcde", 5, 1, 4);
+    test("abcde", 1, 5, "abcde", 6, 0, 0);
+    test("abcde", 1, 5, "abcdefghij", 0, 0, 4);
+    test("abcde", 1, 5, "abcdefghij", 0, 1, 1);
+    test("abcde", 1, 5, "abcdefghij", 0, 5, 1);
+    test("abcde", 1, 5, "abcdefghij", 0, 9, 1);
+    test("abcde", 1, 5, "abcdefghij", 0, 10, 1);
+    test("abcde", 1, 5, "abcdefghij", 0, 11, 1);
+    test("abcde", 1, 5, "abcdefghij", 1, 0, 4);
+    test("abcde", 1, 5, "abcdefghij", 1, 1, 3);
+    test("abcde", 1, 5, "abcdefghij", 1, 4, 0);
+    test("abcde", 1, 5, "abcdefghij", 1, 8, -4);
+    test("abcde", 1, 5, "abcdefghij", 1, 9, -5);
+    test("abcde", 1, 5, "abcdefghij", 1, 10, -5);
+    test("abcde", 1, 5, "abcdefghij", 5, 0, 4);
+    test("abcde", 1, 5, "abcdefghij", 5, 1, -4);
+    test("abcde", 1, 5, "abcdefghij", 5, 2, -4);
+    test("abcde", 1, 5, "abcdefghij", 5, 4, -4);
+    test("abcde", 1, 5, "abcdefghij", 5, 5, -4);
+    test("abcde", 1, 5, "abcdefghij", 5, 6, -4);
+    test("abcde", 1, 5, "abcdefghij", 9, 0, 4);
+    test("abcde", 1, 5, "abcdefghij", 9, 1, -8);
+    test("abcde", 1, 5, "abcdefghij", 9, 2, -8);
+    test("abcde", 1, 5, "abcdefghij", 10, 0, 4);
+    test("abcde", 1, 5, "abcdefghij", 10, 1, 4);
+    test("abcde", 1, 5, "abcdefghij", 11, 0, 0);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 0, 0, 4);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1, 0, 4);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1, 1, 3);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1, 9, -5);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1, 18, -14);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1, 19, -15);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 1, 20, -15);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 10, 0, 4);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 10, 1, -9);
+}
+
+void test11()
+{
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 19, 0, 4);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 20, 0, 4);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 20, 1, 4);
+    test("abcde", 1, 5, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 2, 0, "", 0, 0, 0);
+    test("abcde", 2, 0, "", 0, 1, 0);
+    test("abcde", 2, 0, "", 1, 0, 0);
+    test("abcde", 2, 0, "abcde", 0, 0, 0);
+    test("abcde", 2, 0, "abcde", 0, 1, -1);
+    test("abcde", 2, 0, "abcde", 0, 2, -2);
+    test("abcde", 2, 0, "abcde", 0, 4, -4);
+    test("abcde", 2, 0, "abcde", 0, 5, -5);
+    test("abcde", 2, 0, "abcde", 0, 6, -5);
+    test("abcde", 2, 0, "abcde", 1, 0, 0);
+    test("abcde", 2, 0, "abcde", 1, 1, -1);
+    test("abcde", 2, 0, "abcde", 1, 2, -2);
+    test("abcde", 2, 0, "abcde", 1, 3, -3);
+    test("abcde", 2, 0, "abcde", 1, 4, -4);
+    test("abcde", 2, 0, "abcde", 1, 5, -4);
+    test("abcde", 2, 0, "abcde", 2, 0, 0);
+    test("abcde", 2, 0, "abcde", 2, 1, -1);
+    test("abcde", 2, 0, "abcde", 2, 2, -2);
+    test("abcde", 2, 0, "abcde", 2, 3, -3);
+    test("abcde", 2, 0, "abcde", 2, 4, -3);
+    test("abcde", 2, 0, "abcde", 4, 0, 0);
+    test("abcde", 2, 0, "abcde", 4, 1, -1);
+    test("abcde", 2, 0, "abcde", 4, 2, -1);
+    test("abcde", 2, 0, "abcde", 5, 0, 0);
+    test("abcde", 2, 0, "abcde", 5, 1, 0);
+    test("abcde", 2, 0, "abcde", 6, 0, 0);
+    test("abcde", 2, 0, "abcdefghij", 0, 0, 0);
+    test("abcde", 2, 0, "abcdefghij", 0, 1, -1);
+    test("abcde", 2, 0, "abcdefghij", 0, 5, -5);
+    test("abcde", 2, 0, "abcdefghij", 0, 9, -9);
+    test("abcde", 2, 0, "abcdefghij", 0, 10, -10);
+    test("abcde", 2, 0, "abcdefghij", 0, 11, -10);
+    test("abcde", 2, 0, "abcdefghij", 1, 0, 0);
+    test("abcde", 2, 0, "abcdefghij", 1, 1, -1);
+    test("abcde", 2, 0, "abcdefghij", 1, 4, -4);
+    test("abcde", 2, 0, "abcdefghij", 1, 8, -8);
+    test("abcde", 2, 0, "abcdefghij", 1, 9, -9);
+    test("abcde", 2, 0, "abcdefghij", 1, 10, -9);
+    test("abcde", 2, 0, "abcdefghij", 5, 0, 0);
+    test("abcde", 2, 0, "abcdefghij", 5, 1, -1);
+    test("abcde", 2, 0, "abcdefghij", 5, 2, -2);
+    test("abcde", 2, 0, "abcdefghij", 5, 4, -4);
+    test("abcde", 2, 0, "abcdefghij", 5, 5, -5);
+    test("abcde", 2, 0, "abcdefghij", 5, 6, -5);
+    test("abcde", 2, 0, "abcdefghij", 9, 0, 0);
+    test("abcde", 2, 0, "abcdefghij", 9, 1, -1);
+    test("abcde", 2, 0, "abcdefghij", 9, 2, -1);
+    test("abcde", 2, 0, "abcdefghij", 10, 0, 0);
+    test("abcde", 2, 0, "abcdefghij", 10, 1, 0);
+    test("abcde", 2, 0, "abcdefghij", 11, 0, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcde", 2, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 2, 1, "", 0, 0, 1);
+    test("abcde", 2, 1, "", 0, 1, 1);
+    test("abcde", 2, 1, "", 1, 0, 0);
+    test("abcde", 2, 1, "abcde", 0, 0, 1);
+    test("abcde", 2, 1, "abcde", 0, 1, 2);
+    test("abcde", 2, 1, "abcde", 0, 2, 2);
+    test("abcde", 2, 1, "abcde", 0, 4, 2);
+    test("abcde", 2, 1, "abcde", 0, 5, 2);
+    test("abcde", 2, 1, "abcde", 0, 6, 2);
+    test("abcde", 2, 1, "abcde", 1, 0, 1);
+    test("abcde", 2, 1, "abcde", 1, 1, 1);
+    test("abcde", 2, 1, "abcde", 1, 2, 1);
+    test("abcde", 2, 1, "abcde", 1, 3, 1);
+    test("abcde", 2, 1, "abcde", 1, 4, 1);
+    test("abcde", 2, 1, "abcde", 1, 5, 1);
+    test("abcde", 2, 1, "abcde", 2, 0, 1);
+}
+
+void test12()
+{
+    test("abcde", 2, 1, "abcde", 2, 1, 0);
+    test("abcde", 2, 1, "abcde", 2, 2, -1);
+    test("abcde", 2, 1, "abcde", 2, 3, -2);
+    test("abcde", 2, 1, "abcde", 2, 4, -2);
+    test("abcde", 2, 1, "abcde", 4, 0, 1);
+    test("abcde", 2, 1, "abcde", 4, 1, -2);
+    test("abcde", 2, 1, "abcde", 4, 2, -2);
+    test("abcde", 2, 1, "abcde", 5, 0, 1);
+    test("abcde", 2, 1, "abcde", 5, 1, 1);
+    test("abcde", 2, 1, "abcde", 6, 0, 0);
+    test("abcde", 2, 1, "abcdefghij", 0, 0, 1);
+    test("abcde", 2, 1, "abcdefghij", 0, 1, 2);
+    test("abcde", 2, 1, "abcdefghij", 0, 5, 2);
+    test("abcde", 2, 1, "abcdefghij", 0, 9, 2);
+    test("abcde", 2, 1, "abcdefghij", 0, 10, 2);
+    test("abcde", 2, 1, "abcdefghij", 0, 11, 2);
+    test("abcde", 2, 1, "abcdefghij", 1, 0, 1);
+    test("abcde", 2, 1, "abcdefghij", 1, 1, 1);
+    test("abcde", 2, 1, "abcdefghij", 1, 4, 1);
+    test("abcde", 2, 1, "abcdefghij", 1, 8, 1);
+    test("abcde", 2, 1, "abcdefghij", 1, 9, 1);
+    test("abcde", 2, 1, "abcdefghij", 1, 10, 1);
+    test("abcde", 2, 1, "abcdefghij", 5, 0, 1);
+    test("abcde", 2, 1, "abcdefghij", 5, 1, -3);
+    test("abcde", 2, 1, "abcdefghij", 5, 2, -3);
+    test("abcde", 2, 1, "abcdefghij", 5, 4, -3);
+    test("abcde", 2, 1, "abcdefghij", 5, 5, -3);
+    test("abcde", 2, 1, "abcdefghij", 5, 6, -3);
+    test("abcde", 2, 1, "abcdefghij", 9, 0, 1);
+    test("abcde", 2, 1, "abcdefghij", 9, 1, -7);
+    test("abcde", 2, 1, "abcdefghij", 9, 2, -7);
+    test("abcde", 2, 1, "abcdefghij", 10, 0, 1);
+    test("abcde", 2, 1, "abcdefghij", 10, 1, 1);
+    test("abcde", 2, 1, "abcdefghij", 11, 0, 0);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 0, 1, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 0, 10, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 0, 19, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 0, 20, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 0, 21, 2);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 1, 1, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 1, 9, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 1, 18, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 1, 19, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 1, 20, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 10, 1, -8);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 10, 5, -8);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 10, 9, -8);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 10, 10, -8);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 10, 11, -8);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 19, 1, -17);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 19, 2, -17);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcde", 2, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 2, 2, "", 0, 0, 2);
+    test("abcde", 2, 2, "", 0, 1, 2);
+    test("abcde", 2, 2, "", 1, 0, 0);
+    test("abcde", 2, 2, "abcde", 0, 0, 2);
+    test("abcde", 2, 2, "abcde", 0, 1, 2);
+    test("abcde", 2, 2, "abcde", 0, 2, 2);
+    test("abcde", 2, 2, "abcde", 0, 4, 2);
+    test("abcde", 2, 2, "abcde", 0, 5, 2);
+    test("abcde", 2, 2, "abcde", 0, 6, 2);
+    test("abcde", 2, 2, "abcde", 1, 0, 2);
+    test("abcde", 2, 2, "abcde", 1, 1, 1);
+    test("abcde", 2, 2, "abcde", 1, 2, 1);
+    test("abcde", 2, 2, "abcde", 1, 3, 1);
+    test("abcde", 2, 2, "abcde", 1, 4, 1);
+    test("abcde", 2, 2, "abcde", 1, 5, 1);
+    test("abcde", 2, 2, "abcde", 2, 0, 2);
+    test("abcde", 2, 2, "abcde", 2, 1, 1);
+    test("abcde", 2, 2, "abcde", 2, 2, 0);
+    test("abcde", 2, 2, "abcde", 2, 3, -1);
+    test("abcde", 2, 2, "abcde", 2, 4, -1);
+    test("abcde", 2, 2, "abcde", 4, 0, 2);
+    test("abcde", 2, 2, "abcde", 4, 1, -2);
+    test("abcde", 2, 2, "abcde", 4, 2, -2);
+    test("abcde", 2, 2, "abcde", 5, 0, 2);
+    test("abcde", 2, 2, "abcde", 5, 1, 2);
+    test("abcde", 2, 2, "abcde", 6, 0, 0);
+    test("abcde", 2, 2, "abcdefghij", 0, 0, 2);
+    test("abcde", 2, 2, "abcdefghij", 0, 1, 2);
+    test("abcde", 2, 2, "abcdefghij", 0, 5, 2);
+    test("abcde", 2, 2, "abcdefghij", 0, 9, 2);
+    test("abcde", 2, 2, "abcdefghij", 0, 10, 2);
+    test("abcde", 2, 2, "abcdefghij", 0, 11, 2);
+    test("abcde", 2, 2, "abcdefghij", 1, 0, 2);
+    test("abcde", 2, 2, "abcdefghij", 1, 1, 1);
+    test("abcde", 2, 2, "abcdefghij", 1, 4, 1);
+    test("abcde", 2, 2, "abcdefghij", 1, 8, 1);
+    test("abcde", 2, 2, "abcdefghij", 1, 9, 1);
+    test("abcde", 2, 2, "abcdefghij", 1, 10, 1);
+    test("abcde", 2, 2, "abcdefghij", 5, 0, 2);
+    test("abcde", 2, 2, "abcdefghij", 5, 1, -3);
+    test("abcde", 2, 2, "abcdefghij", 5, 2, -3);
+    test("abcde", 2, 2, "abcdefghij", 5, 4, -3);
+}
+
+void test13()
+{
+    test("abcde", 2, 2, "abcdefghij", 5, 5, -3);
+    test("abcde", 2, 2, "abcdefghij", 5, 6, -3);
+    test("abcde", 2, 2, "abcdefghij", 9, 0, 2);
+    test("abcde", 2, 2, "abcdefghij", 9, 1, -7);
+    test("abcde", 2, 2, "abcdefghij", 9, 2, -7);
+    test("abcde", 2, 2, "abcdefghij", 10, 0, 2);
+    test("abcde", 2, 2, "abcdefghij", 10, 1, 2);
+    test("abcde", 2, 2, "abcdefghij", 11, 0, 0);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 0, 0, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 0, 1, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 0, 10, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 0, 19, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 0, 20, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 0, 21, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 1, 0, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 1, 1, 1);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 1, 9, 1);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 1, 18, 1);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 1, 19, 1);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 1, 20, 1);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 10, 0, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 10, 1, -8);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 10, 5, -8);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 10, 9, -8);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 10, 10, -8);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 10, 11, -8);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 19, 0, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 19, 1, -17);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 19, 2, -17);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 20, 0, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 20, 1, 2);
+    test("abcde", 2, 2, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 2, 3, "", 0, 0, 3);
+    test("abcde", 2, 3, "", 0, 1, 3);
+    test("abcde", 2, 3, "", 1, 0, 0);
+    test("abcde", 2, 3, "abcde", 0, 0, 3);
+    test("abcde", 2, 3, "abcde", 0, 1, 2);
+    test("abcde", 2, 3, "abcde", 0, 2, 2);
+    test("abcde", 2, 3, "abcde", 0, 4, 2);
+    test("abcde", 2, 3, "abcde", 0, 5, 2);
+    test("abcde", 2, 3, "abcde", 0, 6, 2);
+    test("abcde", 2, 3, "abcde", 1, 0, 3);
+    test("abcde", 2, 3, "abcde", 1, 1, 1);
+    test("abcde", 2, 3, "abcde", 1, 2, 1);
+    test("abcde", 2, 3, "abcde", 1, 3, 1);
+    test("abcde", 2, 3, "abcde", 1, 4, 1);
+    test("abcde", 2, 3, "abcde", 1, 5, 1);
+    test("abcde", 2, 3, "abcde", 2, 0, 3);
+    test("abcde", 2, 3, "abcde", 2, 1, 2);
+    test("abcde", 2, 3, "abcde", 2, 2, 1);
+    test("abcde", 2, 3, "abcde", 2, 3, 0);
+    test("abcde", 2, 3, "abcde", 2, 4, 0);
+    test("abcde", 2, 3, "abcde", 4, 0, 3);
+    test("abcde", 2, 3, "abcde", 4, 1, -2);
+    test("abcde", 2, 3, "abcde", 4, 2, -2);
+    test("abcde", 2, 3, "abcde", 5, 0, 3);
+    test("abcde", 2, 3, "abcde", 5, 1, 3);
+    test("abcde", 2, 3, "abcde", 6, 0, 0);
+    test("abcde", 2, 3, "abcdefghij", 0, 0, 3);
+    test("abcde", 2, 3, "abcdefghij", 0, 1, 2);
+    test("abcde", 2, 3, "abcdefghij", 0, 5, 2);
+    test("abcde", 2, 3, "abcdefghij", 0, 9, 2);
+    test("abcde", 2, 3, "abcdefghij", 0, 10, 2);
+    test("abcde", 2, 3, "abcdefghij", 0, 11, 2);
+    test("abcde", 2, 3, "abcdefghij", 1, 0, 3);
+    test("abcde", 2, 3, "abcdefghij", 1, 1, 1);
+    test("abcde", 2, 3, "abcdefghij", 1, 4, 1);
+    test("abcde", 2, 3, "abcdefghij", 1, 8, 1);
+    test("abcde", 2, 3, "abcdefghij", 1, 9, 1);
+    test("abcde", 2, 3, "abcdefghij", 1, 10, 1);
+    test("abcde", 2, 3, "abcdefghij", 5, 0, 3);
+    test("abcde", 2, 3, "abcdefghij", 5, 1, -3);
+    test("abcde", 2, 3, "abcdefghij", 5, 2, -3);
+    test("abcde", 2, 3, "abcdefghij", 5, 4, -3);
+    test("abcde", 2, 3, "abcdefghij", 5, 5, -3);
+    test("abcde", 2, 3, "abcdefghij", 5, 6, -3);
+    test("abcde", 2, 3, "abcdefghij", 9, 0, 3);
+    test("abcde", 2, 3, "abcdefghij", 9, 1, -7);
+    test("abcde", 2, 3, "abcdefghij", 9, 2, -7);
+    test("abcde", 2, 3, "abcdefghij", 10, 0, 3);
+    test("abcde", 2, 3, "abcdefghij", 10, 1, 3);
+    test("abcde", 2, 3, "abcdefghij", 11, 0, 0);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 0, 0, 3);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 0, 1, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 0, 10, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 0, 19, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 0, 20, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 0, 21, 2);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 1, 0, 3);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 1, 1, 1);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 1, 9, 1);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 1, 18, 1);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 1, 19, 1);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 1, 20, 1);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 10, 0, 3);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 10, 1, -8);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 10, 5, -8);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 10, 9, -8);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 10, 10, -8);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 10, 11, -8);
+}
+
+void test14()
+{
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 19, 0, 3);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 19, 1, -17);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 19, 2, -17);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 20, 0, 3);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 20, 1, 3);
+    test("abcde", 2, 3, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 2, 4, "", 0, 0, 3);
+    test("abcde", 2, 4, "", 0, 1, 3);
+    test("abcde", 2, 4, "", 1, 0, 0);
+    test("abcde", 2, 4, "abcde", 0, 0, 3);
+    test("abcde", 2, 4, "abcde", 0, 1, 2);
+    test("abcde", 2, 4, "abcde", 0, 2, 2);
+    test("abcde", 2, 4, "abcde", 0, 4, 2);
+    test("abcde", 2, 4, "abcde", 0, 5, 2);
+    test("abcde", 2, 4, "abcde", 0, 6, 2);
+    test("abcde", 2, 4, "abcde", 1, 0, 3);
+    test("abcde", 2, 4, "abcde", 1, 1, 1);
+    test("abcde", 2, 4, "abcde", 1, 2, 1);
+    test("abcde", 2, 4, "abcde", 1, 3, 1);
+    test("abcde", 2, 4, "abcde", 1, 4, 1);
+    test("abcde", 2, 4, "abcde", 1, 5, 1);
+    test("abcde", 2, 4, "abcde", 2, 0, 3);
+    test("abcde", 2, 4, "abcde", 2, 1, 2);
+    test("abcde", 2, 4, "abcde", 2, 2, 1);
+    test("abcde", 2, 4, "abcde", 2, 3, 0);
+    test("abcde", 2, 4, "abcde", 2, 4, 0);
+    test("abcde", 2, 4, "abcde", 4, 0, 3);
+    test("abcde", 2, 4, "abcde", 4, 1, -2);
+    test("abcde", 2, 4, "abcde", 4, 2, -2);
+    test("abcde", 2, 4, "abcde", 5, 0, 3);
+    test("abcde", 2, 4, "abcde", 5, 1, 3);
+    test("abcde", 2, 4, "abcde", 6, 0, 0);
+    test("abcde", 2, 4, "abcdefghij", 0, 0, 3);
+    test("abcde", 2, 4, "abcdefghij", 0, 1, 2);
+    test("abcde", 2, 4, "abcdefghij", 0, 5, 2);
+    test("abcde", 2, 4, "abcdefghij", 0, 9, 2);
+    test("abcde", 2, 4, "abcdefghij", 0, 10, 2);
+    test("abcde", 2, 4, "abcdefghij", 0, 11, 2);
+    test("abcde", 2, 4, "abcdefghij", 1, 0, 3);
+    test("abcde", 2, 4, "abcdefghij", 1, 1, 1);
+    test("abcde", 2, 4, "abcdefghij", 1, 4, 1);
+    test("abcde", 2, 4, "abcdefghij", 1, 8, 1);
+    test("abcde", 2, 4, "abcdefghij", 1, 9, 1);
+    test("abcde", 2, 4, "abcdefghij", 1, 10, 1);
+    test("abcde", 2, 4, "abcdefghij", 5, 0, 3);
+    test("abcde", 2, 4, "abcdefghij", 5, 1, -3);
+    test("abcde", 2, 4, "abcdefghij", 5, 2, -3);
+    test("abcde", 2, 4, "abcdefghij", 5, 4, -3);
+    test("abcde", 2, 4, "abcdefghij", 5, 5, -3);
+    test("abcde", 2, 4, "abcdefghij", 5, 6, -3);
+    test("abcde", 2, 4, "abcdefghij", 9, 0, 3);
+    test("abcde", 2, 4, "abcdefghij", 9, 1, -7);
+    test("abcde", 2, 4, "abcdefghij", 9, 2, -7);
+    test("abcde", 2, 4, "abcdefghij", 10, 0, 3);
+    test("abcde", 2, 4, "abcdefghij", 10, 1, 3);
+    test("abcde", 2, 4, "abcdefghij", 11, 0, 0);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 0, 0, 3);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 0, 1, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 0, 10, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 0, 19, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 0, 20, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 0, 21, 2);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 1, 0, 3);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 1, 1, 1);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 1, 9, 1);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 1, 18, 1);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 1, 19, 1);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 1, 20, 1);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 10, 0, 3);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 10, 1, -8);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 10, 5, -8);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 10, 9, -8);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 10, 10, -8);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 10, 11, -8);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 19, 0, 3);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 19, 1, -17);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 19, 2, -17);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 20, 0, 3);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 20, 1, 3);
+    test("abcde", 2, 4, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 4, 0, "", 0, 0, 0);
+    test("abcde", 4, 0, "", 0, 1, 0);
+    test("abcde", 4, 0, "", 1, 0, 0);
+    test("abcde", 4, 0, "abcde", 0, 0, 0);
+    test("abcde", 4, 0, "abcde", 0, 1, -1);
+    test("abcde", 4, 0, "abcde", 0, 2, -2);
+    test("abcde", 4, 0, "abcde", 0, 4, -4);
+    test("abcde", 4, 0, "abcde", 0, 5, -5);
+    test("abcde", 4, 0, "abcde", 0, 6, -5);
+    test("abcde", 4, 0, "abcde", 1, 0, 0);
+    test("abcde", 4, 0, "abcde", 1, 1, -1);
+    test("abcde", 4, 0, "abcde", 1, 2, -2);
+    test("abcde", 4, 0, "abcde", 1, 3, -3);
+    test("abcde", 4, 0, "abcde", 1, 4, -4);
+    test("abcde", 4, 0, "abcde", 1, 5, -4);
+    test("abcde", 4, 0, "abcde", 2, 0, 0);
+    test("abcde", 4, 0, "abcde", 2, 1, -1);
+    test("abcde", 4, 0, "abcde", 2, 2, -2);
+    test("abcde", 4, 0, "abcde", 2, 3, -3);
+    test("abcde", 4, 0, "abcde", 2, 4, -3);
+}
+
+void test15()
+{
+    test("abcde", 4, 0, "abcde", 4, 0, 0);
+    test("abcde", 4, 0, "abcde", 4, 1, -1);
+    test("abcde", 4, 0, "abcde", 4, 2, -1);
+    test("abcde", 4, 0, "abcde", 5, 0, 0);
+    test("abcde", 4, 0, "abcde", 5, 1, 0);
+    test("abcde", 4, 0, "abcde", 6, 0, 0);
+    test("abcde", 4, 0, "abcdefghij", 0, 0, 0);
+    test("abcde", 4, 0, "abcdefghij", 0, 1, -1);
+    test("abcde", 4, 0, "abcdefghij", 0, 5, -5);
+    test("abcde", 4, 0, "abcdefghij", 0, 9, -9);
+    test("abcde", 4, 0, "abcdefghij", 0, 10, -10);
+    test("abcde", 4, 0, "abcdefghij", 0, 11, -10);
+    test("abcde", 4, 0, "abcdefghij", 1, 0, 0);
+    test("abcde", 4, 0, "abcdefghij", 1, 1, -1);
+    test("abcde", 4, 0, "abcdefghij", 1, 4, -4);
+    test("abcde", 4, 0, "abcdefghij", 1, 8, -8);
+    test("abcde", 4, 0, "abcdefghij", 1, 9, -9);
+    test("abcde", 4, 0, "abcdefghij", 1, 10, -9);
+    test("abcde", 4, 0, "abcdefghij", 5, 0, 0);
+    test("abcde", 4, 0, "abcdefghij", 5, 1, -1);
+    test("abcde", 4, 0, "abcdefghij", 5, 2, -2);
+    test("abcde", 4, 0, "abcdefghij", 5, 4, -4);
+    test("abcde", 4, 0, "abcdefghij", 5, 5, -5);
+    test("abcde", 4, 0, "abcdefghij", 5, 6, -5);
+    test("abcde", 4, 0, "abcdefghij", 9, 0, 0);
+    test("abcde", 4, 0, "abcdefghij", 9, 1, -1);
+    test("abcde", 4, 0, "abcdefghij", 9, 2, -1);
+    test("abcde", 4, 0, "abcdefghij", 10, 0, 0);
+    test("abcde", 4, 0, "abcdefghij", 10, 1, 0);
+    test("abcde", 4, 0, "abcdefghij", 11, 0, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcde", 4, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 4, 1, "", 0, 0, 1);
+    test("abcde", 4, 1, "", 0, 1, 1);
+    test("abcde", 4, 1, "", 1, 0, 0);
+    test("abcde", 4, 1, "abcde", 0, 0, 1);
+    test("abcde", 4, 1, "abcde", 0, 1, 4);
+    test("abcde", 4, 1, "abcde", 0, 2, 4);
+    test("abcde", 4, 1, "abcde", 0, 4, 4);
+    test("abcde", 4, 1, "abcde", 0, 5, 4);
+    test("abcde", 4, 1, "abcde", 0, 6, 4);
+    test("abcde", 4, 1, "abcde", 1, 0, 1);
+    test("abcde", 4, 1, "abcde", 1, 1, 3);
+    test("abcde", 4, 1, "abcde", 1, 2, 3);
+    test("abcde", 4, 1, "abcde", 1, 3, 3);
+    test("abcde", 4, 1, "abcde", 1, 4, 3);
+    test("abcde", 4, 1, "abcde", 1, 5, 3);
+    test("abcde", 4, 1, "abcde", 2, 0, 1);
+    test("abcde", 4, 1, "abcde", 2, 1, 2);
+    test("abcde", 4, 1, "abcde", 2, 2, 2);
+    test("abcde", 4, 1, "abcde", 2, 3, 2);
+    test("abcde", 4, 1, "abcde", 2, 4, 2);
+    test("abcde", 4, 1, "abcde", 4, 0, 1);
+    test("abcde", 4, 1, "abcde", 4, 1, 0);
+    test("abcde", 4, 1, "abcde", 4, 2, 0);
+    test("abcde", 4, 1, "abcde", 5, 0, 1);
+    test("abcde", 4, 1, "abcde", 5, 1, 1);
+    test("abcde", 4, 1, "abcde", 6, 0, 0);
+    test("abcde", 4, 1, "abcdefghij", 0, 0, 1);
+    test("abcde", 4, 1, "abcdefghij", 0, 1, 4);
+    test("abcde", 4, 1, "abcdefghij", 0, 5, 4);
+    test("abcde", 4, 1, "abcdefghij", 0, 9, 4);
+    test("abcde", 4, 1, "abcdefghij", 0, 10, 4);
+    test("abcde", 4, 1, "abcdefghij", 0, 11, 4);
+    test("abcde", 4, 1, "abcdefghij", 1, 0, 1);
+    test("abcde", 4, 1, "abcdefghij", 1, 1, 3);
+    test("abcde", 4, 1, "abcdefghij", 1, 4, 3);
+    test("abcde", 4, 1, "abcdefghij", 1, 8, 3);
+    test("abcde", 4, 1, "abcdefghij", 1, 9, 3);
+    test("abcde", 4, 1, "abcdefghij", 1, 10, 3);
+    test("abcde", 4, 1, "abcdefghij", 5, 0, 1);
+    test("abcde", 4, 1, "abcdefghij", 5, 1, -1);
+    test("abcde", 4, 1, "abcdefghij", 5, 2, -1);
+    test("abcde", 4, 1, "abcdefghij", 5, 4, -1);
+    test("abcde", 4, 1, "abcdefghij", 5, 5, -1);
+    test("abcde", 4, 1, "abcdefghij", 5, 6, -1);
+    test("abcde", 4, 1, "abcdefghij", 9, 0, 1);
+    test("abcde", 4, 1, "abcdefghij", 9, 1, -5);
+}
+
+void test16()
+{
+    test("abcde", 4, 1, "abcdefghij", 9, 2, -5);
+    test("abcde", 4, 1, "abcdefghij", 10, 0, 1);
+    test("abcde", 4, 1, "abcdefghij", 10, 1, 1);
+    test("abcde", 4, 1, "abcdefghij", 11, 0, 0);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 0, 1, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 0, 10, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 0, 19, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 0, 20, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 0, 21, 4);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 1, 1, 3);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 1, 9, 3);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 1, 18, 3);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 1, 19, 3);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 1, 20, 3);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 10, 1, -6);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 10, 5, -6);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 10, 9, -6);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 10, 10, -6);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 10, 11, -6);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 19, 1, -15);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 19, 2, -15);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcde", 4, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 4, 2, "", 0, 0, 1);
+    test("abcde", 4, 2, "", 0, 1, 1);
+    test("abcde", 4, 2, "", 1, 0, 0);
+    test("abcde", 4, 2, "abcde", 0, 0, 1);
+    test("abcde", 4, 2, "abcde", 0, 1, 4);
+    test("abcde", 4, 2, "abcde", 0, 2, 4);
+    test("abcde", 4, 2, "abcde", 0, 4, 4);
+    test("abcde", 4, 2, "abcde", 0, 5, 4);
+    test("abcde", 4, 2, "abcde", 0, 6, 4);
+    test("abcde", 4, 2, "abcde", 1, 0, 1);
+    test("abcde", 4, 2, "abcde", 1, 1, 3);
+    test("abcde", 4, 2, "abcde", 1, 2, 3);
+    test("abcde", 4, 2, "abcde", 1, 3, 3);
+    test("abcde", 4, 2, "abcde", 1, 4, 3);
+    test("abcde", 4, 2, "abcde", 1, 5, 3);
+    test("abcde", 4, 2, "abcde", 2, 0, 1);
+    test("abcde", 4, 2, "abcde", 2, 1, 2);
+    test("abcde", 4, 2, "abcde", 2, 2, 2);
+    test("abcde", 4, 2, "abcde", 2, 3, 2);
+    test("abcde", 4, 2, "abcde", 2, 4, 2);
+    test("abcde", 4, 2, "abcde", 4, 0, 1);
+    test("abcde", 4, 2, "abcde", 4, 1, 0);
+    test("abcde", 4, 2, "abcde", 4, 2, 0);
+    test("abcde", 4, 2, "abcde", 5, 0, 1);
+    test("abcde", 4, 2, "abcde", 5, 1, 1);
+    test("abcde", 4, 2, "abcde", 6, 0, 0);
+    test("abcde", 4, 2, "abcdefghij", 0, 0, 1);
+    test("abcde", 4, 2, "abcdefghij", 0, 1, 4);
+    test("abcde", 4, 2, "abcdefghij", 0, 5, 4);
+    test("abcde", 4, 2, "abcdefghij", 0, 9, 4);
+    test("abcde", 4, 2, "abcdefghij", 0, 10, 4);
+    test("abcde", 4, 2, "abcdefghij", 0, 11, 4);
+    test("abcde", 4, 2, "abcdefghij", 1, 0, 1);
+    test("abcde", 4, 2, "abcdefghij", 1, 1, 3);
+    test("abcde", 4, 2, "abcdefghij", 1, 4, 3);
+    test("abcde", 4, 2, "abcdefghij", 1, 8, 3);
+    test("abcde", 4, 2, "abcdefghij", 1, 9, 3);
+    test("abcde", 4, 2, "abcdefghij", 1, 10, 3);
+    test("abcde", 4, 2, "abcdefghij", 5, 0, 1);
+    test("abcde", 4, 2, "abcdefghij", 5, 1, -1);
+    test("abcde", 4, 2, "abcdefghij", 5, 2, -1);
+    test("abcde", 4, 2, "abcdefghij", 5, 4, -1);
+    test("abcde", 4, 2, "abcdefghij", 5, 5, -1);
+    test("abcde", 4, 2, "abcdefghij", 5, 6, -1);
+    test("abcde", 4, 2, "abcdefghij", 9, 0, 1);
+    test("abcde", 4, 2, "abcdefghij", 9, 1, -5);
+    test("abcde", 4, 2, "abcdefghij", 9, 2, -5);
+    test("abcde", 4, 2, "abcdefghij", 10, 0, 1);
+    test("abcde", 4, 2, "abcdefghij", 10, 1, 1);
+    test("abcde", 4, 2, "abcdefghij", 11, 0, 0);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 0, 1, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 0, 10, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 0, 19, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 0, 20, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 0, 21, 4);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 1, 1, 3);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 1, 9, 3);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 1, 18, 3);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 1, 19, 3);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 1, 20, 3);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 10, 1, -6);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 10, 5, -6);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 10, 9, -6);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 10, 10, -6);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 10, 11, -6);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 19, 1, -15);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 19, 2, -15);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 20, 0, 1);
+}
+
+void test17()
+{
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcde", 4, 2, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 5, 0, "", 0, 0, 0);
+    test("abcde", 5, 0, "", 0, 1, 0);
+    test("abcde", 5, 0, "", 1, 0, 0);
+    test("abcde", 5, 0, "abcde", 0, 0, 0);
+    test("abcde", 5, 0, "abcde", 0, 1, -1);
+    test("abcde", 5, 0, "abcde", 0, 2, -2);
+    test("abcde", 5, 0, "abcde", 0, 4, -4);
+    test("abcde", 5, 0, "abcde", 0, 5, -5);
+    test("abcde", 5, 0, "abcde", 0, 6, -5);
+    test("abcde", 5, 0, "abcde", 1, 0, 0);
+    test("abcde", 5, 0, "abcde", 1, 1, -1);
+    test("abcde", 5, 0, "abcde", 1, 2, -2);
+    test("abcde", 5, 0, "abcde", 1, 3, -3);
+    test("abcde", 5, 0, "abcde", 1, 4, -4);
+    test("abcde", 5, 0, "abcde", 1, 5, -4);
+    test("abcde", 5, 0, "abcde", 2, 0, 0);
+    test("abcde", 5, 0, "abcde", 2, 1, -1);
+    test("abcde", 5, 0, "abcde", 2, 2, -2);
+    test("abcde", 5, 0, "abcde", 2, 3, -3);
+    test("abcde", 5, 0, "abcde", 2, 4, -3);
+    test("abcde", 5, 0, "abcde", 4, 0, 0);
+    test("abcde", 5, 0, "abcde", 4, 1, -1);
+    test("abcde", 5, 0, "abcde", 4, 2, -1);
+    test("abcde", 5, 0, "abcde", 5, 0, 0);
+    test("abcde", 5, 0, "abcde", 5, 1, 0);
+    test("abcde", 5, 0, "abcde", 6, 0, 0);
+    test("abcde", 5, 0, "abcdefghij", 0, 0, 0);
+    test("abcde", 5, 0, "abcdefghij", 0, 1, -1);
+    test("abcde", 5, 0, "abcdefghij", 0, 5, -5);
+    test("abcde", 5, 0, "abcdefghij", 0, 9, -9);
+    test("abcde", 5, 0, "abcdefghij", 0, 10, -10);
+    test("abcde", 5, 0, "abcdefghij", 0, 11, -10);
+    test("abcde", 5, 0, "abcdefghij", 1, 0, 0);
+    test("abcde", 5, 0, "abcdefghij", 1, 1, -1);
+    test("abcde", 5, 0, "abcdefghij", 1, 4, -4);
+    test("abcde", 5, 0, "abcdefghij", 1, 8, -8);
+    test("abcde", 5, 0, "abcdefghij", 1, 9, -9);
+    test("abcde", 5, 0, "abcdefghij", 1, 10, -9);
+    test("abcde", 5, 0, "abcdefghij", 5, 0, 0);
+    test("abcde", 5, 0, "abcdefghij", 5, 1, -1);
+    test("abcde", 5, 0, "abcdefghij", 5, 2, -2);
+    test("abcde", 5, 0, "abcdefghij", 5, 4, -4);
+    test("abcde", 5, 0, "abcdefghij", 5, 5, -5);
+    test("abcde", 5, 0, "abcdefghij", 5, 6, -5);
+    test("abcde", 5, 0, "abcdefghij", 9, 0, 0);
+    test("abcde", 5, 0, "abcdefghij", 9, 1, -1);
+    test("abcde", 5, 0, "abcdefghij", 9, 2, -1);
+    test("abcde", 5, 0, "abcdefghij", 10, 0, 0);
+    test("abcde", 5, 0, "abcdefghij", 10, 1, 0);
+    test("abcde", 5, 0, "abcdefghij", 11, 0, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcde", 5, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 5, 1, "", 0, 0, 0);
+    test("abcde", 5, 1, "", 0, 1, 0);
+    test("abcde", 5, 1, "", 1, 0, 0);
+    test("abcde", 5, 1, "abcde", 0, 0, 0);
+    test("abcde", 5, 1, "abcde", 0, 1, -1);
+    test("abcde", 5, 1, "abcde", 0, 2, -2);
+    test("abcde", 5, 1, "abcde", 0, 4, -4);
+    test("abcde", 5, 1, "abcde", 0, 5, -5);
+    test("abcde", 5, 1, "abcde", 0, 6, -5);
+    test("abcde", 5, 1, "abcde", 1, 0, 0);
+    test("abcde", 5, 1, "abcde", 1, 1, -1);
+    test("abcde", 5, 1, "abcde", 1, 2, -2);
+    test("abcde", 5, 1, "abcde", 1, 3, -3);
+    test("abcde", 5, 1, "abcde", 1, 4, -4);
+    test("abcde", 5, 1, "abcde", 1, 5, -4);
+    test("abcde", 5, 1, "abcde", 2, 0, 0);
+    test("abcde", 5, 1, "abcde", 2, 1, -1);
+    test("abcde", 5, 1, "abcde", 2, 2, -2);
+    test("abcde", 5, 1, "abcde", 2, 3, -3);
+    test("abcde", 5, 1, "abcde", 2, 4, -3);
+    test("abcde", 5, 1, "abcde", 4, 0, 0);
+    test("abcde", 5, 1, "abcde", 4, 1, -1);
+    test("abcde", 5, 1, "abcde", 4, 2, -1);
+    test("abcde", 5, 1, "abcde", 5, 0, 0);
+}
+
+void test18()
+{
+    test("abcde", 5, 1, "abcde", 5, 1, 0);
+    test("abcde", 5, 1, "abcde", 6, 0, 0);
+    test("abcde", 5, 1, "abcdefghij", 0, 0, 0);
+    test("abcde", 5, 1, "abcdefghij", 0, 1, -1);
+    test("abcde", 5, 1, "abcdefghij", 0, 5, -5);
+    test("abcde", 5, 1, "abcdefghij", 0, 9, -9);
+    test("abcde", 5, 1, "abcdefghij", 0, 10, -10);
+    test("abcde", 5, 1, "abcdefghij", 0, 11, -10);
+    test("abcde", 5, 1, "abcdefghij", 1, 0, 0);
+    test("abcde", 5, 1, "abcdefghij", 1, 1, -1);
+    test("abcde", 5, 1, "abcdefghij", 1, 4, -4);
+    test("abcde", 5, 1, "abcdefghij", 1, 8, -8);
+    test("abcde", 5, 1, "abcdefghij", 1, 9, -9);
+    test("abcde", 5, 1, "abcdefghij", 1, 10, -9);
+    test("abcde", 5, 1, "abcdefghij", 5, 0, 0);
+    test("abcde", 5, 1, "abcdefghij", 5, 1, -1);
+    test("abcde", 5, 1, "abcdefghij", 5, 2, -2);
+    test("abcde", 5, 1, "abcdefghij", 5, 4, -4);
+    test("abcde", 5, 1, "abcdefghij", 5, 5, -5);
+    test("abcde", 5, 1, "abcdefghij", 5, 6, -5);
+    test("abcde", 5, 1, "abcdefghij", 9, 0, 0);
+    test("abcde", 5, 1, "abcdefghij", 9, 1, -1);
+    test("abcde", 5, 1, "abcdefghij", 9, 2, -1);
+    test("abcde", 5, 1, "abcdefghij", 10, 0, 0);
+    test("abcde", 5, 1, "abcdefghij", 10, 1, 0);
+    test("abcde", 5, 1, "abcdefghij", 11, 0, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcde", 5, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcde", 6, 0, "", 0, 0, 0);
+    test("abcde", 6, 0, "", 0, 1, 0);
+    test("abcde", 6, 0, "", 1, 0, 0);
+    test("abcde", 6, 0, "abcde", 0, 0, 0);
+    test("abcde", 6, 0, "abcde", 0, 1, 0);
+    test("abcde", 6, 0, "abcde", 0, 2, 0);
+    test("abcde", 6, 0, "abcde", 0, 4, 0);
+    test("abcde", 6, 0, "abcde", 0, 5, 0);
+    test("abcde", 6, 0, "abcde", 0, 6, 0);
+    test("abcde", 6, 0, "abcde", 1, 0, 0);
+    test("abcde", 6, 0, "abcde", 1, 1, 0);
+    test("abcde", 6, 0, "abcde", 1, 2, 0);
+    test("abcde", 6, 0, "abcde", 1, 3, 0);
+    test("abcde", 6, 0, "abcde", 1, 4, 0);
+    test("abcde", 6, 0, "abcde", 1, 5, 0);
+    test("abcde", 6, 0, "abcde", 2, 0, 0);
+    test("abcde", 6, 0, "abcde", 2, 1, 0);
+    test("abcde", 6, 0, "abcde", 2, 2, 0);
+    test("abcde", 6, 0, "abcde", 2, 3, 0);
+    test("abcde", 6, 0, "abcde", 2, 4, 0);
+    test("abcde", 6, 0, "abcde", 4, 0, 0);
+    test("abcde", 6, 0, "abcde", 4, 1, 0);
+    test("abcde", 6, 0, "abcde", 4, 2, 0);
+    test("abcde", 6, 0, "abcde", 5, 0, 0);
+    test("abcde", 6, 0, "abcde", 5, 1, 0);
+    test("abcde", 6, 0, "abcde", 6, 0, 0);
+    test("abcde", 6, 0, "abcdefghij", 0, 0, 0);
+    test("abcde", 6, 0, "abcdefghij", 0, 1, 0);
+    test("abcde", 6, 0, "abcdefghij", 0, 5, 0);
+    test("abcde", 6, 0, "abcdefghij", 0, 9, 0);
+    test("abcde", 6, 0, "abcdefghij", 0, 10, 0);
+    test("abcde", 6, 0, "abcdefghij", 0, 11, 0);
+    test("abcde", 6, 0, "abcdefghij", 1, 0, 0);
+    test("abcde", 6, 0, "abcdefghij", 1, 1, 0);
+    test("abcde", 6, 0, "abcdefghij", 1, 4, 0);
+    test("abcde", 6, 0, "abcdefghij", 1, 8, 0);
+    test("abcde", 6, 0, "abcdefghij", 1, 9, 0);
+    test("abcde", 6, 0, "abcdefghij", 1, 10, 0);
+    test("abcde", 6, 0, "abcdefghij", 5, 0, 0);
+    test("abcde", 6, 0, "abcdefghij", 5, 1, 0);
+    test("abcde", 6, 0, "abcdefghij", 5, 2, 0);
+    test("abcde", 6, 0, "abcdefghij", 5, 4, 0);
+    test("abcde", 6, 0, "abcdefghij", 5, 5, 0);
+    test("abcde", 6, 0, "abcdefghij", 5, 6, 0);
+    test("abcde", 6, 0, "abcdefghij", 9, 0, 0);
+    test("abcde", 6, 0, "abcdefghij", 9, 1, 0);
+    test("abcde", 6, 0, "abcdefghij", 9, 2, 0);
+    test("abcde", 6, 0, "abcdefghij", 10, 0, 0);
+    test("abcde", 6, 0, "abcdefghij", 10, 1, 0);
+    test("abcde", 6, 0, "abcdefghij", 11, 0, 0);
+}
+
+void test19()
+{
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0, 1, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0, 10, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0, 19, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0, 20, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 0, 21, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 1, 1, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 1, 9, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 1, 18, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 1, 19, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 1, 20, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 10, 1, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 10, 5, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 10, 9, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 10, 10, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 10, 11, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 19, 1, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 19, 2, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcde", 6, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 0, 0, "", 0, 0, 0);
+    test("abcdefghij", 0, 0, "", 0, 1, 0);
+    test("abcdefghij", 0, 0, "", 1, 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 0, 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 0, 1, -1);
+    test("abcdefghij", 0, 0, "abcde", 0, 2, -2);
+    test("abcdefghij", 0, 0, "abcde", 0, 4, -4);
+    test("abcdefghij", 0, 0, "abcde", 0, 5, -5);
+    test("abcdefghij", 0, 0, "abcde", 0, 6, -5);
+    test("abcdefghij", 0, 0, "abcde", 1, 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 1, 1, -1);
+    test("abcdefghij", 0, 0, "abcde", 1, 2, -2);
+    test("abcdefghij", 0, 0, "abcde", 1, 3, -3);
+    test("abcdefghij", 0, 0, "abcde", 1, 4, -4);
+    test("abcdefghij", 0, 0, "abcde", 1, 5, -4);
+    test("abcdefghij", 0, 0, "abcde", 2, 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 2, 1, -1);
+    test("abcdefghij", 0, 0, "abcde", 2, 2, -2);
+    test("abcdefghij", 0, 0, "abcde", 2, 3, -3);
+    test("abcdefghij", 0, 0, "abcde", 2, 4, -3);
+    test("abcdefghij", 0, 0, "abcde", 4, 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 4, 1, -1);
+    test("abcdefghij", 0, 0, "abcde", 4, 2, -1);
+    test("abcdefghij", 0, 0, "abcde", 5, 0, 0);
+    test("abcdefghij", 0, 0, "abcde", 5, 1, 0);
+    test("abcdefghij", 0, 0, "abcde", 6, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghij", 0, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghij", 0, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghij", 0, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghij", 0, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghij", 0, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghij", 0, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghij", 0, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghij", 0, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghij", 0, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 0, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 0, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 0, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghij", 0, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghij", 0, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghij", 0, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 0, 1, "", 0, 0, 1);
+    test("abcdefghij", 0, 1, "", 0, 1, 1);
+}
+
+void test20()
+{
+    test("abcdefghij", 0, 1, "", 1, 0, 0);
+    test("abcdefghij", 0, 1, "abcde", 0, 0, 1);
+    test("abcdefghij", 0, 1, "abcde", 0, 1, 0);
+    test("abcdefghij", 0, 1, "abcde", 0, 2, -1);
+    test("abcdefghij", 0, 1, "abcde", 0, 4, -3);
+    test("abcdefghij", 0, 1, "abcde", 0, 5, -4);
+    test("abcdefghij", 0, 1, "abcde", 0, 6, -4);
+    test("abcdefghij", 0, 1, "abcde", 1, 0, 1);
+    test("abcdefghij", 0, 1, "abcde", 1, 1, -1);
+    test("abcdefghij", 0, 1, "abcde", 1, 2, -1);
+    test("abcdefghij", 0, 1, "abcde", 1, 3, -1);
+    test("abcdefghij", 0, 1, "abcde", 1, 4, -1);
+    test("abcdefghij", 0, 1, "abcde", 1, 5, -1);
+    test("abcdefghij", 0, 1, "abcde", 2, 0, 1);
+    test("abcdefghij", 0, 1, "abcde", 2, 1, -2);
+    test("abcdefghij", 0, 1, "abcde", 2, 2, -2);
+    test("abcdefghij", 0, 1, "abcde", 2, 3, -2);
+    test("abcdefghij", 0, 1, "abcde", 2, 4, -2);
+    test("abcdefghij", 0, 1, "abcde", 4, 0, 1);
+    test("abcdefghij", 0, 1, "abcde", 4, 1, -4);
+    test("abcdefghij", 0, 1, "abcde", 4, 2, -4);
+    test("abcdefghij", 0, 1, "abcde", 5, 0, 1);
+    test("abcdefghij", 0, 1, "abcde", 5, 1, 1);
+    test("abcdefghij", 0, 1, "abcde", 6, 0, 0);
+    test("abcdefghij", 0, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghij", 0, 1, 0);
+    test("abcdefghij", 0, 1, "abcdefghij", 0, 5, -4);
+    test("abcdefghij", 0, 1, "abcdefghij", 0, 9, -8);
+    test("abcdefghij", 0, 1, "abcdefghij", 0, 10, -9);
+    test("abcdefghij", 0, 1, "abcdefghij", 0, 11, -9);
+    test("abcdefghij", 0, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 0, 1, "abcdefghij", 1, 4, -1);
+    test("abcdefghij", 0, 1, "abcdefghij", 1, 8, -1);
+    test("abcdefghij", 0, 1, "abcdefghij", 1, 9, -1);
+    test("abcdefghij", 0, 1, "abcdefghij", 1, 10, -1);
+    test("abcdefghij", 0, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghij", 5, 1, -5);
+    test("abcdefghij", 0, 1, "abcdefghij", 5, 2, -5);
+    test("abcdefghij", 0, 1, "abcdefghij", 5, 4, -5);
+    test("abcdefghij", 0, 1, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 0, 1, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 0, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghij", 9, 1, -9);
+    test("abcdefghij", 0, 1, "abcdefghij", 9, 2, -9);
+    test("abcdefghij", 0, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghij", 0, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 0, 1, 0);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 0, 10, -9);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 0, 19, -18);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 0, 20, -19);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 0, 21, -19);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghij", 0, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 0, 5, "", 0, 0, 5);
+    test("abcdefghij", 0, 5, "", 0, 1, 5);
+    test("abcdefghij", 0, 5, "", 1, 0, 0);
+    test("abcdefghij", 0, 5, "abcde", 0, 0, 5);
+    test("abcdefghij", 0, 5, "abcde", 0, 1, 4);
+    test("abcdefghij", 0, 5, "abcde", 0, 2, 3);
+    test("abcdefghij", 0, 5, "abcde", 0, 4, 1);
+    test("abcdefghij", 0, 5, "abcde", 0, 5, 0);
+    test("abcdefghij", 0, 5, "abcde", 0, 6, 0);
+    test("abcdefghij", 0, 5, "abcde", 1, 0, 5);
+    test("abcdefghij", 0, 5, "abcde", 1, 1, -1);
+    test("abcdefghij", 0, 5, "abcde", 1, 2, -1);
+    test("abcdefghij", 0, 5, "abcde", 1, 3, -1);
+    test("abcdefghij", 0, 5, "abcde", 1, 4, -1);
+    test("abcdefghij", 0, 5, "abcde", 1, 5, -1);
+    test("abcdefghij", 0, 5, "abcde", 2, 0, 5);
+    test("abcdefghij", 0, 5, "abcde", 2, 1, -2);
+    test("abcdefghij", 0, 5, "abcde", 2, 2, -2);
+    test("abcdefghij", 0, 5, "abcde", 2, 3, -2);
+    test("abcdefghij", 0, 5, "abcde", 2, 4, -2);
+    test("abcdefghij", 0, 5, "abcde", 4, 0, 5);
+    test("abcdefghij", 0, 5, "abcde", 4, 1, -4);
+    test("abcdefghij", 0, 5, "abcde", 4, 2, -4);
+    test("abcdefghij", 0, 5, "abcde", 5, 0, 5);
+    test("abcdefghij", 0, 5, "abcde", 5, 1, 5);
+    test("abcdefghij", 0, 5, "abcde", 6, 0, 0);
+    test("abcdefghij", 0, 5, "abcdefghij", 0, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghij", 0, 1, 4);
+}
+
+void test21()
+{
+    test("abcdefghij", 0, 5, "abcdefghij", 0, 5, 0);
+    test("abcdefghij", 0, 5, "abcdefghij", 0, 9, -4);
+    test("abcdefghij", 0, 5, "abcdefghij", 0, 10, -5);
+    test("abcdefghij", 0, 5, "abcdefghij", 0, 11, -5);
+    test("abcdefghij", 0, 5, "abcdefghij", 1, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 0, 5, "abcdefghij", 1, 4, -1);
+    test("abcdefghij", 0, 5, "abcdefghij", 1, 8, -1);
+    test("abcdefghij", 0, 5, "abcdefghij", 1, 9, -1);
+    test("abcdefghij", 0, 5, "abcdefghij", 1, 10, -1);
+    test("abcdefghij", 0, 5, "abcdefghij", 5, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghij", 5, 1, -5);
+    test("abcdefghij", 0, 5, "abcdefghij", 5, 2, -5);
+    test("abcdefghij", 0, 5, "abcdefghij", 5, 4, -5);
+    test("abcdefghij", 0, 5, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 0, 5, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 0, 5, "abcdefghij", 9, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghij", 9, 1, -9);
+    test("abcdefghij", 0, 5, "abcdefghij", 9, 2, -9);
+    test("abcdefghij", 0, 5, "abcdefghij", 10, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghij", 10, 1, 5);
+    test("abcdefghij", 0, 5, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 0, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 0, 1, 4);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 0, 10, -5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 0, 19, -14);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 0, 20, -15);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 0, 21, -15);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 1, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 10, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 19, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 20, 0, 5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 20, 1, 5);
+    test("abcdefghij", 0, 5, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 0, 9, "", 0, 0, 9);
+    test("abcdefghij", 0, 9, "", 0, 1, 9);
+    test("abcdefghij", 0, 9, "", 1, 0, 0);
+    test("abcdefghij", 0, 9, "abcde", 0, 0, 9);
+    test("abcdefghij", 0, 9, "abcde", 0, 1, 8);
+    test("abcdefghij", 0, 9, "abcde", 0, 2, 7);
+    test("abcdefghij", 0, 9, "abcde", 0, 4, 5);
+    test("abcdefghij", 0, 9, "abcde", 0, 5, 4);
+    test("abcdefghij", 0, 9, "abcde", 0, 6, 4);
+    test("abcdefghij", 0, 9, "abcde", 1, 0, 9);
+    test("abcdefghij", 0, 9, "abcde", 1, 1, -1);
+    test("abcdefghij", 0, 9, "abcde", 1, 2, -1);
+    test("abcdefghij", 0, 9, "abcde", 1, 3, -1);
+    test("abcdefghij", 0, 9, "abcde", 1, 4, -1);
+    test("abcdefghij", 0, 9, "abcde", 1, 5, -1);
+    test("abcdefghij", 0, 9, "abcde", 2, 0, 9);
+    test("abcdefghij", 0, 9, "abcde", 2, 1, -2);
+    test("abcdefghij", 0, 9, "abcde", 2, 2, -2);
+    test("abcdefghij", 0, 9, "abcde", 2, 3, -2);
+    test("abcdefghij", 0, 9, "abcde", 2, 4, -2);
+    test("abcdefghij", 0, 9, "abcde", 4, 0, 9);
+    test("abcdefghij", 0, 9, "abcde", 4, 1, -4);
+    test("abcdefghij", 0, 9, "abcde", 4, 2, -4);
+    test("abcdefghij", 0, 9, "abcde", 5, 0, 9);
+    test("abcdefghij", 0, 9, "abcde", 5, 1, 9);
+    test("abcdefghij", 0, 9, "abcde", 6, 0, 0);
+    test("abcdefghij", 0, 9, "abcdefghij", 0, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghij", 0, 1, 8);
+    test("abcdefghij", 0, 9, "abcdefghij", 0, 5, 4);
+    test("abcdefghij", 0, 9, "abcdefghij", 0, 9, 0);
+    test("abcdefghij", 0, 9, "abcdefghij", 0, 10, -1);
+    test("abcdefghij", 0, 9, "abcdefghij", 0, 11, -1);
+    test("abcdefghij", 0, 9, "abcdefghij", 1, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 0, 9, "abcdefghij", 1, 4, -1);
+    test("abcdefghij", 0, 9, "abcdefghij", 1, 8, -1);
+    test("abcdefghij", 0, 9, "abcdefghij", 1, 9, -1);
+    test("abcdefghij", 0, 9, "abcdefghij", 1, 10, -1);
+    test("abcdefghij", 0, 9, "abcdefghij", 5, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghij", 5, 1, -5);
+    test("abcdefghij", 0, 9, "abcdefghij", 5, 2, -5);
+    test("abcdefghij", 0, 9, "abcdefghij", 5, 4, -5);
+    test("abcdefghij", 0, 9, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 0, 9, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 0, 9, "abcdefghij", 9, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghij", 9, 1, -9);
+    test("abcdefghij", 0, 9, "abcdefghij", 9, 2, -9);
+    test("abcdefghij", 0, 9, "abcdefghij", 10, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghij", 10, 1, 9);
+    test("abcdefghij", 0, 9, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 0, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 0, 1, 8);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 0, 10, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 0, 19, -10);
+}
+
+void test22()
+{
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 0, 20, -11);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 0, 21, -11);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 1, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 10, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 19, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 20, 0, 9);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 20, 1, 9);
+    test("abcdefghij", 0, 9, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 0, 10, "", 0, 0, 10);
+    test("abcdefghij", 0, 10, "", 0, 1, 10);
+    test("abcdefghij", 0, 10, "", 1, 0, 0);
+    test("abcdefghij", 0, 10, "abcde", 0, 0, 10);
+    test("abcdefghij", 0, 10, "abcde", 0, 1, 9);
+    test("abcdefghij", 0, 10, "abcde", 0, 2, 8);
+    test("abcdefghij", 0, 10, "abcde", 0, 4, 6);
+    test("abcdefghij", 0, 10, "abcde", 0, 5, 5);
+    test("abcdefghij", 0, 10, "abcde", 0, 6, 5);
+    test("abcdefghij", 0, 10, "abcde", 1, 0, 10);
+    test("abcdefghij", 0, 10, "abcde", 1, 1, -1);
+    test("abcdefghij", 0, 10, "abcde", 1, 2, -1);
+    test("abcdefghij", 0, 10, "abcde", 1, 3, -1);
+    test("abcdefghij", 0, 10, "abcde", 1, 4, -1);
+    test("abcdefghij", 0, 10, "abcde", 1, 5, -1);
+    test("abcdefghij", 0, 10, "abcde", 2, 0, 10);
+    test("abcdefghij", 0, 10, "abcde", 2, 1, -2);
+    test("abcdefghij", 0, 10, "abcde", 2, 2, -2);
+    test("abcdefghij", 0, 10, "abcde", 2, 3, -2);
+    test("abcdefghij", 0, 10, "abcde", 2, 4, -2);
+    test("abcdefghij", 0, 10, "abcde", 4, 0, 10);
+    test("abcdefghij", 0, 10, "abcde", 4, 1, -4);
+    test("abcdefghij", 0, 10, "abcde", 4, 2, -4);
+    test("abcdefghij", 0, 10, "abcde", 5, 0, 10);
+    test("abcdefghij", 0, 10, "abcde", 5, 1, 10);
+    test("abcdefghij", 0, 10, "abcde", 6, 0, 0);
+    test("abcdefghij", 0, 10, "abcdefghij", 0, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghij", 0, 1, 9);
+    test("abcdefghij", 0, 10, "abcdefghij", 0, 5, 5);
+    test("abcdefghij", 0, 10, "abcdefghij", 0, 9, 1);
+    test("abcdefghij", 0, 10, "abcdefghij", 0, 10, 0);
+    test("abcdefghij", 0, 10, "abcdefghij", 0, 11, 0);
+    test("abcdefghij", 0, 10, "abcdefghij", 1, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 0, 10, "abcdefghij", 1, 4, -1);
+    test("abcdefghij", 0, 10, "abcdefghij", 1, 8, -1);
+    test("abcdefghij", 0, 10, "abcdefghij", 1, 9, -1);
+    test("abcdefghij", 0, 10, "abcdefghij", 1, 10, -1);
+    test("abcdefghij", 0, 10, "abcdefghij", 5, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghij", 5, 1, -5);
+    test("abcdefghij", 0, 10, "abcdefghij", 5, 2, -5);
+    test("abcdefghij", 0, 10, "abcdefghij", 5, 4, -5);
+    test("abcdefghij", 0, 10, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 0, 10, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 0, 10, "abcdefghij", 9, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghij", 9, 1, -9);
+    test("abcdefghij", 0, 10, "abcdefghij", 9, 2, -9);
+    test("abcdefghij", 0, 10, "abcdefghij", 10, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghij", 10, 1, 10);
+    test("abcdefghij", 0, 10, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 0, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 0, 1, 9);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 0, 10, 0);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 0, 19, -9);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 0, 20, -10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 0, 21, -10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 1, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 10, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 19, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 20, 0, 10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 20, 1, 10);
+    test("abcdefghij", 0, 10, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 0, 11, "", 0, 0, 10);
+    test("abcdefghij", 0, 11, "", 0, 1, 10);
+    test("abcdefghij", 0, 11, "", 1, 0, 0);
+    test("abcdefghij", 0, 11, "abcde", 0, 0, 10);
+    test("abcdefghij", 0, 11, "abcde", 0, 1, 9);
+    test("abcdefghij", 0, 11, "abcde", 0, 2, 8);
+}
+
+void test23()
+{
+    test("abcdefghij", 0, 11, "abcde", 0, 4, 6);
+    test("abcdefghij", 0, 11, "abcde", 0, 5, 5);
+    test("abcdefghij", 0, 11, "abcde", 0, 6, 5);
+    test("abcdefghij", 0, 11, "abcde", 1, 0, 10);
+    test("abcdefghij", 0, 11, "abcde", 1, 1, -1);
+    test("abcdefghij", 0, 11, "abcde", 1, 2, -1);
+    test("abcdefghij", 0, 11, "abcde", 1, 3, -1);
+    test("abcdefghij", 0, 11, "abcde", 1, 4, -1);
+    test("abcdefghij", 0, 11, "abcde", 1, 5, -1);
+    test("abcdefghij", 0, 11, "abcde", 2, 0, 10);
+    test("abcdefghij", 0, 11, "abcde", 2, 1, -2);
+    test("abcdefghij", 0, 11, "abcde", 2, 2, -2);
+    test("abcdefghij", 0, 11, "abcde", 2, 3, -2);
+    test("abcdefghij", 0, 11, "abcde", 2, 4, -2);
+    test("abcdefghij", 0, 11, "abcde", 4, 0, 10);
+    test("abcdefghij", 0, 11, "abcde", 4, 1, -4);
+    test("abcdefghij", 0, 11, "abcde", 4, 2, -4);
+    test("abcdefghij", 0, 11, "abcde", 5, 0, 10);
+    test("abcdefghij", 0, 11, "abcde", 5, 1, 10);
+    test("abcdefghij", 0, 11, "abcde", 6, 0, 0);
+    test("abcdefghij", 0, 11, "abcdefghij", 0, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghij", 0, 1, 9);
+    test("abcdefghij", 0, 11, "abcdefghij", 0, 5, 5);
+    test("abcdefghij", 0, 11, "abcdefghij", 0, 9, 1);
+    test("abcdefghij", 0, 11, "abcdefghij", 0, 10, 0);
+    test("abcdefghij", 0, 11, "abcdefghij", 0, 11, 0);
+    test("abcdefghij", 0, 11, "abcdefghij", 1, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 0, 11, "abcdefghij", 1, 4, -1);
+    test("abcdefghij", 0, 11, "abcdefghij", 1, 8, -1);
+    test("abcdefghij", 0, 11, "abcdefghij", 1, 9, -1);
+    test("abcdefghij", 0, 11, "abcdefghij", 1, 10, -1);
+    test("abcdefghij", 0, 11, "abcdefghij", 5, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghij", 5, 1, -5);
+    test("abcdefghij", 0, 11, "abcdefghij", 5, 2, -5);
+    test("abcdefghij", 0, 11, "abcdefghij", 5, 4, -5);
+    test("abcdefghij", 0, 11, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 0, 11, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 0, 11, "abcdefghij", 9, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghij", 9, 1, -9);
+    test("abcdefghij", 0, 11, "abcdefghij", 9, 2, -9);
+    test("abcdefghij", 0, 11, "abcdefghij", 10, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghij", 10, 1, 10);
+    test("abcdefghij", 0, 11, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 0, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 0, 1, 9);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 0, 10, 0);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 0, 19, -9);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 0, 20, -10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 0, 21, -10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 1, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 10, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 19, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 20, 0, 10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 20, 1, 10);
+    test("abcdefghij", 0, 11, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 1, 0, "", 0, 0, 0);
+    test("abcdefghij", 1, 0, "", 0, 1, 0);
+    test("abcdefghij", 1, 0, "", 1, 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 0, 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 0, 1, -1);
+    test("abcdefghij", 1, 0, "abcde", 0, 2, -2);
+    test("abcdefghij", 1, 0, "abcde", 0, 4, -4);
+    test("abcdefghij", 1, 0, "abcde", 0, 5, -5);
+    test("abcdefghij", 1, 0, "abcde", 0, 6, -5);
+    test("abcdefghij", 1, 0, "abcde", 1, 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 1, 1, -1);
+    test("abcdefghij", 1, 0, "abcde", 1, 2, -2);
+    test("abcdefghij", 1, 0, "abcde", 1, 3, -3);
+    test("abcdefghij", 1, 0, "abcde", 1, 4, -4);
+    test("abcdefghij", 1, 0, "abcde", 1, 5, -4);
+    test("abcdefghij", 1, 0, "abcde", 2, 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 2, 1, -1);
+    test("abcdefghij", 1, 0, "abcde", 2, 2, -2);
+    test("abcdefghij", 1, 0, "abcde", 2, 3, -3);
+    test("abcdefghij", 1, 0, "abcde", 2, 4, -3);
+    test("abcdefghij", 1, 0, "abcde", 4, 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 4, 1, -1);
+    test("abcdefghij", 1, 0, "abcde", 4, 2, -1);
+    test("abcdefghij", 1, 0, "abcde", 5, 0, 0);
+    test("abcdefghij", 1, 0, "abcde", 5, 1, 0);
+    test("abcdefghij", 1, 0, "abcde", 6, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghij", 1, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghij", 1, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghij", 1, 0, "abcdefghij", 0, 11, -10);
+}
+
+void test24()
+{
+    test("abcdefghij", 1, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghij", 1, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghij", 1, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghij", 1, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghij", 1, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghij", 1, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 1, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 1, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 1, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghij", 1, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghij", 1, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghij", 1, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 1, 1, "", 0, 0, 1);
+    test("abcdefghij", 1, 1, "", 0, 1, 1);
+    test("abcdefghij", 1, 1, "", 1, 0, 0);
+    test("abcdefghij", 1, 1, "abcde", 0, 0, 1);
+    test("abcdefghij", 1, 1, "abcde", 0, 1, 1);
+    test("abcdefghij", 1, 1, "abcde", 0, 2, 1);
+    test("abcdefghij", 1, 1, "abcde", 0, 4, 1);
+    test("abcdefghij", 1, 1, "abcde", 0, 5, 1);
+    test("abcdefghij", 1, 1, "abcde", 0, 6, 1);
+    test("abcdefghij", 1, 1, "abcde", 1, 0, 1);
+    test("abcdefghij", 1, 1, "abcde", 1, 1, 0);
+    test("abcdefghij", 1, 1, "abcde", 1, 2, -1);
+    test("abcdefghij", 1, 1, "abcde", 1, 3, -2);
+    test("abcdefghij", 1, 1, "abcde", 1, 4, -3);
+    test("abcdefghij", 1, 1, "abcde", 1, 5, -3);
+    test("abcdefghij", 1, 1, "abcde", 2, 0, 1);
+    test("abcdefghij", 1, 1, "abcde", 2, 1, -1);
+    test("abcdefghij", 1, 1, "abcde", 2, 2, -1);
+    test("abcdefghij", 1, 1, "abcde", 2, 3, -1);
+    test("abcdefghij", 1, 1, "abcde", 2, 4, -1);
+    test("abcdefghij", 1, 1, "abcde", 4, 0, 1);
+    test("abcdefghij", 1, 1, "abcde", 4, 1, -3);
+    test("abcdefghij", 1, 1, "abcde", 4, 2, -3);
+    test("abcdefghij", 1, 1, "abcde", 5, 0, 1);
+    test("abcdefghij", 1, 1, "abcde", 5, 1, 1);
+    test("abcdefghij", 1, 1, "abcde", 6, 0, 0);
+    test("abcdefghij", 1, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 0, 1, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 0, 5, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 0, 9, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 0, 10, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 0, 11, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 1, 1, 0);
+    test("abcdefghij", 1, 1, "abcdefghij", 1, 4, -3);
+    test("abcdefghij", 1, 1, "abcdefghij", 1, 8, -7);
+    test("abcdefghij", 1, 1, "abcdefghij", 1, 9, -8);
+    test("abcdefghij", 1, 1, "abcdefghij", 1, 10, -8);
+    test("abcdefghij", 1, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 5, 1, -4);
+    test("abcdefghij", 1, 1, "abcdefghij", 5, 2, -4);
+    test("abcdefghij", 1, 1, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 1, 1, "abcdefghij", 5, 5, -4);
+    test("abcdefghij", 1, 1, "abcdefghij", 5, 6, -4);
+    test("abcdefghij", 1, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 9, 1, -8);
+    test("abcdefghij", 1, 1, "abcdefghij", 9, 2, -8);
+    test("abcdefghij", 1, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghij", 1, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1, 1, 0);
+}
+
+void test25()
+{
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1, 9, -8);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1, 18, -17);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1, 19, -18);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 1, 20, -18);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghij", 1, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 1, 4, "", 0, 0, 4);
+    test("abcdefghij", 1, 4, "", 0, 1, 4);
+    test("abcdefghij", 1, 4, "", 1, 0, 0);
+    test("abcdefghij", 1, 4, "abcde", 0, 0, 4);
+    test("abcdefghij", 1, 4, "abcde", 0, 1, 1);
+    test("abcdefghij", 1, 4, "abcde", 0, 2, 1);
+    test("abcdefghij", 1, 4, "abcde", 0, 4, 1);
+    test("abcdefghij", 1, 4, "abcde", 0, 5, 1);
+    test("abcdefghij", 1, 4, "abcde", 0, 6, 1);
+    test("abcdefghij", 1, 4, "abcde", 1, 0, 4);
+    test("abcdefghij", 1, 4, "abcde", 1, 1, 3);
+    test("abcdefghij", 1, 4, "abcde", 1, 2, 2);
+    test("abcdefghij", 1, 4, "abcde", 1, 3, 1);
+    test("abcdefghij", 1, 4, "abcde", 1, 4, 0);
+    test("abcdefghij", 1, 4, "abcde", 1, 5, 0);
+    test("abcdefghij", 1, 4, "abcde", 2, 0, 4);
+    test("abcdefghij", 1, 4, "abcde", 2, 1, -1);
+    test("abcdefghij", 1, 4, "abcde", 2, 2, -1);
+    test("abcdefghij", 1, 4, "abcde", 2, 3, -1);
+    test("abcdefghij", 1, 4, "abcde", 2, 4, -1);
+    test("abcdefghij", 1, 4, "abcde", 4, 0, 4);
+    test("abcdefghij", 1, 4, "abcde", 4, 1, -3);
+    test("abcdefghij", 1, 4, "abcde", 4, 2, -3);
+    test("abcdefghij", 1, 4, "abcde", 5, 0, 4);
+    test("abcdefghij", 1, 4, "abcde", 5, 1, 4);
+    test("abcdefghij", 1, 4, "abcde", 6, 0, 0);
+    test("abcdefghij", 1, 4, "abcdefghij", 0, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghij", 0, 1, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 0, 5, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 0, 9, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 0, 10, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 0, 11, 1);
+    test("abcdefghij", 1, 4, "abcdefghij", 1, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghij", 1, 1, 3);
+    test("abcdefghij", 1, 4, "abcdefghij", 1, 4, 0);
+    test("abcdefghij", 1, 4, "abcdefghij", 1, 8, -4);
+    test("abcdefghij", 1, 4, "abcdefghij", 1, 9, -5);
+    test("abcdefghij", 1, 4, "abcdefghij", 1, 10, -5);
+    test("abcdefghij", 1, 4, "abcdefghij", 5, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghij", 5, 1, -4);
+    test("abcdefghij", 1, 4, "abcdefghij", 5, 2, -4);
+    test("abcdefghij", 1, 4, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 1, 4, "abcdefghij", 5, 5, -4);
+    test("abcdefghij", 1, 4, "abcdefghij", 5, 6, -4);
+    test("abcdefghij", 1, 4, "abcdefghij", 9, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghij", 9, 1, -8);
+    test("abcdefghij", 1, 4, "abcdefghij", 9, 2, -8);
+    test("abcdefghij", 1, 4, "abcdefghij", 10, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghij", 10, 1, 4);
+    test("abcdefghij", 1, 4, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 0, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1, 1, 3);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1, 9, -5);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1, 18, -14);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1, 19, -15);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 1, 20, -15);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 10, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 19, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 20, 0, 4);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 20, 1, 4);
+    test("abcdefghij", 1, 4, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 1, 8, "", 0, 0, 8);
+    test("abcdefghij", 1, 8, "", 0, 1, 8);
+    test("abcdefghij", 1, 8, "", 1, 0, 0);
+    test("abcdefghij", 1, 8, "abcde", 0, 0, 8);
+    test("abcdefghij", 1, 8, "abcde", 0, 1, 1);
+    test("abcdefghij", 1, 8, "abcde", 0, 2, 1);
+    test("abcdefghij", 1, 8, "abcde", 0, 4, 1);
+    test("abcdefghij", 1, 8, "abcde", 0, 5, 1);
+    test("abcdefghij", 1, 8, "abcde", 0, 6, 1);
+    test("abcdefghij", 1, 8, "abcde", 1, 0, 8);
+}
+
+void test26()
+{
+    test("abcdefghij", 1, 8, "abcde", 1, 1, 7);
+    test("abcdefghij", 1, 8, "abcde", 1, 2, 6);
+    test("abcdefghij", 1, 8, "abcde", 1, 3, 5);
+    test("abcdefghij", 1, 8, "abcde", 1, 4, 4);
+    test("abcdefghij", 1, 8, "abcde", 1, 5, 4);
+    test("abcdefghij", 1, 8, "abcde", 2, 0, 8);
+    test("abcdefghij", 1, 8, "abcde", 2, 1, -1);
+    test("abcdefghij", 1, 8, "abcde", 2, 2, -1);
+    test("abcdefghij", 1, 8, "abcde", 2, 3, -1);
+    test("abcdefghij", 1, 8, "abcde", 2, 4, -1);
+    test("abcdefghij", 1, 8, "abcde", 4, 0, 8);
+    test("abcdefghij", 1, 8, "abcde", 4, 1, -3);
+    test("abcdefghij", 1, 8, "abcde", 4, 2, -3);
+    test("abcdefghij", 1, 8, "abcde", 5, 0, 8);
+    test("abcdefghij", 1, 8, "abcde", 5, 1, 8);
+    test("abcdefghij", 1, 8, "abcde", 6, 0, 0);
+    test("abcdefghij", 1, 8, "abcdefghij", 0, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghij", 0, 1, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 0, 5, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 0, 9, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 0, 10, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 0, 11, 1);
+    test("abcdefghij", 1, 8, "abcdefghij", 1, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghij", 1, 1, 7);
+    test("abcdefghij", 1, 8, "abcdefghij", 1, 4, 4);
+    test("abcdefghij", 1, 8, "abcdefghij", 1, 8, 0);
+    test("abcdefghij", 1, 8, "abcdefghij", 1, 9, -1);
+    test("abcdefghij", 1, 8, "abcdefghij", 1, 10, -1);
+    test("abcdefghij", 1, 8, "abcdefghij", 5, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghij", 5, 1, -4);
+    test("abcdefghij", 1, 8, "abcdefghij", 5, 2, -4);
+    test("abcdefghij", 1, 8, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 1, 8, "abcdefghij", 5, 5, -4);
+    test("abcdefghij", 1, 8, "abcdefghij", 5, 6, -4);
+    test("abcdefghij", 1, 8, "abcdefghij", 9, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghij", 9, 1, -8);
+    test("abcdefghij", 1, 8, "abcdefghij", 9, 2, -8);
+    test("abcdefghij", 1, 8, "abcdefghij", 10, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghij", 10, 1, 8);
+    test("abcdefghij", 1, 8, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 0, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1, 1, 7);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1, 18, -10);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1, 19, -11);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 1, 20, -11);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 10, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 19, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 20, 0, 8);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 20, 1, 8);
+    test("abcdefghij", 1, 8, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 1, 9, "", 0, 0, 9);
+    test("abcdefghij", 1, 9, "", 0, 1, 9);
+    test("abcdefghij", 1, 9, "", 1, 0, 0);
+    test("abcdefghij", 1, 9, "abcde", 0, 0, 9);
+    test("abcdefghij", 1, 9, "abcde", 0, 1, 1);
+    test("abcdefghij", 1, 9, "abcde", 0, 2, 1);
+    test("abcdefghij", 1, 9, "abcde", 0, 4, 1);
+    test("abcdefghij", 1, 9, "abcde", 0, 5, 1);
+    test("abcdefghij", 1, 9, "abcde", 0, 6, 1);
+    test("abcdefghij", 1, 9, "abcde", 1, 0, 9);
+    test("abcdefghij", 1, 9, "abcde", 1, 1, 8);
+    test("abcdefghij", 1, 9, "abcde", 1, 2, 7);
+    test("abcdefghij", 1, 9, "abcde", 1, 3, 6);
+    test("abcdefghij", 1, 9, "abcde", 1, 4, 5);
+    test("abcdefghij", 1, 9, "abcde", 1, 5, 5);
+    test("abcdefghij", 1, 9, "abcde", 2, 0, 9);
+    test("abcdefghij", 1, 9, "abcde", 2, 1, -1);
+    test("abcdefghij", 1, 9, "abcde", 2, 2, -1);
+    test("abcdefghij", 1, 9, "abcde", 2, 3, -1);
+    test("abcdefghij", 1, 9, "abcde", 2, 4, -1);
+    test("abcdefghij", 1, 9, "abcde", 4, 0, 9);
+    test("abcdefghij", 1, 9, "abcde", 4, 1, -3);
+    test("abcdefghij", 1, 9, "abcde", 4, 2, -3);
+    test("abcdefghij", 1, 9, "abcde", 5, 0, 9);
+    test("abcdefghij", 1, 9, "abcde", 5, 1, 9);
+    test("abcdefghij", 1, 9, "abcde", 6, 0, 0);
+    test("abcdefghij", 1, 9, "abcdefghij", 0, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghij", 0, 1, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 0, 5, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 0, 9, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 0, 10, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 0, 11, 1);
+    test("abcdefghij", 1, 9, "abcdefghij", 1, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghij", 1, 1, 8);
+    test("abcdefghij", 1, 9, "abcdefghij", 1, 4, 5);
+    test("abcdefghij", 1, 9, "abcdefghij", 1, 8, 1);
+}
+
+void test27()
+{
+    test("abcdefghij", 1, 9, "abcdefghij", 1, 9, 0);
+    test("abcdefghij", 1, 9, "abcdefghij", 1, 10, 0);
+    test("abcdefghij", 1, 9, "abcdefghij", 5, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghij", 5, 1, -4);
+    test("abcdefghij", 1, 9, "abcdefghij", 5, 2, -4);
+    test("abcdefghij", 1, 9, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 1, 9, "abcdefghij", 5, 5, -4);
+    test("abcdefghij", 1, 9, "abcdefghij", 5, 6, -4);
+    test("abcdefghij", 1, 9, "abcdefghij", 9, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghij", 9, 1, -8);
+    test("abcdefghij", 1, 9, "abcdefghij", 9, 2, -8);
+    test("abcdefghij", 1, 9, "abcdefghij", 10, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghij", 10, 1, 9);
+    test("abcdefghij", 1, 9, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 0, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1, 1, 8);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1, 9, 0);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1, 18, -9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1, 19, -10);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 1, 20, -10);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 10, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 19, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 20, 0, 9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 20, 1, 9);
+    test("abcdefghij", 1, 9, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 1, 10, "", 0, 0, 9);
+    test("abcdefghij", 1, 10, "", 0, 1, 9);
+    test("abcdefghij", 1, 10, "", 1, 0, 0);
+    test("abcdefghij", 1, 10, "abcde", 0, 0, 9);
+    test("abcdefghij", 1, 10, "abcde", 0, 1, 1);
+    test("abcdefghij", 1, 10, "abcde", 0, 2, 1);
+    test("abcdefghij", 1, 10, "abcde", 0, 4, 1);
+    test("abcdefghij", 1, 10, "abcde", 0, 5, 1);
+    test("abcdefghij", 1, 10, "abcde", 0, 6, 1);
+    test("abcdefghij", 1, 10, "abcde", 1, 0, 9);
+    test("abcdefghij", 1, 10, "abcde", 1, 1, 8);
+    test("abcdefghij", 1, 10, "abcde", 1, 2, 7);
+    test("abcdefghij", 1, 10, "abcde", 1, 3, 6);
+    test("abcdefghij", 1, 10, "abcde", 1, 4, 5);
+    test("abcdefghij", 1, 10, "abcde", 1, 5, 5);
+    test("abcdefghij", 1, 10, "abcde", 2, 0, 9);
+    test("abcdefghij", 1, 10, "abcde", 2, 1, -1);
+    test("abcdefghij", 1, 10, "abcde", 2, 2, -1);
+    test("abcdefghij", 1, 10, "abcde", 2, 3, -1);
+    test("abcdefghij", 1, 10, "abcde", 2, 4, -1);
+    test("abcdefghij", 1, 10, "abcde", 4, 0, 9);
+    test("abcdefghij", 1, 10, "abcde", 4, 1, -3);
+    test("abcdefghij", 1, 10, "abcde", 4, 2, -3);
+    test("abcdefghij", 1, 10, "abcde", 5, 0, 9);
+    test("abcdefghij", 1, 10, "abcde", 5, 1, 9);
+    test("abcdefghij", 1, 10, "abcde", 6, 0, 0);
+    test("abcdefghij", 1, 10, "abcdefghij", 0, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghij", 0, 1, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 0, 5, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 0, 9, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 0, 10, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 0, 11, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 1, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghij", 1, 1, 8);
+    test("abcdefghij", 1, 10, "abcdefghij", 1, 4, 5);
+    test("abcdefghij", 1, 10, "abcdefghij", 1, 8, 1);
+    test("abcdefghij", 1, 10, "abcdefghij", 1, 9, 0);
+    test("abcdefghij", 1, 10, "abcdefghij", 1, 10, 0);
+    test("abcdefghij", 1, 10, "abcdefghij", 5, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghij", 5, 1, -4);
+    test("abcdefghij", 1, 10, "abcdefghij", 5, 2, -4);
+    test("abcdefghij", 1, 10, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 1, 10, "abcdefghij", 5, 5, -4);
+    test("abcdefghij", 1, 10, "abcdefghij", 5, 6, -4);
+    test("abcdefghij", 1, 10, "abcdefghij", 9, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghij", 9, 1, -8);
+    test("abcdefghij", 1, 10, "abcdefghij", 9, 2, -8);
+    test("abcdefghij", 1, 10, "abcdefghij", 10, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghij", 10, 1, 9);
+    test("abcdefghij", 1, 10, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 0, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1, 1, 8);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1, 9, 0);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1, 18, -9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1, 19, -10);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 1, 20, -10);
+}
+
+void test28()
+{
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 10, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 19, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 20, 0, 9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 20, 1, 9);
+    test("abcdefghij", 1, 10, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 5, 0, "", 0, 0, 0);
+    test("abcdefghij", 5, 0, "", 0, 1, 0);
+    test("abcdefghij", 5, 0, "", 1, 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 0, 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 0, 1, -1);
+    test("abcdefghij", 5, 0, "abcde", 0, 2, -2);
+    test("abcdefghij", 5, 0, "abcde", 0, 4, -4);
+    test("abcdefghij", 5, 0, "abcde", 0, 5, -5);
+    test("abcdefghij", 5, 0, "abcde", 0, 6, -5);
+    test("abcdefghij", 5, 0, "abcde", 1, 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 1, 1, -1);
+    test("abcdefghij", 5, 0, "abcde", 1, 2, -2);
+    test("abcdefghij", 5, 0, "abcde", 1, 3, -3);
+    test("abcdefghij", 5, 0, "abcde", 1, 4, -4);
+    test("abcdefghij", 5, 0, "abcde", 1, 5, -4);
+    test("abcdefghij", 5, 0, "abcde", 2, 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 2, 1, -1);
+    test("abcdefghij", 5, 0, "abcde", 2, 2, -2);
+    test("abcdefghij", 5, 0, "abcde", 2, 3, -3);
+    test("abcdefghij", 5, 0, "abcde", 2, 4, -3);
+    test("abcdefghij", 5, 0, "abcde", 4, 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 4, 1, -1);
+    test("abcdefghij", 5, 0, "abcde", 4, 2, -1);
+    test("abcdefghij", 5, 0, "abcde", 5, 0, 0);
+    test("abcdefghij", 5, 0, "abcde", 5, 1, 0);
+    test("abcdefghij", 5, 0, "abcde", 6, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghij", 5, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghij", 5, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghij", 5, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghij", 5, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghij", 5, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghij", 5, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghij", 5, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghij", 5, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghij", 5, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 5, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 5, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 5, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghij", 5, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghij", 5, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghij", 5, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 5, 1, "", 0, 0, 1);
+    test("abcdefghij", 5, 1, "", 0, 1, 1);
+    test("abcdefghij", 5, 1, "", 1, 0, 0);
+    test("abcdefghij", 5, 1, "abcde", 0, 0, 1);
+    test("abcdefghij", 5, 1, "abcde", 0, 1, 5);
+    test("abcdefghij", 5, 1, "abcde", 0, 2, 5);
+    test("abcdefghij", 5, 1, "abcde", 0, 4, 5);
+    test("abcdefghij", 5, 1, "abcde", 0, 5, 5);
+    test("abcdefghij", 5, 1, "abcde", 0, 6, 5);
+    test("abcdefghij", 5, 1, "abcde", 1, 0, 1);
+    test("abcdefghij", 5, 1, "abcde", 1, 1, 4);
+    test("abcdefghij", 5, 1, "abcde", 1, 2, 4);
+    test("abcdefghij", 5, 1, "abcde", 1, 3, 4);
+    test("abcdefghij", 5, 1, "abcde", 1, 4, 4);
+}
+
+void test29()
+{
+    test("abcdefghij", 5, 1, "abcde", 1, 5, 4);
+    test("abcdefghij", 5, 1, "abcde", 2, 0, 1);
+    test("abcdefghij", 5, 1, "abcde", 2, 1, 3);
+    test("abcdefghij", 5, 1, "abcde", 2, 2, 3);
+    test("abcdefghij", 5, 1, "abcde", 2, 3, 3);
+    test("abcdefghij", 5, 1, "abcde", 2, 4, 3);
+    test("abcdefghij", 5, 1, "abcde", 4, 0, 1);
+    test("abcdefghij", 5, 1, "abcde", 4, 1, 1);
+    test("abcdefghij", 5, 1, "abcde", 4, 2, 1);
+    test("abcdefghij", 5, 1, "abcde", 5, 0, 1);
+    test("abcdefghij", 5, 1, "abcde", 5, 1, 1);
+    test("abcdefghij", 5, 1, "abcde", 6, 0, 0);
+    test("abcdefghij", 5, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghij", 0, 1, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 0, 5, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 0, 9, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 0, 10, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 0, 11, 5);
+    test("abcdefghij", 5, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghij", 1, 1, 4);
+    test("abcdefghij", 5, 1, "abcdefghij", 1, 4, 4);
+    test("abcdefghij", 5, 1, "abcdefghij", 1, 8, 4);
+    test("abcdefghij", 5, 1, "abcdefghij", 1, 9, 4);
+    test("abcdefghij", 5, 1, "abcdefghij", 1, 10, 4);
+    test("abcdefghij", 5, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghij", 5, 1, 0);
+    test("abcdefghij", 5, 1, "abcdefghij", 5, 2, -1);
+    test("abcdefghij", 5, 1, "abcdefghij", 5, 4, -3);
+    test("abcdefghij", 5, 1, "abcdefghij", 5, 5, -4);
+    test("abcdefghij", 5, 1, "abcdefghij", 5, 6, -4);
+    test("abcdefghij", 5, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghij", 9, 1, -4);
+    test("abcdefghij", 5, 1, "abcdefghij", 9, 2, -4);
+    test("abcdefghij", 5, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghij", 5, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 0, 1, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 0, 10, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 0, 19, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 0, 20, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 0, 21, 5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 1, 1, 4);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 1, 9, 4);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 1, 18, 4);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 1, 19, 4);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 1, 20, 4);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 10, 1, -5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 10, 9, -5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 10, 10, -5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 10, 11, -5);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 19, 1, -14);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 19, 2, -14);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghij", 5, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 5, 2, "", 0, 0, 2);
+    test("abcdefghij", 5, 2, "", 0, 1, 2);
+    test("abcdefghij", 5, 2, "", 1, 0, 0);
+    test("abcdefghij", 5, 2, "abcde", 0, 0, 2);
+    test("abcdefghij", 5, 2, "abcde", 0, 1, 5);
+    test("abcdefghij", 5, 2, "abcde", 0, 2, 5);
+    test("abcdefghij", 5, 2, "abcde", 0, 4, 5);
+    test("abcdefghij", 5, 2, "abcde", 0, 5, 5);
+    test("abcdefghij", 5, 2, "abcde", 0, 6, 5);
+    test("abcdefghij", 5, 2, "abcde", 1, 0, 2);
+    test("abcdefghij", 5, 2, "abcde", 1, 1, 4);
+    test("abcdefghij", 5, 2, "abcde", 1, 2, 4);
+    test("abcdefghij", 5, 2, "abcde", 1, 3, 4);
+    test("abcdefghij", 5, 2, "abcde", 1, 4, 4);
+    test("abcdefghij", 5, 2, "abcde", 1, 5, 4);
+    test("abcdefghij", 5, 2, "abcde", 2, 0, 2);
+    test("abcdefghij", 5, 2, "abcde", 2, 1, 3);
+    test("abcdefghij", 5, 2, "abcde", 2, 2, 3);
+    test("abcdefghij", 5, 2, "abcde", 2, 3, 3);
+    test("abcdefghij", 5, 2, "abcde", 2, 4, 3);
+    test("abcdefghij", 5, 2, "abcde", 4, 0, 2);
+    test("abcdefghij", 5, 2, "abcde", 4, 1, 1);
+    test("abcdefghij", 5, 2, "abcde", 4, 2, 1);
+    test("abcdefghij", 5, 2, "abcde", 5, 0, 2);
+    test("abcdefghij", 5, 2, "abcde", 5, 1, 2);
+    test("abcdefghij", 5, 2, "abcde", 6, 0, 0);
+    test("abcdefghij", 5, 2, "abcdefghij", 0, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghij", 0, 1, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 0, 5, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 0, 9, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 0, 10, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 0, 11, 5);
+    test("abcdefghij", 5, 2, "abcdefghij", 1, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghij", 1, 1, 4);
+    test("abcdefghij", 5, 2, "abcdefghij", 1, 4, 4);
+    test("abcdefghij", 5, 2, "abcdefghij", 1, 8, 4);
+    test("abcdefghij", 5, 2, "abcdefghij", 1, 9, 4);
+    test("abcdefghij", 5, 2, "abcdefghij", 1, 10, 4);
+    test("abcdefghij", 5, 2, "abcdefghij", 5, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghij", 5, 1, 1);
+}
+
+void test30()
+{
+    test("abcdefghij", 5, 2, "abcdefghij", 5, 2, 0);
+    test("abcdefghij", 5, 2, "abcdefghij", 5, 4, -2);
+    test("abcdefghij", 5, 2, "abcdefghij", 5, 5, -3);
+    test("abcdefghij", 5, 2, "abcdefghij", 5, 6, -3);
+    test("abcdefghij", 5, 2, "abcdefghij", 9, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghij", 9, 1, -4);
+    test("abcdefghij", 5, 2, "abcdefghij", 9, 2, -4);
+    test("abcdefghij", 5, 2, "abcdefghij", 10, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghij", 10, 1, 2);
+    test("abcdefghij", 5, 2, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 0, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 0, 1, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 0, 10, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 0, 19, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 0, 20, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 0, 21, 5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 1, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 1, 1, 4);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 1, 9, 4);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 1, 18, 4);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 1, 19, 4);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 1, 20, 4);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 10, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 10, 1, -5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 10, 9, -5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 10, 10, -5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 10, 11, -5);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 19, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 19, 1, -14);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 19, 2, -14);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 20, 0, 2);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 20, 1, 2);
+    test("abcdefghij", 5, 2, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 5, 4, "", 0, 0, 4);
+    test("abcdefghij", 5, 4, "", 0, 1, 4);
+    test("abcdefghij", 5, 4, "", 1, 0, 0);
+    test("abcdefghij", 5, 4, "abcde", 0, 0, 4);
+    test("abcdefghij", 5, 4, "abcde", 0, 1, 5);
+    test("abcdefghij", 5, 4, "abcde", 0, 2, 5);
+    test("abcdefghij", 5, 4, "abcde", 0, 4, 5);
+    test("abcdefghij", 5, 4, "abcde", 0, 5, 5);
+    test("abcdefghij", 5, 4, "abcde", 0, 6, 5);
+    test("abcdefghij", 5, 4, "abcde", 1, 0, 4);
+    test("abcdefghij", 5, 4, "abcde", 1, 1, 4);
+    test("abcdefghij", 5, 4, "abcde", 1, 2, 4);
+    test("abcdefghij", 5, 4, "abcde", 1, 3, 4);
+    test("abcdefghij", 5, 4, "abcde", 1, 4, 4);
+    test("abcdefghij", 5, 4, "abcde", 1, 5, 4);
+    test("abcdefghij", 5, 4, "abcde", 2, 0, 4);
+    test("abcdefghij", 5, 4, "abcde", 2, 1, 3);
+    test("abcdefghij", 5, 4, "abcde", 2, 2, 3);
+    test("abcdefghij", 5, 4, "abcde", 2, 3, 3);
+    test("abcdefghij", 5, 4, "abcde", 2, 4, 3);
+    test("abcdefghij", 5, 4, "abcde", 4, 0, 4);
+    test("abcdefghij", 5, 4, "abcde", 4, 1, 1);
+    test("abcdefghij", 5, 4, "abcde", 4, 2, 1);
+    test("abcdefghij", 5, 4, "abcde", 5, 0, 4);
+    test("abcdefghij", 5, 4, "abcde", 5, 1, 4);
+    test("abcdefghij", 5, 4, "abcde", 6, 0, 0);
+    test("abcdefghij", 5, 4, "abcdefghij", 0, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 0, 1, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 0, 5, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 0, 9, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 0, 10, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 0, 11, 5);
+    test("abcdefghij", 5, 4, "abcdefghij", 1, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 1, 1, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 1, 4, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 1, 8, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 1, 9, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 1, 10, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 5, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 5, 1, 3);
+    test("abcdefghij", 5, 4, "abcdefghij", 5, 2, 2);
+    test("abcdefghij", 5, 4, "abcdefghij", 5, 4, 0);
+    test("abcdefghij", 5, 4, "abcdefghij", 5, 5, -1);
+    test("abcdefghij", 5, 4, "abcdefghij", 5, 6, -1);
+    test("abcdefghij", 5, 4, "abcdefghij", 9, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 9, 1, -4);
+    test("abcdefghij", 5, 4, "abcdefghij", 9, 2, -4);
+    test("abcdefghij", 5, 4, "abcdefghij", 10, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 10, 1, 4);
+    test("abcdefghij", 5, 4, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 0, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 0, 1, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 0, 10, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 0, 19, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 0, 20, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 0, 21, 5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 1, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 1, 1, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 1, 9, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 1, 18, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 1, 19, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 1, 20, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 10, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 10, 1, -5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 10, 9, -5);
+}
+
+void test31()
+{
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 10, 10, -5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 10, 11, -5);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 19, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 19, 1, -14);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 19, 2, -14);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 20, 0, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 20, 1, 4);
+    test("abcdefghij", 5, 4, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 5, 5, "", 0, 0, 5);
+    test("abcdefghij", 5, 5, "", 0, 1, 5);
+    test("abcdefghij", 5, 5, "", 1, 0, 0);
+    test("abcdefghij", 5, 5, "abcde", 0, 0, 5);
+    test("abcdefghij", 5, 5, "abcde", 0, 1, 5);
+    test("abcdefghij", 5, 5, "abcde", 0, 2, 5);
+    test("abcdefghij", 5, 5, "abcde", 0, 4, 5);
+    test("abcdefghij", 5, 5, "abcde", 0, 5, 5);
+    test("abcdefghij", 5, 5, "abcde", 0, 6, 5);
+    test("abcdefghij", 5, 5, "abcde", 1, 0, 5);
+    test("abcdefghij", 5, 5, "abcde", 1, 1, 4);
+    test("abcdefghij", 5, 5, "abcde", 1, 2, 4);
+    test("abcdefghij", 5, 5, "abcde", 1, 3, 4);
+    test("abcdefghij", 5, 5, "abcde", 1, 4, 4);
+    test("abcdefghij", 5, 5, "abcde", 1, 5, 4);
+    test("abcdefghij", 5, 5, "abcde", 2, 0, 5);
+    test("abcdefghij", 5, 5, "abcde", 2, 1, 3);
+    test("abcdefghij", 5, 5, "abcde", 2, 2, 3);
+    test("abcdefghij", 5, 5, "abcde", 2, 3, 3);
+    test("abcdefghij", 5, 5, "abcde", 2, 4, 3);
+    test("abcdefghij", 5, 5, "abcde", 4, 0, 5);
+    test("abcdefghij", 5, 5, "abcde", 4, 1, 1);
+    test("abcdefghij", 5, 5, "abcde", 4, 2, 1);
+    test("abcdefghij", 5, 5, "abcde", 5, 0, 5);
+    test("abcdefghij", 5, 5, "abcde", 5, 1, 5);
+    test("abcdefghij", 5, 5, "abcde", 6, 0, 0);
+    test("abcdefghij", 5, 5, "abcdefghij", 0, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 0, 1, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 0, 5, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 0, 9, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 0, 10, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 0, 11, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 1, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 1, 1, 4);
+    test("abcdefghij", 5, 5, "abcdefghij", 1, 4, 4);
+    test("abcdefghij", 5, 5, "abcdefghij", 1, 8, 4);
+    test("abcdefghij", 5, 5, "abcdefghij", 1, 9, 4);
+    test("abcdefghij", 5, 5, "abcdefghij", 1, 10, 4);
+    test("abcdefghij", 5, 5, "abcdefghij", 5, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 5, 1, 4);
+    test("abcdefghij", 5, 5, "abcdefghij", 5, 2, 3);
+    test("abcdefghij", 5, 5, "abcdefghij", 5, 4, 1);
+    test("abcdefghij", 5, 5, "abcdefghij", 5, 5, 0);
+    test("abcdefghij", 5, 5, "abcdefghij", 5, 6, 0);
+    test("abcdefghij", 5, 5, "abcdefghij", 9, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 9, 1, -4);
+    test("abcdefghij", 5, 5, "abcdefghij", 9, 2, -4);
+    test("abcdefghij", 5, 5, "abcdefghij", 10, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 10, 1, 5);
+    test("abcdefghij", 5, 5, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 0, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 0, 1, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 0, 10, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 0, 19, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 0, 20, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 0, 21, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 1, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 1, 1, 4);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 1, 9, 4);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 1, 18, 4);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 1, 19, 4);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 1, 20, 4);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 10, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 10, 1, -5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 10, 9, -5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 10, 10, -5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 10, 11, -5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 19, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 19, 1, -14);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 19, 2, -14);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 20, 0, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 20, 1, 5);
+    test("abcdefghij", 5, 5, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 5, 6, "", 0, 0, 5);
+    test("abcdefghij", 5, 6, "", 0, 1, 5);
+    test("abcdefghij", 5, 6, "", 1, 0, 0);
+    test("abcdefghij", 5, 6, "abcde", 0, 0, 5);
+    test("abcdefghij", 5, 6, "abcde", 0, 1, 5);
+    test("abcdefghij", 5, 6, "abcde", 0, 2, 5);
+    test("abcdefghij", 5, 6, "abcde", 0, 4, 5);
+    test("abcdefghij", 5, 6, "abcde", 0, 5, 5);
+    test("abcdefghij", 5, 6, "abcde", 0, 6, 5);
+    test("abcdefghij", 5, 6, "abcde", 1, 0, 5);
+    test("abcdefghij", 5, 6, "abcde", 1, 1, 4);
+    test("abcdefghij", 5, 6, "abcde", 1, 2, 4);
+    test("abcdefghij", 5, 6, "abcde", 1, 3, 4);
+    test("abcdefghij", 5, 6, "abcde", 1, 4, 4);
+    test("abcdefghij", 5, 6, "abcde", 1, 5, 4);
+    test("abcdefghij", 5, 6, "abcde", 2, 0, 5);
+    test("abcdefghij", 5, 6, "abcde", 2, 1, 3);
+    test("abcdefghij", 5, 6, "abcde", 2, 2, 3);
+}
+
+void test32()
+{
+    test("abcdefghij", 5, 6, "abcde", 2, 3, 3);
+    test("abcdefghij", 5, 6, "abcde", 2, 4, 3);
+    test("abcdefghij", 5, 6, "abcde", 4, 0, 5);
+    test("abcdefghij", 5, 6, "abcde", 4, 1, 1);
+    test("abcdefghij", 5, 6, "abcde", 4, 2, 1);
+    test("abcdefghij", 5, 6, "abcde", 5, 0, 5);
+    test("abcdefghij", 5, 6, "abcde", 5, 1, 5);
+    test("abcdefghij", 5, 6, "abcde", 6, 0, 0);
+    test("abcdefghij", 5, 6, "abcdefghij", 0, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 0, 1, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 0, 5, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 0, 9, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 0, 10, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 0, 11, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 1, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 1, 1, 4);
+    test("abcdefghij", 5, 6, "abcdefghij", 1, 4, 4);
+    test("abcdefghij", 5, 6, "abcdefghij", 1, 8, 4);
+    test("abcdefghij", 5, 6, "abcdefghij", 1, 9, 4);
+    test("abcdefghij", 5, 6, "abcdefghij", 1, 10, 4);
+    test("abcdefghij", 5, 6, "abcdefghij", 5, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 5, 1, 4);
+    test("abcdefghij", 5, 6, "abcdefghij", 5, 2, 3);
+    test("abcdefghij", 5, 6, "abcdefghij", 5, 4, 1);
+    test("abcdefghij", 5, 6, "abcdefghij", 5, 5, 0);
+    test("abcdefghij", 5, 6, "abcdefghij", 5, 6, 0);
+    test("abcdefghij", 5, 6, "abcdefghij", 9, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 9, 1, -4);
+    test("abcdefghij", 5, 6, "abcdefghij", 9, 2, -4);
+    test("abcdefghij", 5, 6, "abcdefghij", 10, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 10, 1, 5);
+    test("abcdefghij", 5, 6, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 0, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 0, 1, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 0, 10, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 0, 19, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 0, 20, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 0, 21, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 1, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 1, 1, 4);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 1, 9, 4);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 1, 18, 4);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 1, 19, 4);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 1, 20, 4);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 10, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 10, 1, -5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 10, 9, -5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 10, 10, -5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 10, 11, -5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 19, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 19, 1, -14);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 19, 2, -14);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 20, 0, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 20, 1, 5);
+    test("abcdefghij", 5, 6, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 9, 0, "", 0, 0, 0);
+    test("abcdefghij", 9, 0, "", 0, 1, 0);
+    test("abcdefghij", 9, 0, "", 1, 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 0, 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 0, 1, -1);
+    test("abcdefghij", 9, 0, "abcde", 0, 2, -2);
+    test("abcdefghij", 9, 0, "abcde", 0, 4, -4);
+    test("abcdefghij", 9, 0, "abcde", 0, 5, -5);
+    test("abcdefghij", 9, 0, "abcde", 0, 6, -5);
+    test("abcdefghij", 9, 0, "abcde", 1, 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 1, 1, -1);
+    test("abcdefghij", 9, 0, "abcde", 1, 2, -2);
+    test("abcdefghij", 9, 0, "abcde", 1, 3, -3);
+    test("abcdefghij", 9, 0, "abcde", 1, 4, -4);
+    test("abcdefghij", 9, 0, "abcde", 1, 5, -4);
+    test("abcdefghij", 9, 0, "abcde", 2, 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 2, 1, -1);
+    test("abcdefghij", 9, 0, "abcde", 2, 2, -2);
+    test("abcdefghij", 9, 0, "abcde", 2, 3, -3);
+    test("abcdefghij", 9, 0, "abcde", 2, 4, -3);
+    test("abcdefghij", 9, 0, "abcde", 4, 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 4, 1, -1);
+    test("abcdefghij", 9, 0, "abcde", 4, 2, -1);
+    test("abcdefghij", 9, 0, "abcde", 5, 0, 0);
+    test("abcdefghij", 9, 0, "abcde", 5, 1, 0);
+    test("abcdefghij", 9, 0, "abcde", 6, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghij", 9, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghij", 9, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghij", 9, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghij", 9, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghij", 9, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghij", 9, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghij", 9, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghij", 9, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghij", 9, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 9, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 9, 0, "abcdefghij", 5, 6, -5);
+}
+
+void test33()
+{
+    test("abcdefghij", 9, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghij", 9, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghij", 9, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghij", 9, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 9, 1, "", 0, 0, 1);
+    test("abcdefghij", 9, 1, "", 0, 1, 1);
+    test("abcdefghij", 9, 1, "", 1, 0, 0);
+    test("abcdefghij", 9, 1, "abcde", 0, 0, 1);
+    test("abcdefghij", 9, 1, "abcde", 0, 1, 9);
+    test("abcdefghij", 9, 1, "abcde", 0, 2, 9);
+    test("abcdefghij", 9, 1, "abcde", 0, 4, 9);
+    test("abcdefghij", 9, 1, "abcde", 0, 5, 9);
+    test("abcdefghij", 9, 1, "abcde", 0, 6, 9);
+    test("abcdefghij", 9, 1, "abcde", 1, 0, 1);
+    test("abcdefghij", 9, 1, "abcde", 1, 1, 8);
+    test("abcdefghij", 9, 1, "abcde", 1, 2, 8);
+    test("abcdefghij", 9, 1, "abcde", 1, 3, 8);
+    test("abcdefghij", 9, 1, "abcde", 1, 4, 8);
+    test("abcdefghij", 9, 1, "abcde", 1, 5, 8);
+    test("abcdefghij", 9, 1, "abcde", 2, 0, 1);
+    test("abcdefghij", 9, 1, "abcde", 2, 1, 7);
+    test("abcdefghij", 9, 1, "abcde", 2, 2, 7);
+    test("abcdefghij", 9, 1, "abcde", 2, 3, 7);
+    test("abcdefghij", 9, 1, "abcde", 2, 4, 7);
+    test("abcdefghij", 9, 1, "abcde", 4, 0, 1);
+    test("abcdefghij", 9, 1, "abcde", 4, 1, 5);
+    test("abcdefghij", 9, 1, "abcde", 4, 2, 5);
+    test("abcdefghij", 9, 1, "abcde", 5, 0, 1);
+    test("abcdefghij", 9, 1, "abcde", 5, 1, 1);
+    test("abcdefghij", 9, 1, "abcde", 6, 0, 0);
+    test("abcdefghij", 9, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghij", 0, 1, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 0, 5, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 0, 9, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 0, 10, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 0, 11, 9);
+    test("abcdefghij", 9, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghij", 1, 1, 8);
+    test("abcdefghij", 9, 1, "abcdefghij", 1, 4, 8);
+    test("abcdefghij", 9, 1, "abcdefghij", 1, 8, 8);
+    test("abcdefghij", 9, 1, "abcdefghij", 1, 9, 8);
+    test("abcdefghij", 9, 1, "abcdefghij", 1, 10, 8);
+    test("abcdefghij", 9, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghij", 5, 1, 4);
+    test("abcdefghij", 9, 1, "abcdefghij", 5, 2, 4);
+    test("abcdefghij", 9, 1, "abcdefghij", 5, 4, 4);
+    test("abcdefghij", 9, 1, "abcdefghij", 5, 5, 4);
+    test("abcdefghij", 9, 1, "abcdefghij", 5, 6, 4);
+    test("abcdefghij", 9, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghij", 9, 1, 0);
+    test("abcdefghij", 9, 1, "abcdefghij", 9, 2, 0);
+    test("abcdefghij", 9, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghij", 9, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 0, 1, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 0, 10, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 0, 19, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 0, 20, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 0, 21, 9);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 1, 1, 8);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 1, 9, 8);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 1, 18, 8);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 1, 19, 8);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 1, 20, 8);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 10, 5, -1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 10, 9, -1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 10, 10, -1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 10, 11, -1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 19, 1, -10);
+}
+
+void test34()
+{
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 19, 2, -10);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghij", 9, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 9, 2, "", 0, 0, 1);
+    test("abcdefghij", 9, 2, "", 0, 1, 1);
+    test("abcdefghij", 9, 2, "", 1, 0, 0);
+    test("abcdefghij", 9, 2, "abcde", 0, 0, 1);
+    test("abcdefghij", 9, 2, "abcde", 0, 1, 9);
+    test("abcdefghij", 9, 2, "abcde", 0, 2, 9);
+    test("abcdefghij", 9, 2, "abcde", 0, 4, 9);
+    test("abcdefghij", 9, 2, "abcde", 0, 5, 9);
+    test("abcdefghij", 9, 2, "abcde", 0, 6, 9);
+    test("abcdefghij", 9, 2, "abcde", 1, 0, 1);
+    test("abcdefghij", 9, 2, "abcde", 1, 1, 8);
+    test("abcdefghij", 9, 2, "abcde", 1, 2, 8);
+    test("abcdefghij", 9, 2, "abcde", 1, 3, 8);
+    test("abcdefghij", 9, 2, "abcde", 1, 4, 8);
+    test("abcdefghij", 9, 2, "abcde", 1, 5, 8);
+    test("abcdefghij", 9, 2, "abcde", 2, 0, 1);
+    test("abcdefghij", 9, 2, "abcde", 2, 1, 7);
+    test("abcdefghij", 9, 2, "abcde", 2, 2, 7);
+    test("abcdefghij", 9, 2, "abcde", 2, 3, 7);
+    test("abcdefghij", 9, 2, "abcde", 2, 4, 7);
+    test("abcdefghij", 9, 2, "abcde", 4, 0, 1);
+    test("abcdefghij", 9, 2, "abcde", 4, 1, 5);
+    test("abcdefghij", 9, 2, "abcde", 4, 2, 5);
+    test("abcdefghij", 9, 2, "abcde", 5, 0, 1);
+    test("abcdefghij", 9, 2, "abcde", 5, 1, 1);
+    test("abcdefghij", 9, 2, "abcde", 6, 0, 0);
+    test("abcdefghij", 9, 2, "abcdefghij", 0, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghij", 0, 1, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 0, 5, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 0, 9, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 0, 10, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 0, 11, 9);
+    test("abcdefghij", 9, 2, "abcdefghij", 1, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghij", 1, 1, 8);
+    test("abcdefghij", 9, 2, "abcdefghij", 1, 4, 8);
+    test("abcdefghij", 9, 2, "abcdefghij", 1, 8, 8);
+    test("abcdefghij", 9, 2, "abcdefghij", 1, 9, 8);
+    test("abcdefghij", 9, 2, "abcdefghij", 1, 10, 8);
+    test("abcdefghij", 9, 2, "abcdefghij", 5, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghij", 5, 1, 4);
+    test("abcdefghij", 9, 2, "abcdefghij", 5, 2, 4);
+    test("abcdefghij", 9, 2, "abcdefghij", 5, 4, 4);
+    test("abcdefghij", 9, 2, "abcdefghij", 5, 5, 4);
+    test("abcdefghij", 9, 2, "abcdefghij", 5, 6, 4);
+    test("abcdefghij", 9, 2, "abcdefghij", 9, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghij", 9, 1, 0);
+    test("abcdefghij", 9, 2, "abcdefghij", 9, 2, 0);
+    test("abcdefghij", 9, 2, "abcdefghij", 10, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghij", 10, 1, 1);
+    test("abcdefghij", 9, 2, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 0, 1, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 0, 10, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 0, 19, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 0, 20, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 0, 21, 9);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 1, 1, 8);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 1, 9, 8);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 1, 18, 8);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 1, 19, 8);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 1, 20, 8);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 10, 5, -1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 10, 9, -1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 10, 10, -1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 10, 11, -1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 19, 1, -10);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 19, 2, -10);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghij", 9, 2, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 10, 0, "", 0, 0, 0);
+    test("abcdefghij", 10, 0, "", 0, 1, 0);
+    test("abcdefghij", 10, 0, "", 1, 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 0, 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 0, 1, -1);
+    test("abcdefghij", 10, 0, "abcde", 0, 2, -2);
+    test("abcdefghij", 10, 0, "abcde", 0, 4, -4);
+    test("abcdefghij", 10, 0, "abcde", 0, 5, -5);
+    test("abcdefghij", 10, 0, "abcde", 0, 6, -5);
+    test("abcdefghij", 10, 0, "abcde", 1, 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 1, 1, -1);
+    test("abcdefghij", 10, 0, "abcde", 1, 2, -2);
+    test("abcdefghij", 10, 0, "abcde", 1, 3, -3);
+    test("abcdefghij", 10, 0, "abcde", 1, 4, -4);
+    test("abcdefghij", 10, 0, "abcde", 1, 5, -4);
+    test("abcdefghij", 10, 0, "abcde", 2, 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 2, 1, -1);
+    test("abcdefghij", 10, 0, "abcde", 2, 2, -2);
+    test("abcdefghij", 10, 0, "abcde", 2, 3, -3);
+    test("abcdefghij", 10, 0, "abcde", 2, 4, -3);
+    test("abcdefghij", 10, 0, "abcde", 4, 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 4, 1, -1);
+}
+
+void test35()
+{
+    test("abcdefghij", 10, 0, "abcde", 4, 2, -1);
+    test("abcdefghij", 10, 0, "abcde", 5, 0, 0);
+    test("abcdefghij", 10, 0, "abcde", 5, 1, 0);
+    test("abcdefghij", 10, 0, "abcde", 6, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghij", 10, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghij", 10, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghij", 10, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghij", 10, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghij", 10, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghij", 10, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghij", 10, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghij", 10, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghij", 10, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 10, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 10, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 10, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghij", 10, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghij", 10, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghij", 10, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 10, 1, "", 0, 0, 0);
+    test("abcdefghij", 10, 1, "", 0, 1, 0);
+    test("abcdefghij", 10, 1, "", 1, 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 0, 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 0, 1, -1);
+    test("abcdefghij", 10, 1, "abcde", 0, 2, -2);
+    test("abcdefghij", 10, 1, "abcde", 0, 4, -4);
+    test("abcdefghij", 10, 1, "abcde", 0, 5, -5);
+    test("abcdefghij", 10, 1, "abcde", 0, 6, -5);
+    test("abcdefghij", 10, 1, "abcde", 1, 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 1, 1, -1);
+    test("abcdefghij", 10, 1, "abcde", 1, 2, -2);
+    test("abcdefghij", 10, 1, "abcde", 1, 3, -3);
+    test("abcdefghij", 10, 1, "abcde", 1, 4, -4);
+    test("abcdefghij", 10, 1, "abcde", 1, 5, -4);
+    test("abcdefghij", 10, 1, "abcde", 2, 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 2, 1, -1);
+    test("abcdefghij", 10, 1, "abcde", 2, 2, -2);
+    test("abcdefghij", 10, 1, "abcde", 2, 3, -3);
+    test("abcdefghij", 10, 1, "abcde", 2, 4, -3);
+    test("abcdefghij", 10, 1, "abcde", 4, 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 4, 1, -1);
+    test("abcdefghij", 10, 1, "abcde", 4, 2, -1);
+    test("abcdefghij", 10, 1, "abcde", 5, 0, 0);
+    test("abcdefghij", 10, 1, "abcde", 5, 1, 0);
+    test("abcdefghij", 10, 1, "abcde", 6, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghij", 0, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghij", 0, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghij", 0, 5, -5);
+    test("abcdefghij", 10, 1, "abcdefghij", 0, 9, -9);
+    test("abcdefghij", 10, 1, "abcdefghij", 0, 10, -10);
+    test("abcdefghij", 10, 1, "abcdefghij", 0, 11, -10);
+    test("abcdefghij", 10, 1, "abcdefghij", 1, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghij", 1, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghij", 1, 4, -4);
+    test("abcdefghij", 10, 1, "abcdefghij", 1, 8, -8);
+    test("abcdefghij", 10, 1, "abcdefghij", 1, 9, -9);
+    test("abcdefghij", 10, 1, "abcdefghij", 1, 10, -9);
+    test("abcdefghij", 10, 1, "abcdefghij", 5, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghij", 5, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghij", 5, 2, -2);
+    test("abcdefghij", 10, 1, "abcdefghij", 5, 4, -4);
+    test("abcdefghij", 10, 1, "abcdefghij", 5, 5, -5);
+    test("abcdefghij", 10, 1, "abcdefghij", 5, 6, -5);
+    test("abcdefghij", 10, 1, "abcdefghij", 9, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghij", 9, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghij", 9, 2, -1);
+    test("abcdefghij", 10, 1, "abcdefghij", 10, 0, 0);
+}
+
+void test36()
+{
+    test("abcdefghij", 10, 1, "abcdefghij", 10, 1, 0);
+    test("abcdefghij", 10, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghij", 10, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghij", 11, 0, "", 0, 0, 0);
+    test("abcdefghij", 11, 0, "", 0, 1, 0);
+    test("abcdefghij", 11, 0, "", 1, 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 0, 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 0, 1, 0);
+    test("abcdefghij", 11, 0, "abcde", 0, 2, 0);
+    test("abcdefghij", 11, 0, "abcde", 0, 4, 0);
+    test("abcdefghij", 11, 0, "abcde", 0, 5, 0);
+    test("abcdefghij", 11, 0, "abcde", 0, 6, 0);
+    test("abcdefghij", 11, 0, "abcde", 1, 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 1, 1, 0);
+    test("abcdefghij", 11, 0, "abcde", 1, 2, 0);
+    test("abcdefghij", 11, 0, "abcde", 1, 3, 0);
+    test("abcdefghij", 11, 0, "abcde", 1, 4, 0);
+    test("abcdefghij", 11, 0, "abcde", 1, 5, 0);
+    test("abcdefghij", 11, 0, "abcde", 2, 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 2, 1, 0);
+    test("abcdefghij", 11, 0, "abcde", 2, 2, 0);
+    test("abcdefghij", 11, 0, "abcde", 2, 3, 0);
+    test("abcdefghij", 11, 0, "abcde", 2, 4, 0);
+    test("abcdefghij", 11, 0, "abcde", 4, 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 4, 1, 0);
+    test("abcdefghij", 11, 0, "abcde", 4, 2, 0);
+    test("abcdefghij", 11, 0, "abcde", 5, 0, 0);
+    test("abcdefghij", 11, 0, "abcde", 5, 1, 0);
+    test("abcdefghij", 11, 0, "abcde", 6, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0, 5, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0, 9, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0, 10, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 0, 11, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 1, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 1, 4, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 1, 8, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 1, 9, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 1, 10, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 5, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 5, 2, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 5, 4, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 5, 5, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 5, 6, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 9, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 9, 2, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0, 10, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0, 19, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0, 20, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 0, 21, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 1, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 1, 9, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 1, 18, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 1, 19, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 1, 20, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 10, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 10, 5, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 10, 9, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 10, 10, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 10, 11, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 19, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 19, 2, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghij", 11, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+}
+
+void test37()
+{
+    test("abcdefghijklmnopqrst", 0, 0, "", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 0, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 0, 4, -4);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 0, 6, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 1, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 1, 3, -3);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 1, 5, -4);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 2, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 2, 3, -3);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 2, 4, -3);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 4, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 4, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 4, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghijklmnopqrst", 0, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 0, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 0, 4, -3);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 0, 5, -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 0, 6, -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 1, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 1, 3, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 1, 5, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 2, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 2, 1, -2);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 2, 3, -2);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 2, 4, -2);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 4, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 4, 1, -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 4, 2, -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 5, 1, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcde", 6, 0, 0);
+}
+
+void test38()
+{
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 0, 5, -4);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 0, 9, -8);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 0, 10, -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 0, 11, -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 1, 8, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 1, 10, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 5, 1, -5);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 5, 2, -5);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 5, 4, -5);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 9, 1, -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 9, 2, -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 0, 10, -9);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 0, 19, -18);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 0, 20, -19);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 0, 21, -19);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghijklmnopqrst", 0, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 0, 1, 9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 0, 2, 8);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 0, 4, 6);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 0, 5, 5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 0, 6, 5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 1, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 1, 3, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 1, 5, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 2, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 2, 1, -2);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 2, 3, -2);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 2, 4, -2);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 4, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 4, 1, -4);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 4, 2, -4);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 5, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 5, 1, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0, 1, 9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0, 5, 5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0, 9, 1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0, 10, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 0, 11, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 1, 8, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 1, 10, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 5, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 5, 1, -5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 5, 2, -5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 5, 4, -5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 9, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 9, 1, -9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 9, 2, -9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 10, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 10, 1, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 0, 1, 9);
+}
+
+void test39()
+{
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 0, 10, 0);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 0, 19, -9);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 0, 20, -10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 0, 21, -10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 10, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 19, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 20, 0, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 20, 1, 10);
+    test("abcdefghijklmnopqrst", 0, 10, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 19, "", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 0, 1, 18);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 0, 2, 17);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 0, 4, 15);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 0, 5, 14);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 0, 6, 14);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 1, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 1, 3, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 1, 5, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 2, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 2, 1, -2);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 2, 3, -2);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 2, 4, -2);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 4, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 4, 1, -4);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 4, 2, -4);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 5, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 5, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 0, 1, 18);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 0, 5, 14);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 0, 9, 10);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 0, 10, 9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 0, 11, 9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 1, 8, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 1, 10, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 5, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 5, 1, -5);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 5, 2, -5);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 5, 4, -5);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 9, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 9, 1, -9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 9, 2, -9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 10, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 10, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 0, 1, 18);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 0, 10, 9);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 0, 19, 0);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 0, 20, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 0, 21, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 10, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 19, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 20, 0, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 20, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 19, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 20, "", 0, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "", 0, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 0, 0, 20);
+}
+
+void test40()
+{
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 0, 2, 18);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 0, 4, 16);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 0, 5, 15);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 0, 6, 15);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 1, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 1, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 1, 3, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 1, 5, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 2, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 2, 1, -2);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 2, 3, -2);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 2, 4, -2);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 4, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 4, 1, -4);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 4, 2, -4);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 5, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 5, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 0, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 0, 5, 15);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 0, 9, 11);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 0, 11, 10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 1, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 1, 8, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 1, 10, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 5, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 5, 1, -5);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 5, 2, -5);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 5, 4, -5);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 9, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 9, 1, -9);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 9, 2, -9);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 10, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 10, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0, 20, 0);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 0, 21, 0);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 1, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 10, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 19, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 20, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 20, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 20, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 21, "", 0, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "", 0, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 0, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 0, 2, 18);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 0, 4, 16);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 0, 5, 15);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 0, 6, 15);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 1, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 1, 2, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 1, 3, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 1, 5, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 2, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 2, 1, -2);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 2, 3, -2);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 2, 4, -2);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 4, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 4, 1, -4);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 4, 2, -4);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 5, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 5, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 0, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 0, 5, 15);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 0, 9, 11);
+}
+
+void test41()
+{
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 0, 11, 10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 1, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 1, 4, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 1, 8, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 1, 10, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 5, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 5, 1, -5);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 5, 2, -5);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 5, 4, -5);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 9, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 9, 1, -9);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 9, 2, -9);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 10, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 10, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0, 20, 0);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 0, 21, 0);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 1, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 1, 9, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 1, 18, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 10, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 10, 1, -10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 10, 5, -10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 10, 9, -10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 19, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 19, 1, -19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 19, 2, -19);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 20, 0, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 20, 1, 20);
+    test("abcdefghijklmnopqrst", 0, 21, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 0, 2, -2);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 0, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 0, 6, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 1, 2, -2);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 1, 3, -3);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 1, 5, -4);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 2, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 2, 3, -3);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 2, 4, -3);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 4, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 4, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 4, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+}
+
+void test42()
+{
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghijklmnopqrst", 1, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 1, "", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 0, 2, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 0, 4, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 0, 6, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1, 1, 0);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1, 3, -2);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1, 4, -3);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 1, 5, -3);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 2, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 2, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 2, 3, -1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 2, 4, -1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 4, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 4, 1, -3);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 4, 2, -3);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 5, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 0, 9, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 0, 11, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1, 1, 0);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1, 4, -3);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1, 8, -7);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1, 9, -8);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 1, 10, -8);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 5, 1, -4);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 5, 2, -4);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 5, 5, -4);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 5, 6, -4);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 9, 1, -8);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 9, 2, -8);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1, 1, 0);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1, 9, -8);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1, 18, -17);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1, 19, -18);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 1, 20, -18);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 9, "", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "", 0, 1, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 0, 2, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 0, 4, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 0, 5, 1);
+}
+
+void test43()
+{
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 0, 6, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1, 1, 8);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1, 2, 7);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1, 3, 6);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1, 4, 5);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 1, 5, 5);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 2, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 2, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 2, 3, -1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 2, 4, -1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 4, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 4, 1, -3);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 4, 2, -3);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 5, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 5, 1, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 0, 9, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 0, 11, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1, 1, 8);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1, 4, 5);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1, 8, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1, 9, 0);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 1, 10, 0);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 5, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 5, 1, -4);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 5, 2, -4);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 5, 5, -4);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 5, 6, -4);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 9, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 9, 1, -8);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 9, 2, -8);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 10, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 10, 1, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1, 1, 8);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1, 9, 0);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1, 18, -9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1, 19, -10);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 1, 20, -10);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 10, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 19, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 20, 0, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 20, 1, 9);
+    test("abcdefghijklmnopqrst", 1, 9, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 18, "", 0, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "", 0, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 0, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 0, 2, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 0, 4, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 0, 6, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1, 1, 17);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1, 2, 16);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1, 3, 15);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1, 4, 14);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 1, 5, 14);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 2, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 2, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 2, 3, -1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 2, 4, -1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 4, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 4, 1, -3);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 4, 2, -3);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 5, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 5, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 0, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 0, 9, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 0, 11, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1, 1, 17);
+}
+
+void test44()
+{
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1, 4, 14);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1, 8, 10);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 1, 10, 9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 5, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 5, 1, -4);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 5, 2, -4);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 5, 5, -4);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 5, 6, -4);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 9, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 9, 1, -8);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 9, 2, -8);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 10, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 10, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 0, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1, 1, 17);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1, 18, 0);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1, 19, -1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 1, 20, -1);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 10, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 19, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 20, 0, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 20, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 18, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 19, "", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 0, 2, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 0, 4, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 0, 6, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1, 2, 17);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1, 3, 16);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1, 4, 15);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 1, 5, 15);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 2, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 2, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 2, 3, -1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 2, 4, -1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 4, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 4, 1, -3);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 4, 2, -3);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 5, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 5, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 0, 9, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 0, 11, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1, 4, 15);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1, 8, 11);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1, 9, 10);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 1, 10, 10);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 5, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 5, 1, -4);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 5, 2, -4);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 5, 5, -4);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 5, 6, -4);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 9, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 9, 1, -8);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 9, 2, -8);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 10, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 10, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1, 9, 10);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1, 18, 1);
+}
+
+void test45()
+{
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1, 19, 0);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 1, 20, 0);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 10, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 19, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 20, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 20, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 19, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 20, "", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 0, 2, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 0, 4, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 0, 6, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1, 2, 17);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1, 3, 16);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1, 4, 15);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 1, 5, 15);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 2, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 2, 2, -1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 2, 3, -1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 2, 4, -1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 4, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 4, 1, -3);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 4, 2, -3);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 5, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 5, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 0, 5, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 0, 9, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 0, 11, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1, 4, 15);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1, 8, 11);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1, 9, 10);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 1, 10, 10);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 5, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 5, 1, -4);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 5, 2, -4);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 5, 5, -4);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 5, 6, -4);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 9, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 9, 1, -8);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 9, 2, -8);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 10, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 10, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 0, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 0, 10, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 0, 19, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 0, 20, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 0, 21, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1, 9, 10);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1, 18, 1);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1, 19, 0);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 1, 20, 0);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 10, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 10, 1, -9);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 10, 5, -9);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 19, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 19, 1, -18);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 19, 2, -18);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 20, 0, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 20, 1, 19);
+    test("abcdefghijklmnopqrst", 1, 20, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 0, 2, -2);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 0, 4, -4);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 0, 6, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 1, 2, -2);
+}
+
+void test46()
+{
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 1, 3, -3);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 1, 5, -4);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 2, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 2, 3, -3);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 2, 4, -3);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 4, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 4, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 4, 2, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghijklmnopqrst", 10, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 1, "", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 0, 2, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 0, 4, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 0, 6, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 1, 2, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 1, 3, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 1, 5, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 2, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 2, 1, 8);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 2, 2, 8);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 2, 3, 8);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 2, 4, 8);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 4, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 4, 1, 6);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 4, 2, 6);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 5, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 0, 9, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 0, 11, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 1, 8, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 1, 10, 9);
+}
+
+void test47()
+{
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 5, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 5, 2, 5);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 5, 4, 5);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 5, 5, 5);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 5, 6, 5);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 9, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 9, 2, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 0, 19, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 0, 20, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 0, 21, 10);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 1, 18, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 1, 19, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 1, 20, 9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10, 5, -4);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10, 9, -8);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10, 10, -9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 10, 11, -9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 19, 1, -9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 19, 2, -9);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 5, "", 0, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "", 0, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 0, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 0, 2, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 0, 4, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 0, 6, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 1, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 1, 2, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 1, 3, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 1, 5, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 2, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 2, 1, 8);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 2, 2, 8);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 2, 3, 8);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 2, 4, 8);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 4, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 4, 1, 6);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 4, 2, 6);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 5, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 5, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 0, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 0, 9, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 0, 11, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 1, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 1, 8, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 1, 10, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 5, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 5, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 5, 2, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 5, 4, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 5, 5, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 5, 6, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 9, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 9, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 9, 2, 1);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 10, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 10, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 0, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 0, 19, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 0, 20, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 0, 21, 10);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 1, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 1, 18, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 1, 19, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 1, 20, 9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10, 1, 4);
+}
+
+void test48()
+{
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10, 5, 0);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10, 9, -4);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10, 10, -5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 10, 11, -5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 19, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 19, 1, -9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 19, 2, -9);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 20, 0, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 20, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 5, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 9, "", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "", 0, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 0, 2, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 0, 4, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 0, 6, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 1, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 1, 2, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 1, 3, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 1, 5, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 2, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 2, 1, 8);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 2, 2, 8);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 2, 3, 8);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 2, 4, 8);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 4, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 4, 1, 6);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 4, 2, 6);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 5, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 5, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 0, 9, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 0, 11, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 1, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 1, 8, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 1, 10, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 5, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 5, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 5, 2, 5);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 5, 4, 5);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 5, 5, 5);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 5, 6, 5);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 9, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 9, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 9, 2, 1);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 10, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 10, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 0, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 0, 19, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 0, 20, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 0, 21, 10);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 1, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 1, 18, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 1, 19, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 1, 20, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10, 1, 8);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10, 5, 4);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10, 9, 0);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10, 10, -1);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 10, 11, -1);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 19, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 19, 1, -9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 19, 2, -9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 20, 0, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 20, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 9, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 10, "", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 0, 2, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 0, 4, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 0, 6, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 1, 2, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 1, 3, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 1, 5, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 2, 0, 10);
+}
+
+void test49()
+{
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 2, 1, 8);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 2, 2, 8);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 2, 3, 8);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 2, 4, 8);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 4, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 4, 1, 6);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 4, 2, 6);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 5, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 5, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 0, 9, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 0, 11, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 1, 8, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 1, 10, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 5, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 5, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 5, 2, 5);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 5, 4, 5);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 5, 5, 5);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 5, 6, 5);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 9, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 9, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 9, 2, 1);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 10, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 10, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 0, 19, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 0, 20, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 0, 21, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 1, 18, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 1, 19, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 1, 20, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10, 5, 5);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10, 9, 1);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10, 10, 0);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 10, 11, 0);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 19, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 19, 1, -9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 19, 2, -9);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 20, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 20, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 10, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 11, "", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 0, 2, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 0, 4, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 0, 6, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 1, 2, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 1, 3, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 1, 5, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 2, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 2, 1, 8);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 2, 2, 8);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 2, 3, 8);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 2, 4, 8);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 4, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 4, 1, 6);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 4, 2, 6);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 5, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 5, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 0, 5, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 0, 9, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 0, 11, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 1, 4, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 1, 8, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 1, 10, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 5, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 5, 1, 5);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 5, 2, 5);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 5, 4, 5);
+}
+
+void test50()
+{
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 5, 5, 5);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 5, 6, 5);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 9, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 9, 1, 1);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 9, 2, 1);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 10, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 10, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 0, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 0, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 0, 10, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 0, 19, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 0, 20, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 0, 21, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 1, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 1, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 1, 9, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 1, 18, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 1, 19, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 1, 20, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10, 1, 9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10, 5, 5);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10, 9, 1);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10, 10, 0);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 10, 11, 0);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 19, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 19, 1, -9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 19, 2, -9);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 20, 0, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 20, 1, 10);
+    test("abcdefghijklmnopqrst", 10, 11, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 0, 2, -2);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 0, 4, -4);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 0, 6, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 1, 2, -2);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 1, 3, -3);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 1, 5, -4);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 2, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 2, 3, -3);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 2, 4, -3);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 4, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 4, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 4, 2, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 9, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+}
+
+void test51()
+{
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghijklmnopqrst", 19, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 1, "", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 0, 2, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 0, 4, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 0, 5, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 0, 6, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 1, 2, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 1, 3, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 1, 4, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 1, 5, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 2, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 2, 1, 17);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 2, 2, 17);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 2, 3, 17);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 2, 4, 17);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 4, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 4, 1, 15);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 4, 2, 15);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 5, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 0, 5, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 0, 9, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 0, 10, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 0, 11, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 1, 4, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 1, 8, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 1, 9, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 1, 10, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 5, 1, 14);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 5, 2, 14);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 5, 4, 14);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 5, 5, 14);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 5, 6, 14);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 9, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 9, 1, 10);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 9, 2, 10);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 10, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 0, 10, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 0, 19, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 0, 20, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 0, 21, 19);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 1, 9, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 1, 18, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 1, 19, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 1, 20, 18);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 10, 1, 9);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 10, 5, 9);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 10, 9, 9);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 10, 10, 9);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 10, 11, 9);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 19, 1, 0);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 19, 2, 0);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 2, "", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "", 0, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 0, 2, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 0, 4, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 0, 5, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 0, 6, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 1, 2, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 1, 3, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 1, 4, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 1, 5, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 2, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 2, 1, 17);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 2, 2, 17);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 2, 3, 17);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 2, 4, 17);
+}
+
+void test52()
+{
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 4, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 4, 1, 15);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 4, 2, 15);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 5, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 0, 5, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 0, 9, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 0, 10, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 0, 11, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 1, 4, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 1, 8, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 1, 9, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 1, 10, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 5, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 5, 1, 14);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 5, 2, 14);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 5, 4, 14);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 5, 5, 14);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 5, 6, 14);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 9, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 9, 1, 10);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 9, 2, 10);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 10, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 0, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 0, 1, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 0, 10, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 0, 19, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 0, 20, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 0, 21, 19);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 1, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 1, 1, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 1, 9, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 1, 18, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 1, 19, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 1, 20, 18);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 10, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 10, 1, 9);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 10, 5, 9);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 10, 9, 9);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 10, 10, 9);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 10, 11, 9);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 19, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 19, 1, 0);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 19, 2, 0);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 20, 0, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 20, 1, 1);
+    test("abcdefghijklmnopqrst", 19, 2, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 0, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 0, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 0, 6, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 1, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 1, 3, -3);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 1, 5, -4);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 2, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 2, 3, -3);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 2, 4, -3);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 4, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 4, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 4, 2, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 0, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 0, 11, -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 1, 8, -8);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 1, 10, -9);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 5, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 5, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 9, 1, -1);
+}
+
+void test53()
+{
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 9, 2, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 0, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 0, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 0, 6, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 1, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 1, 3, -3);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 1, 5, -4);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 2, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 2, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 2, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 2, 3, -3);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 2, 4, -3);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 4, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 4, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 4, 2, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 0, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 0, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 0, 11, -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 1, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 1, 8, -8);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 1, 10, -9);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 5, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 5, 2, -2);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 5, 4, -4);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 5, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 5, 6, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 9, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 9, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 9, 2, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 0, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 0, 10, -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 0, 19, -19);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 0, 20, -20);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 0, 21, -20);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 1, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 1, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 1, 18, -18);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 1, 19, -19);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 1, 20, -19);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 10, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 10, 5, -5);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 10, 9, -9);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 10, 10, -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 10, 11, -10);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 19, 1, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 19, 2, -1);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 20, 0, 0);
+}
+
+void test54()
+{
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghijklmnopqrst", 20, 1, "abcdefghijklmnopqrst", 21, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 4, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 5, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 0, 6, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 3, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 4, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 1, 5, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 2, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 2, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 2, 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 2, 3, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 2, 4, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 4, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 4, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 4, 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcde", 6, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0, 5, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0, 9, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0, 10, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 0, 11, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 1, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 1, 4, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 1, 8, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 1, 9, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 1, 10, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 5, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 5, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 5, 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 5, 4, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 5, 5, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 5, 6, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 9, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 9, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 9, 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghij", 11, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0, 10, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0, 19, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0, 20, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 0, 21, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 1, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 1, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 1, 9, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 1, 18, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 1, 19, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 1, 20, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 10, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 10, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 10, 5, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 10, 9, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 10, 10, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 10, 11, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 19, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 19, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 19, 2, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 20, 0, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 20, 1, 0);
+    test("abcdefghijklmnopqrst", 21, 0, "abcdefghijklmnopqrst", 21, 0, 0);
+}
+
+
+int main () {
+    test0();
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+    test6();
+    test7();
+    test8();
+    test9();
+    test10();
+    test11();
+    test12();
+    test13();
+    test14();
+    test15();
+    test16();
+    test17();
+    test18();
+    test19();
+    test20();
+    test21();
+    test22();
+    test23();
+    test24();
+    test25();
+    test26();
+    test27();
+    test28();
+    test29();
+    test30();
+    test31();
+    test32();
+    test33();
+    test34();
+    test35();
+    test36();
+    test37();
+    test38();
+    test39();
+    test40();
+    test41();
+    test42();
+    test43();
+    test44();
+    test45();
+    test46();
+    test47();
+    test48();
+    test49();
+    test50();
+    test51();
+    test52();
+    test53();
+    test54();
+
+    
+    {
+    test("abcde", 5, 1, "", 0, 0, 0);
+    test("abcde", 2, 4, "", 0, 0, 3);
+    test("abcde", 2, 4, "abcde", 3, 4, -2);
+    test("ABCde", 2, 4, "abcde", 2, 4, -1);
+    }
+
+    {
+    test(L"abcde", 5, 1, L"", 0, 0, 0);
+    test(L"abcde", 2, 4, L"", 0, 0, 3);
+    test(L"abcde", 2, 4, L"abcde", 3, 4, -2);
+    test(L"ABCde", 2, 4, L"abcde", 2, 4, -1);
+    }
+
+#if __cplusplus >= 201103L
+    {
+    test(u"abcde", 5, 1, u"", 0, 0, 0);
+    test(u"abcde", 2, 4, u"", 0, 0, 3);
+    test(u"abcde", 2, 4, u"abcde", 3, 4, -2);
+    test(u"ABCde", 2, 4, u"abcde", 2, 4, -1);
+    }
+
+    {
+    test(U"abcde", 5, 1, U"", 0, 0, 0);
+    test(U"abcde", 2, 4, U"", 0, 0, 3);
+    test(U"abcde", 2, 4, U"abcde", 3, 4, -2);
+    test(U"ABCde", 2, 4, U"abcde", 2, 4, -1);
+    }
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1 { "abcde", 5 };
+    static_assert ( sv1.compare(5, 1, "", 0, 0) == 0, "" );
+    static_assert ( sv1.compare(2, 4, "", 0, 0) == 1, "" );
+    static_assert ( sv1.compare(2, 4, "abcde", 3, 4) == -1, "" );
+    }
+#endif
+}
diff --git a/test/experimental/string.view/string.view.ops/compare.sv.pass.cpp b/test/experimental/string.view/string.view.ops/compare.sv.pass.cpp
new file mode 100644
index 0000000..3f68669
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/compare.sv.pass.cpp
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+// constexpr int compare(basic_string_view str) const noexcept;
+
+#include <experimental/string_view>
+#include <cassert>
+
+#include "constexpr_char_traits.hpp"
+
+int sign ( int x ) { return x > 0 ? 1 : ( x < 0 ? -1 : 0 ); }
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv1, 
+            std::experimental::basic_string_view<CharT> sv2, int expected ) {
+    assert ( sign( sv1.compare(sv2)) == sign(expected));
+}
+
+
+template<typename CharT>
+void test ( const CharT *s1, const CharT  *s2, int expected ) {
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    
+    string_view_t sv1 ( s1 );
+    string_view_t sv2 ( s2 );
+    test1(sv1, sv2, expected);
+}
+
+int main () {
+
+    test("",                     "", 0);
+    test("",                     "abcde", -5);
+    test("",                     "abcdefghij", -10);
+    test("",                     "abcdefghijklmnopqrst", -20);
+    test("abcde",                "", 5);
+    test("abcde",                "abcde", 0);
+    test("abcde",                "abcdefghij", -5);
+    test("abcde",                "abcdefghijklmnopqrst", -15);
+    test("abcdefghij",           "", 10);
+    test("abcdefghij",           "abcde", 5);
+    test("abcdefghij",           "abcdefghij", 0);
+    test("abcdefghij",           "abcdefghijklmnopqrst", -10);
+    test("abcdefghijklmnopqrst", "", 20);
+    test("abcdefghijklmnopqrst", "abcde", 15);
+    test("abcdefghijklmnopqrst", "abcdefghij", 10);
+    test("abcdefghijklmnopqrst", "abcdefghijklmnopqrst", 0);
+
+    test(L"",                     L"", 0);
+    test(L"",                     L"abcde", -5);
+    test(L"",                     L"abcdefghij", -10);
+    test(L"",                     L"abcdefghijklmnopqrst", -20);
+    test(L"abcde",                L"", 5);
+    test(L"abcde",                L"abcde", 0);
+    test(L"abcde",                L"abcdefghij", -5);
+    test(L"abcde",                L"abcdefghijklmnopqrst", -15);
+    test(L"abcdefghij",           L"", 10);
+    test(L"abcdefghij",           L"abcde", 5);
+    test(L"abcdefghij",           L"abcdefghij", 0);
+    test(L"abcdefghij",           L"abcdefghijklmnopqrst", -10);
+    test(L"abcdefghijklmnopqrst", L"", 20);
+    test(L"abcdefghijklmnopqrst", L"abcde", 15);
+    test(L"abcdefghijklmnopqrst", L"abcdefghij", 10);
+    test(L"abcdefghijklmnopqrst", L"abcdefghijklmnopqrst", 0);
+
+#if __cplusplus >= 201103L
+    test(u"",                     u"", 0);
+    test(u"",                     u"abcde", -5);
+    test(u"",                     u"abcdefghij", -10);
+    test(u"",                     u"abcdefghijklmnopqrst", -20);
+    test(u"abcde",                u"", 5);
+    test(u"abcde",                u"abcde", 0);
+    test(u"abcde",                u"abcdefghij", -5);
+    test(u"abcde",                u"abcdefghijklmnopqrst", -15);
+    test(u"abcdefghij",           u"", 10);
+    test(u"abcdefghij",           u"abcde", 5);
+    test(u"abcdefghij",           u"abcdefghij", 0);
+    test(u"abcdefghij",           u"abcdefghijklmnopqrst", -10);
+    test(u"abcdefghijklmnopqrst", u"", 20);
+    test(u"abcdefghijklmnopqrst", u"abcde", 15);
+    test(u"abcdefghijklmnopqrst", u"abcdefghij", 10);
+    test(u"abcdefghijklmnopqrst", u"abcdefghijklmnopqrst", 0);
+
+    test(U"",                     U"", 0);
+    test(U"",                     U"abcde", -5);
+    test(U"",                     U"abcdefghij", -10);
+    test(U"",                     U"abcdefghijklmnopqrst", -20);
+    test(U"abcde",                U"", 5);
+    test(U"abcde",                U"abcde", 0);
+    test(U"abcde",                U"abcdefghij", -5);
+    test(U"abcde",                U"abcdefghijklmnopqrst", -15);
+    test(U"abcdefghij",           U"", 10);
+    test(U"abcdefghij",           U"abcde", 5);
+    test(U"abcdefghij",           U"abcdefghij", 0);
+    test(U"abcdefghij",           U"abcdefghijklmnopqrst", -10);
+    test(U"abcdefghijklmnopqrst", U"", 20);
+    test(U"abcdefghijklmnopqrst", U"abcde", 15);
+    test(U"abcdefghijklmnopqrst", U"abcdefghij", 10);
+    test(U"abcdefghijklmnopqrst", U"abcdefghijklmnopqrst", 0);
+#endif
+    
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::experimental::basic_string_view<char, constexpr_char_traits<char>> SV;
+    constexpr SV  sv1 { "abcde", 5 };
+    constexpr SV  sv2 { "abcde", 5 };
+    constexpr SV  sv3 { "edcba0", 6 };
+    static_assert ( sv1.compare(sv2) == 0, "" );
+    static_assert ( sv2.compare(sv1) == 0, "" );
+    static_assert ( sv3.compare(sv2)  > 0, "" );
+    static_assert ( sv2.compare(sv3)  < 0, "" );
+    }
+#endif    
+}
diff --git a/test/experimental/string.view/string.view.ops/copy.pass.cpp b/test/experimental/string.view/string.view.ops/copy.pass.cpp
new file mode 100644
index 0000000..96246d2
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/copy.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// size_type copy(charT* s, size_type n, size_type pos = 0) const;
+
+// Throws: out_of_range if pos > size().
+// Remarks: Let rlen be the smaller of n and size() - pos.
+// Requires: [s, s+rlen) is a valid range.
+// Effects: Equivalent to std::copy_n(begin() + pos, rlen, s).
+// Returns: rlen.
+
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv, size_t n, size_t pos ) {
+    const size_t rlen = std::min ( n, sv.size() - pos );
+
+    CharT *dest1 = new CharT [rlen + 1];    dest1[rlen] = 0;
+    CharT *dest2 = new CharT [rlen + 1];    dest2[rlen] = 0;
+    
+    try {
+        sv.copy(dest1, n, pos);
+        std::copy_n(sv.begin() + pos, rlen, dest2);
+
+        for ( size_t i = 0; i <= rlen; ++i )
+            assert ( dest1[i] == dest2[i] );
+        }
+    catch ( const std::out_of_range & ) { assert ( pos > sv.size()); }
+    delete [] dest1;
+    delete [] dest2;    
+}
+
+
+template<typename CharT>
+void test ( const CharT *s ) {
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    
+    string_view_t sv1 ( s );
+
+    test1(sv1,  0, 0);
+    test1(sv1,  1, 0);
+    test1(sv1, 20, 0);
+    test1(sv1, sv1.size(), 0);
+    test1(sv1, 20, string_view_t::npos);
+    
+    test1(sv1,   0, 3);
+    test1(sv1,   2, 3);
+    test1(sv1, 100, 3);
+    test1(sv1, 100, string_view_t::npos);
+
+    test1(sv1, sv1.size(), string_view_t::npos);
+
+    test1(sv1, sv1.size() + 1, 0);
+    test1(sv1, sv1.size() + 1, 1);
+    test1(sv1, sv1.size() + 1, string_view_t::npos);
+
+}
+
+int main () {
+    test ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( "ABCDE");
+    test ( "a" );
+    test ( "" );
+
+    test ( L"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( L"ABCDE" );
+    test ( L"a" );
+    test ( L"" );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( u"ABCDE" );
+    test ( u"a" );
+    test ( u"" );
+
+    test ( U"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( U"ABCDE" );
+    test ( U"a" );
+    test ( U"" );
+#endif
+}
diff --git a/test/experimental/string.view/string.view.ops/substr.pass.cpp b/test/experimental/string.view/string.view.ops/substr.pass.cpp
new file mode 100644
index 0000000..2b134ea
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/substr.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+// constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
+
+// Throws: out_of_range if pos > size().
+// Effects: Determines the effective length rlen of the string to reference as the smaller of n and size() - pos.
+// Returns: basic_string_view(data()+pos, rlen).
+
+#include <experimental/string_view>
+#include <cassert>
+
+template<typename CharT>
+void test1 ( std::experimental::basic_string_view<CharT> sv, size_t n, size_t pos ) {
+    try {
+        std::experimental::basic_string_view<CharT> sv1 = sv.substr(pos, n);
+        const size_t rlen = std::min ( n, sv.size() - pos );
+        assert ( sv1.size() == rlen );
+        for ( size_t i = 0; i <= rlen; ++i )
+            assert ( sv[pos+i] == sv1[i] );
+        }
+    catch ( const std::out_of_range & ) { assert ( pos > sv.size()); }
+}
+
+
+template<typename CharT>
+void test ( const CharT *s ) {
+    typedef std::experimental::basic_string_view<CharT> string_view_t;
+    
+    string_view_t sv1 ( s );
+
+    test1(sv1,  0, 0);
+    test1(sv1,  1, 0);
+    test1(sv1, 20, 0);
+    test1(sv1, sv1.size(), 0);
+    
+    test1(sv1,   0, 3);
+    test1(sv1,   2, 3);
+    test1(sv1, 100, 3);
+
+    test1(sv1, 0, string_view_t::npos);
+    test1(sv1, 2, string_view_t::npos);
+    test1(sv1, sv1.size(), string_view_t::npos);
+
+    test1(sv1, sv1.size() + 1, 0);
+    test1(sv1, sv1.size() + 1, 1);
+    test1(sv1, sv1.size() + 1, string_view_t::npos);
+}
+
+int main () {
+    test ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( "ABCDE");
+    test ( "a" );
+    test ( "" );
+
+    test ( L"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( L"ABCDE" );
+    test ( L"a" );
+    test ( L"" );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( u"ABCDE" );
+    test ( u"a" );
+    test ( u"" );
+
+    test ( U"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( U"ABCDE" );
+    test ( U"a" );
+    test ( U"" );
+#endif
+    
+#if _LIBCPP_STD_VER > 11
+    {
+    constexpr std::experimental::string_view sv1 { "ABCDE", 5 };
+
+    {
+    constexpr std::experimental::string_view sv2 = sv1.substr ( 0, 3 );
+    static_assert ( sv2.size() == 3, "" );
+    static_assert ( sv2[0] == 'A', "" );
+    static_assert ( sv2[1] == 'B', "" );
+    static_assert ( sv2[2] == 'C', "" );
+    }
+    
+    {
+    constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 0 );
+    static_assert ( sv2.size() == 0, "" );
+    }
+
+    {
+    constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 3 );
+    static_assert ( sv2.size() == 2, "" );
+    static_assert ( sv2[0] == 'D', "" );
+    static_assert ( sv2[1] == 'E', "" );
+    }
+    }
+#endif
+}
\ No newline at end of file
diff --git a/test/experimental/string.view/string.view.ops/to_string.pass.cpp b/test/experimental/string.view/string.view.ops/to_string.pass.cpp
new file mode 100644
index 0000000..6387ac2
--- /dev/null
+++ b/test/experimental/string.view/string.view.ops/to_string.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// <string_view>
+
+//  template<class Allocator>
+//  explicit operator basic_string<_CharT, _Traits, Allocator> () const;
+//  template<class _CharT, class _Traits = char_traits<_CharT>, class Allocator = allocator<_CharT> >
+//  basic_string<_CharT, _Traits, Allocator> to_string (
+//          basic_string_view<_CharT, _Traits> _sv, const Allocator& _a = Allocator()) const;
+
+#include <experimental/string_view>
+#include <cassert>
+#include "min_allocator.h"
+
+template<typename CharT>
+void test ( const CharT *s ) {
+    typedef std::basic_string<CharT> String ;
+    {
+    const std::experimental::basic_string_view<CharT> sv1 ( s );
+    String                                            str1 = (String) sv1;
+    
+    assert ( sv1.size() == str1.size ());
+    assert ( std::char_traits<CharT>::compare ( sv1.data(), str1.data(),  sv1.size()) == 0 );
+
+#if __cplusplus >= 201103L
+    auto str2 = sv1.to_string(min_allocator<CharT>());
+    assert ( sv1.size() == str2.size ());
+    assert ( std::char_traits<CharT>::compare ( sv1.data(), str2.data(), sv1.size()) == 0 );
+#endif
+    }
+
+    {
+    const std::experimental::basic_string_view<CharT> sv1;
+    String                                            str1 = (String) sv1;
+
+    assert ( sv1.size() == str1.size ());
+    assert ( std::char_traits<CharT>::compare ( sv1.data(), str1.data(), sv1.size()) == 0 );
+
+#if __cplusplus >= 201103L
+    auto str2 = sv1.to_string(min_allocator<CharT>());
+    assert ( sv1.size() == str2.size ());
+    assert ( std::char_traits<CharT>::compare ( sv1.data(), str2.data(), sv1.size()) == 0 );
+#endif
+    }
+}
+
+int main () {
+    test ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( "ABCDE");
+    test ( "a" );
+    test ( "" );
+
+    test ( L"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( L"ABCDE" );
+    test ( L"a" );
+    test ( L"" );
+
+#if __cplusplus >= 201103L
+    test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( u"ABCDE" );
+    test ( u"a" );
+    test ( u"" );
+
+    test ( U"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" );
+    test ( U"ABCDE" );
+    test ( U"a" );
+    test ( U"" );
+#endif
+}
diff --git a/test/experimental/string.view/string.view.synop/nothing_to_do.pass.cpp b/test/experimental/string.view/string.view.synop/nothing_to_do.pass.cpp
new file mode 100644
index 0000000..c21f8a7
--- /dev/null
+++ b/test/experimental/string.view/string.view.synop/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <experimental/string_view>
+
+int main () {}
diff --git a/test/experimental/string.view/string.view.template/nothing_to_do.pass.cpp b/test/experimental/string.view/string.view.template/nothing_to_do.pass.cpp
new file mode 100644
index 0000000..c21f8a7
--- /dev/null
+++ b/test/experimental/string.view/string.view.template/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <experimental/string_view>
+
+int main () {}
diff --git a/test/experimental/utilities/nothing_to_do.pass.cpp b/test/experimental/utilities/nothing_to_do.pass.cpp
new file mode 100644
index 0000000..9a59227
--- /dev/null
+++ b/test/experimental/utilities/nothing_to_do.pass.cpp
@@ -0,0 +1,13 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/experimental/utilities/utility/utility.erased.type/erased_type.pass.cpp b/test/experimental/utilities/utility/utility.erased.type/erased_type.pass.cpp
new file mode 100644
index 0000000..3e38d5e
--- /dev/null
+++ b/test/experimental/utilities/utility/utility.erased.type/erased_type.pass.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/utility>
+
+#include <experimental/utility>
+
+int main()
+{
+    std::experimental::erased_type e();
+}
diff --git a/test/experimental/utilities/utility/utility.synop/includes.pass.cpp b/test/experimental/utilities/utility/utility.synop/includes.pass.cpp
new file mode 100644
index 0000000..2583d43
--- /dev/null
+++ b/test/experimental/utilities/utility/utility.synop/includes.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/utility>
+
+#include <experimental/utility>
+
+#ifndef _LIBCPP_UTILITY
+#   error "<experimental/utility> must include <utility>"
+#endif
+
+int main()
+{
+}
diff --git a/test/experimental/utilities/utility/version.pass.cpp b/test/experimental/utilities/utility/version.pass.cpp
new file mode 100644
index 0000000..4377124
--- /dev/null
+++ b/test/experimental/utilities/utility/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <experimental/utility>
+
+#include <experimental/utility>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/input.output/iostream.format/ext.manip/get_money.pass.cpp b/test/input.output/iostream.format/ext.manip/get_money.pass.cpp
index 0719df9..1ea1d78 100644
--- a/test/input.output/iostream.format/ext.manip/get_money.pass.cpp
+++ b/test/input.output/iostream.format/ext.manip/get_money.pass.cpp
@@ -7,13 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <iomanip>
 
 // template <class moneyT> T7 get_money(moneyT& mon, bool intl = false);
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <iomanip>
 #include <cassert>
 
diff --git a/test/input.output/iostream.format/ext.manip/put_money.pass.cpp b/test/input.output/iostream.format/ext.manip/put_money.pass.cpp
index 885bf6a..a00cf13 100644
--- a/test/input.output/iostream.format/ext.manip/put_money.pass.cpp
+++ b/test/input.output/iostream.format/ext.manip/put_money.pass.cpp
@@ -7,13 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <iomanip>
 
 // template <class charT, class moneyT> T8 put_money(const moneyT& mon, bool intl = false);
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <iomanip>
 #include <cassert>
 
diff --git a/test/input.output/string.streams/istringstream/istringstream.assign/move.pass.cpp b/test/input.output/string.streams/istringstream/istringstream.assign/move.pass.cpp
index 6e20640..e57ad55 100644
--- a/test/input.output/string.streams/istringstream/istringstream.assign/move.pass.cpp
+++ b/test/input.output/string.streams/istringstream/istringstream.assign/move.pass.cpp
@@ -34,6 +34,24 @@
         assert(i == 456);
     }
     {
+        std::istringstream s1("Aaaaa Bbbbb Cccccccccc Dddddddddddddddddd");
+        std::string s;
+        s1 >> s;
+
+        std::istringstream s2 = std::move(s1);
+        s2 >> s;
+        assert(s == "Bbbbb");
+
+        std::istringstream s3;
+        s3 = std::move(s2);
+        s3 >> s;
+        assert(s == "Cccccccccc");
+
+        s1 = std::move(s3);
+        s1 >> s;
+        assert(s == "Dddddddddddddddddd");
+    }
+    {
         std::wistringstream ss0(L" 123 456");
         std::wistringstream ss;
         ss = std::move(ss0);
@@ -46,5 +64,23 @@
         ss >> i;
         assert(i == 456);
     }
+    {
+        std::wistringstream s1(L"Aaaaa Bbbbb Cccccccccc Dddddddddddddddddd");
+        std::wstring s;
+        s1 >> s;
+
+        std::wistringstream s2 = std::move(s1);
+        s2 >> s;
+        assert(s == L"Bbbbb");
+
+        std::wistringstream s3;
+        s3 = std::move(s2);
+        s3 >> s;
+        assert(s == L"Cccccccccc");
+
+        s1 = std::move(s3);
+        s1 >> s;
+        assert(s == L"Dddddddddddddddddd");
+    }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/iterators/iterator.container/data.pass.cpp b/test/iterators/iterator.container/data.pass.cpp
new file mode 100644
index 0000000..75ba950
--- /dev/null
+++ b/test/iterators/iterator.container/data.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <iterator>
+// template <class C> constexpr auto data(C& c) -> decltype(c.data());               // C++17
+// template <class C> constexpr auto data(const C& c) -> decltype(c.data());         // C++17
+// template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;           // C++17
+// template <class E> constexpr const E* data(initializer_list<E> il) noexcept;      // C++17
+
+#if __cplusplus <= 201402L
+int main () {}
+#else
+
+
+#include <__config>
+
+#include <iterator>
+#include <cassert>
+#include <vector>
+#include <array>
+#include <initializer_list>
+
+template<typename C>
+void test_const_container( const C& c )
+{
+    assert ( std::data(c)   == c.data());
+}
+
+template<typename T>
+void test_const_container( const std::initializer_list<T>& c )
+{
+    assert ( std::data(c)   == c.begin());
+}
+
+template<typename C>
+void test_container( C& c )
+{
+    assert ( std::data(c)   == c.data());
+}
+    
+template<typename T>
+void test_container( std::initializer_list<T>& c)
+{
+    assert ( std::data(c)   == c.begin());
+}
+
+template<typename T, size_t Sz>
+void test_const_array( const T (&array)[Sz] )
+{
+    assert ( std::data(array) == &array[0]);
+}
+
+int main()
+{
+    std::vector<int> v; v.push_back(1);
+    std::array<int, 1> a; a[0] = 3;
+    std::initializer_list<int> il = { 4 };
+    
+    test_container ( v );
+    test_container ( a );
+    test_container ( il );
+
+    test_const_container ( v );
+    test_const_container ( a );
+    test_const_container ( il );
+    
+    static constexpr int arrA [] { 1, 2, 3 };
+    test_const_array ( arrA );
+}
+
+#endif
diff --git a/test/iterators/iterator.container/empty.pass.cpp b/test/iterators/iterator.container/empty.pass.cpp
new file mode 100644
index 0000000..196a0e3
--- /dev/null
+++ b/test/iterators/iterator.container/empty.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <iterator>
+// template <class C> constexpr auto empty(const C& c) -> decltype(c.empty());       // C++17
+// template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept;  // C++17
+// template <class E> constexpr bool empty(initializer_list<E> il) noexcept;         // C++17
+
+#if __cplusplus <= 201402L
+int main () {}
+#else
+
+
+#include <__config>
+
+#include <iterator>
+#include <cassert>
+#include <vector>
+#include <array>
+#include <list>
+#include <initializer_list>
+
+template<typename C>
+void test_const_container( const C& c )
+{
+    assert ( std::empty(c)   == c.empty());
+}
+
+template<typename T>
+void test_const_container( const std::initializer_list<T>& c )
+{
+    assert ( std::empty(c)   == (c.size() == 0));
+}
+
+template<typename C>
+void test_container( C& c )
+{
+    assert ( std::empty(c)   == c.empty());
+}
+    
+template<typename T>
+void test_container( std::initializer_list<T>& c )
+{
+    assert ( std::empty(c)   == (c.size() == 0));
+}
+
+template<typename T, size_t Sz>
+void test_const_array( const T (&array)[Sz] )
+{
+    assert (!std::empty(array));
+}
+
+int main()
+{
+    std::vector<int> v; v.push_back(1);
+    std::list<int>   l; l.push_back(2);
+    std::array<int, 1> a; a[0] = 3;
+    std::initializer_list<int> il = { 4 };
+    
+    test_container ( v );
+    test_container ( l );
+    test_container ( a );
+    test_container ( il );
+
+    test_const_container ( v );
+    test_const_container ( l );
+    test_const_container ( a );
+    test_const_container ( il );
+    
+    static constexpr int arrA [] { 1, 2, 3 };
+    test_const_array ( arrA );
+}
+
+#endif
diff --git a/test/iterators/iterator.container/size.pass.cpp b/test/iterators/iterator.container/size.pass.cpp
new file mode 100644
index 0000000..f8da9bf
--- /dev/null
+++ b/test/iterators/iterator.container/size.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <iterator>
+// template <class C> constexpr auto size(const C& c) -> decltype(c.size());         // C++17
+// template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; // C++17
+
+#if __cplusplus <= 201402L
+int main () {}
+#else
+
+
+#include <__config>
+
+#include <iterator>
+#include <cassert>
+#include <vector>
+#include <array>
+#include <list>
+#include <initializer_list>
+
+template<typename C>
+void test_const_container( const C& c )
+{
+    assert ( std::size(c)   == c.size());
+}
+
+template<typename T>
+void test_const_container( const std::initializer_list<T>& c)
+{
+    assert ( std::size(c)   == c.size());
+}
+
+template<typename C>
+void test_container( C& c)
+{
+    assert ( std::size(c)   == c.size());
+}
+    
+template<typename T>
+void test_container( std::initializer_list<T>& c )
+{
+    assert ( std::size(c)   == c.size());
+}
+
+template<typename T, size_t Sz>
+void test_const_array( const T (&array)[Sz] )
+{
+    assert ( std::size(array) == Sz );
+}
+
+int main()
+{
+    std::vector<int> v; v.push_back(1);
+    std::list<int>   l; l.push_back(2);
+    std::array<int, 1> a; a[0] = 3;
+    std::initializer_list<int> il = { 4 };
+    
+    test_container ( v );
+    test_container ( l );
+    test_container ( a );
+    test_container ( il );
+
+    test_const_container ( v );
+    test_const_container ( l );
+    test_const_container ( a );
+    test_const_container ( il );
+    
+    static constexpr int arrA [] { 1, 2, 3 };
+    test_const_array ( arrA );
+}
+
+#endif
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
index 63f847f..052d88f 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
@@ -7,7 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new[]
+// test operator new[]
+// NOTE: asan and msan will not call the new handler.
+// UNSUPPORTED: asan, msan
+
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
index 60bc7c4..259f5b0 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
@@ -7,7 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new [] (nothrow)
+// test operator new [] (nothrow)
+// NOTE: asan and msan will not call the new handler.
+// UNSUPPORTED: asan, msan
+
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
index 9bf6e8a..3e3a00c 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new [] nothrow by replacing only operator new
+// test operator new [] nothrow by replacing only operator new
+
+// UNSUPPORTED: asan, msan
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
index 959bc45..acf972b 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new[] replacement by replacing only operator new
+// test operator new[] replacement by replacing only operator new
+
+// UNSUPPORTED: asan, msan
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
index 4d219e3..3ba71dd 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
@@ -7,7 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new
+// test operator new
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: asan, msan
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
index c54d14e..c76bfa0 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
@@ -7,7 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new (nothrow)
+// test operator new (nothrow)
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: asan, msan
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
index ed3c035..f2dbb98 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new nothrow by replacing only operator new
+// test operator new nothrow by replacing only operator new
+
+// UNSUPPORTED: asan, msan
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp b/test/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
index 7646097..2d411b9 100644
--- a/test/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
+++ b/test/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
@@ -7,7 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
- // test operator new replacement
+// test operator new replacement
+
+// UNSUPPORTED: asan, msan
 
 #include <new>
 #include <cstddef>
diff --git a/test/language.support/support.runtime/csetjmp.pass.cpp b/test/language.support/support.runtime/csetjmp.pass.cpp
index a54f67b..dc034ce 100644
--- a/test/language.support/support.runtime/csetjmp.pass.cpp
+++ b/test/language.support/support.runtime/csetjmp.pass.cpp
@@ -19,6 +19,6 @@
 int main()
 {
     std::jmp_buf jb;
-    static_assert((std::is_same<__typeof__(std::longjmp(jb, 0)), void>::value),
-                  "std::is_same<__typeof__(std::longjmp(jb, 0)), void>::value");
+    static_assert((std::is_same<decltype(std::longjmp(jb, 0)), void>::value),
+                  "std::is_same<decltype(std::longjmp(jb, 0)), void>::value");
 }
diff --git a/test/language.support/support.runtime/cstdarg.pass.cpp b/test/language.support/support.runtime/cstdarg.pass.cpp
index 00baf80..059ad2f 100644
--- a/test/language.support/support.runtime/cstdarg.pass.cpp
+++ b/test/language.support/support.runtime/cstdarg.pass.cpp
@@ -15,8 +15,10 @@
 #error va_arg not defined
 #endif
 
-#ifndef va_copy
-#error va_copy not defined
+#if __cplusplus >= 201103L
+#  ifndef va_copy
+#    error va_copy is not defined when c++ >= 11
+#  endif
 #endif
 
 #ifndef va_end
diff --git a/test/language.support/support.start.term/quick_exit.pass.cpp b/test/language.support/support.start.term/quick_exit.pass.cpp
index 1945a1b..bcfdbb7 100644
--- a/test/language.support/support.start.term/quick_exit.pass.cpp
+++ b/test/language.support/support.start.term/quick_exit.pass.cpp
@@ -7,17 +7,17 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// XFAIL: apple-darwin
 
 // test quick_exit and at_quick_exit
 
 #include <cstdlib>
-#include <type_traits>
 
 void f() {}
 
 int main()
 {
+#ifdef _LIBCPP_HAS_QUICK_EXIT
     std::at_quick_exit(f);
-    quick_exit(0);
+    std::quick_exit(0);
+#endif
 }
diff --git a/test/language.support/support.start.term/quick_exit_check1.fail.cpp b/test/language.support/support.start.term/quick_exit_check1.fail.cpp
new file mode 100644
index 0000000..8b97293
--- /dev/null
+++ b/test/language.support/support.start.term/quick_exit_check1.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+// test that referencing at_quick_exit when _LIBCPP_HAS_QUICK_EXIT is not defined
+// results in a compile error.
+
+#include <cstdlib>
+
+void f() {}
+
+int main()
+{
+#ifndef _LIBCPP_HAS_QUICK_EXIT
+    std::at_quick_exit(f);
+#else
+#error
+#endif
+}
diff --git a/test/language.support/support.start.term/quick_exit_check2.fail.cpp b/test/language.support/support.start.term/quick_exit_check2.fail.cpp
new file mode 100644
index 0000000..3959141
--- /dev/null
+++ b/test/language.support/support.start.term/quick_exit_check2.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+// test that referencing quick_exit when _LIBCPP_HAS_QUICK_EXIT is not defined
+// results in a compile error.
+
+#include <cstdlib>
+
+void f() {}
+
+int main()
+{
+#ifndef _LIBCPP_HAS_QUICK_EXIT
+    std::quick_exit(0);
+#else
+#error
+#endif
+}
diff --git a/test/language.support/support.types/nullptr_t.pass.cpp b/test/language.support/support.types/nullptr_t.pass.cpp
index 6c15fef..4d7c8b0 100644
--- a/test/language.support/support.types/nullptr_t.pass.cpp
+++ b/test/language.support/support.types/nullptr_t.pass.cpp
@@ -18,42 +18,62 @@
     A(std::nullptr_t) {}
 };
 
+template <class T>
+void test_conversions()
+{
+    {
+        T p = 0;
+        assert(p == nullptr);
+    }
+    {
+        T p = nullptr;
+        assert(p == nullptr);
+        assert(nullptr == p);
+        assert(!(p != nullptr));
+        assert(!(nullptr != p));
+    }
+}
+
+template <class T>
+void test_comparisons()
+{
+    T p = nullptr;
+    assert(p == nullptr);
+    assert(p <= nullptr);
+    assert(p >= nullptr);
+    assert(!(p != nullptr));
+    assert(!(p < nullptr));
+    assert(!(p > nullptr));
+    assert(nullptr == p);
+    assert(nullptr <= p);
+    assert(nullptr >= p);
+    assert(!(nullptr != p));
+    assert(!(nullptr < p));
+    assert(!(nullptr > p));
+}
+
+
 int main()
 {
     static_assert(sizeof(std::nullptr_t) == sizeof(void*),
                   "sizeof(std::nullptr_t) == sizeof(void*)");
-    A* p = 0;
-    assert(p == nullptr);
-    void (A::*pmf)() = 0;
-#ifdef __clang__
-    // GCC 4.2 can't handle this
-    assert(pmf == nullptr);
-#endif
-    int A::*pmd = 0;
-    assert(pmd == nullptr);
-    A a1(nullptr);
-    A a2(0);
-    bool b = nullptr;
-    assert(!b);
-    assert(nullptr == nullptr);
-    assert(nullptr <= nullptr);
-    assert(nullptr >= nullptr);
-    assert(!(nullptr != nullptr));
-    assert(!(nullptr < nullptr));
-    assert(!(nullptr > nullptr));
-    A* a = nullptr;
-    assert(a == nullptr);
-    assert(a <= nullptr);
-    assert(a >= nullptr);
-    assert(!(a != nullptr));
-    assert(!(a < nullptr));
-    assert(!(a > nullptr));
-    assert(nullptr == a);
-    assert(nullptr <= a);
-    assert(nullptr >= a);
-    assert(!(nullptr != a));
-    assert(!(nullptr < a));
-    assert(!(nullptr > a));
-    std::ptrdiff_t i = reinterpret_cast<std::ptrdiff_t>(nullptr);
-    assert(i == 0);
+
+    {
+        test_conversions<std::nullptr_t>();
+        test_conversions<void*>();
+        test_conversions<A*>();
+        test_conversions<void(*)()>();
+        test_conversions<void(A::*)()>();
+        test_conversions<int A::*>();
+    }
+    {
+        test_comparisons<std::nullptr_t>();
+        test_comparisons<void*>();
+        test_comparisons<A*>();
+        test_comparisons<void(*)()>();
+    }
+    {
+        bool b = nullptr;
+        assert(!b);
+    }
 }
diff --git a/test/language.support/support.types/nullptr_t_integral_cast.fail.cpp b/test/language.support/support.types/nullptr_t_integral_cast.fail.cpp
new file mode 100644
index 0000000..92bd879
--- /dev/null
+++ b/test/language.support/support.types/nullptr_t_integral_cast.fail.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// typedef decltype(nullptr) nullptr_t;
+
+#include <cstddef>
+
+int main()
+{
+    std::ptrdiff_t i = static_cast<std::ptrdiff_t>(nullptr);
+}
diff --git a/test/language.support/support.types/nullptr_t_integral_cast.pass.cpp b/test/language.support/support.types/nullptr_t_integral_cast.pass.cpp
new file mode 100644
index 0000000..34c7a93
--- /dev/null
+++ b/test/language.support/support.types/nullptr_t_integral_cast.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: nullptr_t emulation cannot handle a reinterpret_cast to an
+// integral type
+// XFAIL: c++98, c++03
+
+// typedef decltype(nullptr) nullptr_t;
+
+
+#include <cstddef>
+#include <cassert>
+
+int main()
+{
+    std::ptrdiff_t i = reinterpret_cast<std::ptrdiff_t>(nullptr);
+    assert(i == 0);
+}
diff --git a/test/localization/c.locales/clocale.pass.cpp b/test/localization/c.locales/clocale.pass.cpp
index 8774865..3b3e933 100644
--- a/test/localization/c.locales/clocale.pass.cpp
+++ b/test/localization/c.locales/clocale.pass.cpp
@@ -43,6 +43,6 @@
 int main()
 {
     std::lconv lc;
-    static_assert((std::is_same<__typeof__(std::setlocale(0, "")), char*>::value), "");
-    static_assert((std::is_same<__typeof__(std::localeconv()), std::lconv*>::value), "");
+    static_assert((std::is_same<decltype(std::setlocale(0, "")), char*>::value), "");
+    static_assert((std::is_same<decltype(std::localeconv()), std::lconv*>::value), "");
 }
diff --git a/test/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp b/test/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp
index d644125..69af9ac 100644
--- a/test/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp
+++ b/test/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp
@@ -18,6 +18,11 @@
 //     has any difference from "C" collation.  But I do believe I'm picking
 //     up the OS's collation files.
 
+// TODO investigation needed.
+// Glibc seems to collate files differently from the way Apple's C library does
+// it.
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <string>
 #include <cassert>
diff --git a/test/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp b/test/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp
index 11ad5d4..8971412 100644
--- a/test/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp
+++ b/test/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp
@@ -7,15 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // template <class charT> class collate_byname
 
 // string_type transform(const charT* low, const charT* high) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <string>
 #include <cassert>
diff --git a/test/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp b/test/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
index 6d9e1cd..f7c957b 100644
--- a/test/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
+++ b/test/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp
@@ -13,6 +13,8 @@
 
 // ~ctype();
 
+// UNSUPPORTED: asan, msan
+
 #include <locale>
 #include <cassert>
 #include <new>
diff --git a/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_1.pass.cpp b/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_1.pass.cpp
index 91da9f7..509e52a 100644
--- a/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_1.pass.cpp
+++ b/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_1.pass.cpp
@@ -7,16 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Bionic's wchar_t ctype functions are only valid for the ASCII range.
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // template <class charT> class ctype_byname;
 
 // bool is(mask m, charT c) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <type_traits>
 #include <cassert>
diff --git a/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_many.pass.cpp b/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_many.pass.cpp
index cc64719..a993466 100644
--- a/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_many.pass.cpp
+++ b/test/localization/locale.categories/category.ctype/locale.ctype.byname/is_many.pass.cpp
@@ -7,16 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Bionic's wchar_t ctype functions are only valid for the ASCII range.
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // template <class charT> class ctype_byname;
 
 // const charT* do_is(const charT* low, const charT* high, mask* vec) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <string>
 #include <vector>
diff --git a/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_is.pass.cpp b/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_is.pass.cpp
index 5a26dc6..25b2c3e 100644
--- a/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_is.pass.cpp
+++ b/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_is.pass.cpp
@@ -7,16 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Bionic's wchar_t ctype functions are only valid for the ASCII range.
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // template <class charT> class ctype_byname;
 
 // const charT* scan_is(mask m, const charT* low, const charT* high) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <string>
 #include <vector>
diff --git a/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_not.pass.cpp b/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_not.pass.cpp
index bc07fcf..270ae1f 100644
--- a/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_not.pass.cpp
+++ b/test/localization/locale.categories/category.ctype/locale.ctype.byname/scan_not.pass.cpp
@@ -7,16 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Bionic's wchar_t ctype functions are only valid for the ASCII range.
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // template <class charT> class ctype_byname;
 
 // const charT* scan_not(mask m, const charT* low, const charT* high) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <string>
 #include <vector>
diff --git a/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_en_US.pass.cpp b/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_en_US.pass.cpp
index d780fb5..0f034fa 100644
--- a/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_en_US.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_en_US.pass.cpp
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // class money_get<charT, InputIterator>
@@ -17,6 +14,8 @@
 // iter_type get(iter_type b, iter_type e, bool intl, ios_base& iob,
 //               ios_base::iostate& err, long double& v) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <ios>
 #include <streambuf>
diff --git a/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp b/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
index 374443a..07a33f7 100644
--- a/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp
@@ -16,6 +16,9 @@
 // iter_type get(iter_type b, iter_type e, bool intl, ios_base& iob,
 //               ios_base::iostate& err, long double& v) const;
 
+// TODO For zh_CN GLIBC puts the negative sign after the currency symbol.
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <ios>
 #include <streambuf>
diff --git a/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_string_en_US.pass.cpp b/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_string_en_US.pass.cpp
index fabdeb8..b9099f4 100644
--- a/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_string_en_US.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_string_en_US.pass.cpp
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // class money_get<charT, InputIterator>
@@ -17,6 +14,8 @@
 // iter_type get(iter_type b, iter_type e, bool intl, ios_base& iob,
 //               ios_base::iostate& err, string_type& v) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <ios>
 #include <streambuf>
diff --git a/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_en_US.pass.cpp b/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_en_US.pass.cpp
index 59ea0e1..db193ea 100644
--- a/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_en_US.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_en_US.pass.cpp
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // class money_put<charT, OutputIterator>
@@ -17,6 +14,8 @@
 // iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
 //               long double units) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <ios>
 #include <streambuf>
diff --git a/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp b/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
index 242701e..633e188 100644
--- a/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp
@@ -16,6 +16,9 @@
 // iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
 //               long double units) const;
 
+// TODO For zh_CN GLIBC puts the negative sign after the currency symbol.
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <ios>
 #include <streambuf>
diff --git a/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_string_en_US.pass.cpp b/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_string_en_US.pass.cpp
index 9af0ac8..659f948 100644
--- a/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_string_en_US.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_string_en_US.pass.cpp
@@ -7,9 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <locale>
 
 // class money_put<charT, OutputIterator>
@@ -17,6 +14,8 @@
 // iter_type put(iter_type s, bool intl, ios_base& f, char_type fill,
 //               const string_type& units) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 #include <locale>
 #include <ios>
 #include <streambuf>
diff --git a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp
index 6db1f56..8270377 100644
--- a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/decimal_point.pass.cpp
@@ -6,7 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.fr_FR.UTF-8
@@ -18,11 +17,6 @@
 
 // <locale>
 
-// REQUIRES: locale.en_US.UTF-8
-// REQUIRES: locale.fr_FR.UTF-8
-// REQUIRES: locale.ru_RU.UTF-8
-// REQUIRES: locale.zh_CN.UTF-8
-
 // class moneypunct_byname<charT, International>
 
 // charT decimal_point() const;
diff --git a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/frac_digits.pass.cpp b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/frac_digits.pass.cpp
index 4967914..724dc1e 100644
--- a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/frac_digits.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/frac_digits.pass.cpp
@@ -6,7 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
 
 // <locale>
 
diff --git a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/negative_sign.pass.cpp b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/negative_sign.pass.cpp
index 45c58ef..66c8c64 100644
--- a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/negative_sign.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/negative_sign.pass.cpp
@@ -6,7 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/positive_sign.pass.cpp b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/positive_sign.pass.cpp
index dadf0da..04cd173 100644
--- a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/positive_sign.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/positive_sign.pass.cpp
@@ -6,7 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
index 640b7cb..a878283 100644
--- a/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
+++ b/test/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp
@@ -6,7 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.fr_FR.UTF-8
@@ -19,6 +18,12 @@
 
 // charT thousands_sep() const;
 
+// Failure related to GLIBC's use of U00A0 as mon_thousands_sep
+// and U002E as mon_decimal_point.
+// TODO: U00A0 should be investigated.
+// Possibly related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16006
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <limits>
 #include <cassert>
diff --git a/test/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp b/test/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp
index 2010dca..9359612 100644
--- a/test/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp
+++ b/test/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.pass.cpp
@@ -13,6 +13,9 @@
 
 // iter_type put(iter_type s, ios_base& iob, char_type fill, long double v) const;
 
+// TODO GLIBC uses a different string for positive and negative NAN numbers.
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <ios>
 #include <cassert>
diff --git a/test/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp b/test/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
index 536859e..72b6327 100644
--- a/test/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
+++ b/test/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp
@@ -19,6 +19,9 @@
 // iter_type get(iter_type s, iter_type end, ios_base& f,
 //               ios_base::iostate& err, tm *t, char format, char modifier = 0) const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 #include "test_iterators.h"
diff --git a/test/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp b/test/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
index 36c8a8e..ae8bce2 100644
--- a/test/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
+++ b/test/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp
@@ -19,6 +19,9 @@
 // iter_type get(iter_type s, iter_type end, ios_base& f,
 //               ios_base::iostate& err, tm *t, char format, char modifier = 0) const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 #include "test_iterators.h"
diff --git a/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday.pass.cpp b/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday.pass.cpp
index db070be..09055ad 100644
--- a/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday.pass.cpp
+++ b/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday.pass.cpp
@@ -20,6 +20,9 @@
 // get_weekday(iter_type s, iter_type end, ios_base& str,
 //             ios_base::iostate& err, tm* t) const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 #include "test_iterators.h"
diff --git a/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday_wide.pass.cpp b/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday_wide.pass.cpp
index ac607ba..31135a3 100644
--- a/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday_wide.pass.cpp
+++ b/test/localization/locale.categories/category.time/locale.time.get.byname/get_weekday_wide.pass.cpp
@@ -20,6 +20,9 @@
 // get_weekday(iter_type s, iter_type end, ios_base& str,
 //             ios_base::iostate& err, tm* t) const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 #include "test_iterators.h"
diff --git a/test/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp b/test/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
index ff3bb82..3e7538d 100644
--- a/test/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
+++ b/test/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp
@@ -24,6 +24,9 @@
 //     ~time_put_byname();
 // };
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 #include "test_iterators.h"
diff --git a/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp b/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
index 577655f..427d7c5 100644
--- a/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
+++ b/test/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
@@ -14,6 +14,9 @@
 // iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
 //               char format, char modifier = 0) const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 #include "test_iterators.h"
diff --git a/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/decimal_point.pass.cpp b/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/decimal_point.pass.cpp
index b1f225c..0617cdc 100644
--- a/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/decimal_point.pass.cpp
+++ b/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/decimal_point.pass.cpp
@@ -6,10 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-
-// REQUIRES: locale.en_US.UTF-8
-// REQUIRES: locale.fr_FR.UTF-8
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.fr_FR.UTF-8
diff --git a/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp b/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
index b1da92d..d5112a9 100644
--- a/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
+++ b/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/grouping.pass.cpp
@@ -6,7 +6,6 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.fr_FR.UTF-8
@@ -17,6 +16,9 @@
 
 // string grouping() const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 
diff --git a/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp b/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
index 80b440a..b1bd03f 100644
--- a/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
+++ b/test/localization/locale.categories/facet.numpunct/locale.numpunct.byname/thousands_sep.pass.cpp
@@ -16,6 +16,9 @@
 
 // char_type thousands_sep() const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <locale>
 #include <cassert>
 
diff --git a/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp b/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp
index 0569e4d..7e38021 100644
--- a/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp
+++ b/test/localization/locale.stdcvt/codecvt_utf16.pass.cpp
@@ -17,6 +17,8 @@
 //     // unspecified
 // };
 
+// UNSUPPORTED: asan, msan
+
 // Not a portable test
 
 #include <codecvt>
diff --git a/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp b/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp
index 4232f59..cc06e95 100644
--- a/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp
+++ b/test/localization/locale.stdcvt/codecvt_utf8.pass.cpp
@@ -17,6 +17,8 @@
 //     // unspecified
 // };
 
+// UNSUPPORTED: asan, msan
+
 // Not a portable test
 
 #include <codecvt>
diff --git a/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp b/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
index 6935c3e..3649f15 100644
--- a/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
+++ b/test/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
@@ -14,6 +14,8 @@
 // wbuffer_convert(streambuf *bytebuf = 0, Codecvt *pcvt = new Codecvt,
 //                 state_type state = state_type());
 
+// UNSUPPORTED: asan, msan
+
 #include <locale>
 #include <codecvt>
 #include <sstream>
diff --git a/test/localization/locales/locale/locale.cons/assign.pass.cpp b/test/localization/locales/locale/locale.cons/assign.pass.cpp
index 4aca354..75ce9b5 100644
--- a/test/localization/locales/locale/locale.cons/assign.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/assign.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 // REQUIRES: locale.ru_RU.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.cons/char_pointer.pass.cpp b/test/localization/locales/locale/locale.cons/char_pointer.pass.cpp
index 8b4509b..01857a4 100644
--- a/test/localization/locales/locale/locale.cons/char_pointer.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/char_pointer.pass.cpp
@@ -9,6 +9,7 @@
 
 // REQUIRES: locale.ru_RU.UTF-8
 // REQUIRES: locale.zh_CN.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.cons/copy.pass.cpp b/test/localization/locales/locale/locale.cons/copy.pass.cpp
index 7dd7cf4..629c9e6 100644
--- a/test/localization/locales/locale/locale.cons/copy.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/copy.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 // REQUIRES: locale.fr_FR.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.cons/default.pass.cpp b/test/localization/locales/locale/locale.cons/default.pass.cpp
index 0d46a76..25db9bb 100644
--- a/test/localization/locales/locale/locale.cons/default.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/default.pass.cpp
@@ -11,6 +11,8 @@
 
 // locale() throw();
 
+// UNSUPPORTED: asan, msan
+
 #include <locale>
 #include <new>
 #include <cassert>
diff --git a/test/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp b/test/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
index 6bd1f63..eaadbb9 100644
--- a/test/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
@@ -9,6 +9,7 @@
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.ru_RU.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp b/test/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp
index f7349aa..8b83bc0 100644
--- a/test/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 // REQUIRES: locale.ru_RU.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp b/test/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
index 05d87a4..05f0619 100644
--- a/test/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
@@ -9,6 +9,7 @@
 
 // REQUIRES: locale.en_US.UTF-8
 // REQUIRES: locale.ru_RU.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp b/test/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
index 34718c8..66be76d 100644
--- a/test/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 // REQUIRES: locale.ru_RU.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.cons/string.pass.cpp b/test/localization/locales/locale/locale.cons/string.pass.cpp
index 6c80df0..32c3507 100644
--- a/test/localization/locales/locale/locale.cons/string.pass.cpp
+++ b/test/localization/locales/locale/locale.cons/string.pass.cpp
@@ -9,6 +9,7 @@
 
 // REQUIRES: locale.ru_RU.UTF-8
 // REQUIRES: locale.zh_CN.UTF-8
+// UNSUPPORTED: msan, asan
 
 // <locale>
 
diff --git a/test/localization/locales/locale/locale.members/combine.pass.cpp b/test/localization/locales/locale/locale.members/combine.pass.cpp
index 8d74da0..8f189c7 100644
--- a/test/localization/locales/locale/locale.members/combine.pass.cpp
+++ b/test/localization/locales/locale/locale.members/combine.pass.cpp
@@ -11,6 +11,8 @@
 
 // template <class Facet> locale combine(const locale& other) const;
 
+// UNSUPPORTED: asan, msan
+
 #include <locale>
 #include <new>
 #include <cassert>
diff --git a/test/numerics/c.math/cmath.pass.cpp b/test/numerics/c.math/cmath.pass.cpp
index 973bea0..0b0d862 100644
--- a/test/numerics/c.math/cmath.pass.cpp
+++ b/test/numerics/c.math/cmath.pass.cpp
@@ -24,11 +24,88 @@
     operator T () { return T(N); }
 };
 
+// See PR21083
+// Ambiguous is a user-defined type that defines its own overloads of cmath
+// functions. When the std overloads are candidates too (by using or adl),
+// they should not interfere.
+struct Ambiguous : std::true_type { // ADL
+    operator float () { return 0.f; }
+    operator double () { return 0.; }
+};
+Ambiguous abs(Ambiguous){ return Ambiguous(); }
+Ambiguous acos(Ambiguous){ return Ambiguous(); }
+Ambiguous asin(Ambiguous){ return Ambiguous(); }
+Ambiguous atan(Ambiguous){ return Ambiguous(); }
+Ambiguous atan2(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous ceil(Ambiguous){ return Ambiguous(); }
+Ambiguous cos(Ambiguous){ return Ambiguous(); }
+Ambiguous cosh(Ambiguous){ return Ambiguous(); }
+Ambiguous exp(Ambiguous){ return Ambiguous(); }
+Ambiguous fabs(Ambiguous){ return Ambiguous(); }
+Ambiguous floor(Ambiguous){ return Ambiguous(); }
+Ambiguous fmod(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous frexp(Ambiguous, int*){ return Ambiguous(); }
+Ambiguous ldexp(Ambiguous, int){ return Ambiguous(); }
+Ambiguous log(Ambiguous){ return Ambiguous(); }
+Ambiguous log10(Ambiguous){ return Ambiguous(); }
+Ambiguous modf(Ambiguous, Ambiguous*){ return Ambiguous(); }
+Ambiguous pow(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous sin(Ambiguous){ return Ambiguous(); }
+Ambiguous sinh(Ambiguous){ return Ambiguous(); }
+Ambiguous sqrt(Ambiguous){ return Ambiguous(); }
+Ambiguous tan(Ambiguous){ return Ambiguous(); }
+Ambiguous tanh(Ambiguous){ return Ambiguous(); }
+Ambiguous signbit(Ambiguous){ return Ambiguous(); }
+Ambiguous fpclassify(Ambiguous){ return Ambiguous(); }
+Ambiguous isfinite(Ambiguous){ return Ambiguous(); }
+Ambiguous isnormal(Ambiguous){ return Ambiguous(); }
+Ambiguous isgreater(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous isgreaterequal(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous isless(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous islessequal(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous islessgreater(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous isunordered(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous acosh(Ambiguous){ return Ambiguous(); }
+Ambiguous asinh(Ambiguous){ return Ambiguous(); }
+Ambiguous atanh(Ambiguous){ return Ambiguous(); }
+Ambiguous cbrt(Ambiguous){ return Ambiguous(); }
+Ambiguous copysign(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous erf(Ambiguous){ return Ambiguous(); }
+Ambiguous erfc(Ambiguous){ return Ambiguous(); }
+Ambiguous exp2(Ambiguous){ return Ambiguous(); }
+Ambiguous expm1(Ambiguous){ return Ambiguous(); }
+Ambiguous fdim(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous fma(Ambiguous, Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous fmax(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous fmin(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous hypot(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous ilogb(Ambiguous){ return Ambiguous(); }
+Ambiguous lgamma(Ambiguous){ return Ambiguous(); }
+Ambiguous llrint(Ambiguous){ return Ambiguous(); }
+Ambiguous llround(Ambiguous){ return Ambiguous(); }
+Ambiguous log1p(Ambiguous){ return Ambiguous(); }
+Ambiguous log2(Ambiguous){ return Ambiguous(); }
+Ambiguous logb(Ambiguous){ return Ambiguous(); }
+Ambiguous lrint(Ambiguous){ return Ambiguous(); }
+Ambiguous lround(Ambiguous){ return Ambiguous(); }
+Ambiguous nearbyint(Ambiguous){ return Ambiguous(); }
+Ambiguous nextafter(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous nexttoward(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous remainder(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous remquo(Ambiguous, Ambiguous, int*){ return Ambiguous(); }
+Ambiguous rint(Ambiguous){ return Ambiguous(); }
+Ambiguous round(Ambiguous){ return Ambiguous(); }
+Ambiguous scalbln(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous scalbn(Ambiguous, Ambiguous){ return Ambiguous(); }
+Ambiguous tgamma(Ambiguous){ return Ambiguous(); }
+Ambiguous trunc(Ambiguous){ return Ambiguous(); }
+
 void test_abs()
 {
     static_assert((std::is_same<decltype(std::abs((float)0)), float>::value), "");
     static_assert((std::is_same<decltype(std::abs((double)0)), double>::value), "");
     static_assert((std::is_same<decltype(std::abs((long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value), "");
     assert(std::abs(-1.) == 1);
 }
 
@@ -47,6 +124,7 @@
     static_assert((std::is_same<decltype(std::acos((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::acosf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::acosl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(acos(Ambiguous())), Ambiguous>::value), "");
     assert(std::acos(1) == 0);
 }
 
@@ -65,6 +143,7 @@
     static_assert((std::is_same<decltype(std::asin((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::asinf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::asinl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(asin(Ambiguous())), Ambiguous>::value), "");
     assert(std::asin(0) == 0);
 }
 
@@ -83,6 +162,7 @@
     static_assert((std::is_same<decltype(std::atan((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::atanf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::atanl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atan(Ambiguous())), Ambiguous>::value), "");
     assert(std::atan(0) == 0);
 }
 
@@ -105,6 +185,7 @@
     static_assert((std::is_same<decltype(std::atan2f(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::atan2l(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::atan2((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(atan2(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::atan2(0,1) == 0);
 }
 
@@ -123,6 +204,7 @@
     static_assert((std::is_same<decltype(std::ceil((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::ceilf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::ceill(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(ceil(Ambiguous())), Ambiguous>::value), "");
     assert(std::ceil(0) == 0);
 }
 
@@ -141,6 +223,7 @@
     static_assert((std::is_same<decltype(std::cos((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::cosf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::cosl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(cos(Ambiguous())), Ambiguous>::value), "");
     assert(std::cos(0) == 1);
 }
 
@@ -159,6 +242,7 @@
     static_assert((std::is_same<decltype(std::cosh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::coshf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::coshl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(cosh(Ambiguous())), Ambiguous>::value), "");
     assert(std::cosh(0) == 1);
 }
 
@@ -177,6 +261,7 @@
     static_assert((std::is_same<decltype(std::exp((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::expf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::expl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(exp(Ambiguous())), Ambiguous>::value), "");
     assert(std::exp(0) == 1);
 }
 
@@ -195,6 +280,7 @@
     static_assert((std::is_same<decltype(std::fabs((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::fabsf(0.0f)), float>::value), "");
     static_assert((std::is_same<decltype(std::fabsl(0.0L)), long double>::value), "");
+    static_assert((std::is_same<decltype(fabs(Ambiguous())), Ambiguous>::value), "");
     assert(std::fabs(-1) == 1);
 }
 
@@ -213,6 +299,7 @@
     static_assert((std::is_same<decltype(std::floor((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::floorf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::floorl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(floor(Ambiguous())), Ambiguous>::value), "");
     assert(std::floor(1) == 1);
 }
 
@@ -235,6 +322,7 @@
     static_assert((std::is_same<decltype(std::fmodf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::fmodl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::fmod((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmod(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::fmod(1.5,1) == .5);
 }
 
@@ -254,6 +342,7 @@
     static_assert((std::is_same<decltype(std::frexp((long double)0, &ip)), long double>::value), "");
     static_assert((std::is_same<decltype(std::frexpf(0, &ip)), float>::value), "");
     static_assert((std::is_same<decltype(std::frexpl(0, &ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(frexp(Ambiguous(), &ip)), Ambiguous>::value), "");
     assert(std::frexp(0, &ip) == 0);
 }
 
@@ -273,6 +362,7 @@
     static_assert((std::is_same<decltype(std::ldexp((long double)0, ip)), long double>::value), "");
     static_assert((std::is_same<decltype(std::ldexpf(0, ip)), float>::value), "");
     static_assert((std::is_same<decltype(std::ldexpl(0, ip)), long double>::value), "");
+    static_assert((std::is_same<decltype(ldexp(Ambiguous(), ip)), Ambiguous>::value), "");
     assert(std::ldexp(1, ip) == 2);
 }
 
@@ -291,6 +381,7 @@
     static_assert((std::is_same<decltype(std::log((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::logf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::logl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log(Ambiguous())), Ambiguous>::value), "");
     assert(std::log(1) == 0);
 }
 
@@ -309,6 +400,7 @@
     static_assert((std::is_same<decltype(std::log10((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::log10f(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::log10l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log10(Ambiguous())), Ambiguous>::value), "");
     assert(std::log10(1) == 0);
 }
 
@@ -319,6 +411,7 @@
     static_assert((std::is_same<decltype(std::modf((long double)0, (long double*)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::modff(0, (float*)0)), float>::value), "");
     static_assert((std::is_same<decltype(std::modfl(0, (long double*)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(modf(Ambiguous(), (Ambiguous*)0)), Ambiguous>::value), "");
     double i;
     assert(std::modf(1., &i) == 0);
 }
@@ -345,6 +438,7 @@
 //     static_assert((std::is_same<decltype(std::pow(Value<int>(), (int)0)), double>::value), "");
 //     static_assert((std::is_same<decltype(std::pow(Value<long double>(), (float)0)), long double>::value), "");
 //     static_assert((std::is_same<decltype(std::pow((float) 0, Value<float>())), float>::value), "");
+    static_assert((std::is_same<decltype(pow(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::pow(1,1) == 1);
 //     assert(std::pow(Value<int,1>(), Value<float,1>())  == 1);
 //     assert(std::pow(1.0f, Value<double,1>()) == 1);
@@ -367,6 +461,7 @@
     static_assert((std::is_same<decltype(std::sin((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::sinf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::sinl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(sin(Ambiguous())), Ambiguous>::value), "");
     assert(std::sin(0) == 0);
 }
 
@@ -385,6 +480,7 @@
     static_assert((std::is_same<decltype(std::sinh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::sinhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::sinhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(sinh(Ambiguous())), Ambiguous>::value), "");
     assert(std::sinh(0) == 0);
 }
 
@@ -403,6 +499,7 @@
     static_assert((std::is_same<decltype(std::sqrt((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::sqrtf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::sqrtl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(sqrt(Ambiguous())), Ambiguous>::value), "");
     assert(std::sqrt(4) == 2);
 }
 
@@ -421,6 +518,7 @@
     static_assert((std::is_same<decltype(std::tan((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::tanf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::tanl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(tan(Ambiguous())), Ambiguous>::value), "");
     assert(std::tan(0) == 0);
 }
 
@@ -439,6 +537,7 @@
     static_assert((std::is_same<decltype(std::tanh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::tanhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::tanhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(tanh(Ambiguous())), Ambiguous>::value), "");
     assert(std::tanh(0) == 0);
 }
 
@@ -451,6 +550,7 @@
     static_assert((std::is_same<decltype(std::signbit((double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::signbit(0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::signbit((long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(signbit(Ambiguous())), Ambiguous>::value), "");
     assert(std::signbit(-1.0) == true);
 }
 
@@ -463,6 +563,7 @@
     static_assert((std::is_same<decltype(std::fpclassify((double)0)), int>::value), "");
     static_assert((std::is_same<decltype(std::fpclassify(0)), int>::value), "");
     static_assert((std::is_same<decltype(std::fpclassify((long double)0)), int>::value), "");
+    static_assert((std::is_same<decltype(fpclassify(Ambiguous())), Ambiguous>::value), "");
     assert(std::fpclassify(-1.0) == FP_NORMAL);
 }
 
@@ -475,6 +576,7 @@
     static_assert((std::is_same<decltype(std::isfinite((double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isfinite(0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isfinite((long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isfinite(Ambiguous())), Ambiguous>::value), "");
     assert(std::isfinite(-1.0) == true);
 }
 
@@ -487,6 +589,7 @@
     static_assert((std::is_same<decltype(std::isnormal((double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isnormal(0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isnormal((long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isnormal(Ambiguous())), Ambiguous>::value), "");
     assert(std::isnormal(-1.0) == true);
 }
 
@@ -505,6 +608,7 @@
     static_assert((std::is_same<decltype(std::isgreater((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isgreater((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isgreater((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isgreater(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::isgreater(-1.0, 0.F) == false);
 }
 
@@ -523,6 +627,7 @@
     static_assert((std::is_same<decltype(std::isgreaterequal((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isgreaterequal((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isgreaterequal((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isgreaterequal(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::isgreaterequal(-1.0, 0.F) == false);
 }
 
@@ -541,6 +646,7 @@
     static_assert((std::is_same<decltype(std::isless((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isless((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isless((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isless(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::isless(-1.0, 0.F) == true);
 }
 
@@ -559,6 +665,7 @@
     static_assert((std::is_same<decltype(std::islessequal((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::islessequal((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::islessequal((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(islessequal(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::islessequal(-1.0, 0.F) == true);
 }
 
@@ -577,6 +684,7 @@
     static_assert((std::is_same<decltype(std::islessgreater((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::islessgreater((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::islessgreater((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(islessgreater(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::islessgreater(-1.0, 0.F) == true);
 }
 
@@ -595,6 +703,7 @@
     static_assert((std::is_same<decltype(std::isunordered((long double)0, (float)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isunordered((long double)0, (double)0)), bool>::value), "");
     static_assert((std::is_same<decltype(std::isunordered((long double)0, (long double)0)), bool>::value), "");
+    static_assert((std::is_same<decltype(isunordered(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::isunordered(-1.0, 0.F) == false);
 }
 
@@ -613,6 +722,7 @@
     static_assert((std::is_same<decltype(std::acosh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::acoshf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::acoshl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(acosh(Ambiguous())), Ambiguous>::value), "");
     assert(std::acosh(1) == 0);
 }
 
@@ -631,6 +741,7 @@
     static_assert((std::is_same<decltype(std::asinh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::asinhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::asinhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(asinh(Ambiguous())), Ambiguous>::value), "");
     assert(std::asinh(0) == 0);
 }
 
@@ -649,6 +760,7 @@
     static_assert((std::is_same<decltype(std::atanh((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::atanhf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::atanhl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(atanh(Ambiguous())), Ambiguous>::value), "");
     assert(std::atanh(0) == 0);
 }
 
@@ -667,6 +779,7 @@
     static_assert((std::is_same<decltype(std::cbrt((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::cbrtf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::cbrtl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(cbrt(Ambiguous())), Ambiguous>::value), "");
     assert(std::cbrt(1) == 1);
 }
 
@@ -689,6 +802,7 @@
     static_assert((std::is_same<decltype(std::copysignf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::copysignl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::copysign((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(copysign(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::copysign(1,1) == 1);
 }
 
@@ -707,6 +821,7 @@
     static_assert((std::is_same<decltype(std::erf((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::erff(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::erfl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(erf(Ambiguous())), Ambiguous>::value), "");
     assert(std::erf(0) == 0);
 }
 
@@ -725,6 +840,7 @@
     static_assert((std::is_same<decltype(std::erfc((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::erfcf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::erfcl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(erfc(Ambiguous())), Ambiguous>::value), "");
     assert(std::erfc(0) == 1);
 }
 
@@ -743,6 +859,7 @@
     static_assert((std::is_same<decltype(std::exp2((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::exp2f(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::exp2l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(exp2(Ambiguous())), Ambiguous>::value), "");
     assert(std::exp2(1) == 2);
 }
 
@@ -761,6 +878,7 @@
     static_assert((std::is_same<decltype(std::expm1((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::expm1f(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::expm1l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(expm1(Ambiguous())), Ambiguous>::value), "");
     assert(std::expm1(0) == 0);
 }
 
@@ -783,6 +901,7 @@
     static_assert((std::is_same<decltype(std::fdimf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::fdiml(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::fdim((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fdim(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::fdim(1,0) == 1);
 }
 
@@ -820,6 +939,7 @@
 
     static_assert((std::is_same<decltype(std::fmaf(0,0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::fmal(0,0,0)), long double>::value), "");
+    static_assert((std::is_same<decltype(fma(Ambiguous(), Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::fma(1,1,1) == 2);
 }
 
@@ -842,6 +962,7 @@
     static_assert((std::is_same<decltype(std::fmaxf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::fmaxl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::fmax((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmax(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::fmax(1,0) == 1);
 }
 
@@ -864,6 +985,7 @@
     static_assert((std::is_same<decltype(std::fminf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::fminl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::fmin((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(fmin(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::fmin(1,0) == 0);
 }
 
@@ -886,6 +1008,7 @@
     static_assert((std::is_same<decltype(std::hypotf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::hypotl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::hypot((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(hypot(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::hypot(3,4) == 5);
 }
 
@@ -904,6 +1027,7 @@
     static_assert((std::is_same<decltype(std::ilogb((long double)0)), int>::value), "");
     static_assert((std::is_same<decltype(std::ilogbf(0)), int>::value), "");
     static_assert((std::is_same<decltype(std::ilogbl(0)), int>::value), "");
+    static_assert((std::is_same<decltype(ilogb(Ambiguous())), Ambiguous>::value), "");
     assert(std::ilogb(1) == 0);
 }
 
@@ -922,6 +1046,7 @@
     static_assert((std::is_same<decltype(std::lgamma((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::lgammaf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::lgammal(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(lgamma(Ambiguous())), Ambiguous>::value), "");
     assert(std::lgamma(1) == 0);
 }
 
@@ -940,6 +1065,7 @@
     static_assert((std::is_same<decltype(std::llrint((long double)0)), long long>::value), "");
     static_assert((std::is_same<decltype(std::llrintf(0)), long long>::value), "");
     static_assert((std::is_same<decltype(std::llrintl(0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llrint(Ambiguous())), Ambiguous>::value), "");
     assert(std::llrint(1) == 1LL);
 }
 
@@ -958,6 +1084,7 @@
     static_assert((std::is_same<decltype(std::llround((long double)0)), long long>::value), "");
     static_assert((std::is_same<decltype(std::llroundf(0)), long long>::value), "");
     static_assert((std::is_same<decltype(std::llroundl(0)), long long>::value), "");
+    static_assert((std::is_same<decltype(llround(Ambiguous())), Ambiguous>::value), "");
     assert(std::llround(1) == 1LL);
 }
 
@@ -976,6 +1103,7 @@
     static_assert((std::is_same<decltype(std::log1p((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::log1pf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::log1pl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log1p(Ambiguous())), Ambiguous>::value), "");
     assert(std::log1p(0) == 0);
 }
 
@@ -994,6 +1122,7 @@
     static_assert((std::is_same<decltype(std::log2((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::log2f(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::log2l(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(log2(Ambiguous())), Ambiguous>::value), "");
     assert(std::log2(1) == 0);
 }
 
@@ -1012,6 +1141,7 @@
     static_assert((std::is_same<decltype(std::logb((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::logbf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::logbl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(logb(Ambiguous())), Ambiguous>::value), "");
     assert(std::logb(1) == 0);
 }
 
@@ -1030,6 +1160,7 @@
     static_assert((std::is_same<decltype(std::lrint((long double)0)), long>::value), "");
     static_assert((std::is_same<decltype(std::lrintf(0)), long>::value), "");
     static_assert((std::is_same<decltype(std::lrintl(0)), long>::value), "");
+    static_assert((std::is_same<decltype(lrint(Ambiguous())), Ambiguous>::value), "");
     assert(std::lrint(1) == 1L);
 }
 
@@ -1048,6 +1179,7 @@
     static_assert((std::is_same<decltype(std::lround((long double)0)), long>::value), "");
     static_assert((std::is_same<decltype(std::lroundf(0)), long>::value), "");
     static_assert((std::is_same<decltype(std::lroundl(0)), long>::value), "");
+    static_assert((std::is_same<decltype(lround(Ambiguous())), Ambiguous>::value), "");
     assert(std::lround(1) == 1L);
 }
 
@@ -1073,6 +1205,7 @@
     static_assert((std::is_same<decltype(std::nearbyint((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::nearbyintf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::nearbyintl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nearbyint(Ambiguous())), Ambiguous>::value), "");
     assert(std::nearbyint(1) == 1);
 }
 
@@ -1095,6 +1228,7 @@
     static_assert((std::is_same<decltype(std::nextafterf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::nextafterl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::nextafter((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(nextafter(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::nextafter(0,1) == hexfloat<double>(0x1, 0, -1074));
 }
 
@@ -1113,6 +1247,7 @@
     static_assert((std::is_same<decltype(std::nexttoward((long double)0, (long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::nexttowardf(0, (long double)0)), float>::value), "");
     static_assert((std::is_same<decltype(std::nexttowardl(0, (long double)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(nexttoward(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::nexttoward(0, 1) == hexfloat<double>(0x1, 0, -1074));
 }
 
@@ -1135,6 +1270,7 @@
     static_assert((std::is_same<decltype(std::remainderf(0,0)), float>::value), "");
     static_assert((std::is_same<decltype(std::remainderl(0,0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::remainder((int)0, (int)0)), double>::value), "");
+    static_assert((std::is_same<decltype(remainder(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::remainder(0.5,1) == 0.5);
 }
 
@@ -1158,6 +1294,7 @@
     static_assert((std::is_same<decltype(std::remquof(0,0, &ip)), float>::value), "");
     static_assert((std::is_same<decltype(std::remquol(0,0, &ip)), long double>::value), "");
     static_assert((std::is_same<decltype(std::remquo((int)0, (int)0, &ip)), double>::value), "");
+    static_assert((std::is_same<decltype(remquo(Ambiguous(), Ambiguous(), &ip)), Ambiguous>::value), "");
     assert(std::remquo(0.5,1, &ip) == 0.5);
 }
 
@@ -1176,6 +1313,7 @@
     static_assert((std::is_same<decltype(std::rint((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::rintf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::rintl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(rint(Ambiguous())), Ambiguous>::value), "");
     assert(std::rint(1) == 1);
 }
 
@@ -1194,6 +1332,7 @@
     static_assert((std::is_same<decltype(std::round((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::roundf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::roundl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(round(Ambiguous())), Ambiguous>::value), "");
     assert(std::round(1) == 1);
 }
 
@@ -1212,6 +1351,7 @@
     static_assert((std::is_same<decltype(std::scalbln((long double)0, (long)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::scalblnf(0, (long)0)), float>::value), "");
     static_assert((std::is_same<decltype(std::scalblnl(0, (long)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(scalbln(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::scalbln(1, 1) == 2);
 }
 
@@ -1230,6 +1370,7 @@
     static_assert((std::is_same<decltype(std::scalbn((long double)0, (int)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::scalbnf(0, (int)0)), float>::value), "");
     static_assert((std::is_same<decltype(std::scalbnl(0, (int)0)), long double>::value), "");
+    static_assert((std::is_same<decltype(scalbn(Ambiguous(), Ambiguous())), Ambiguous>::value), "");
     assert(std::scalbn(1, 1) == 2);
 }
 
@@ -1248,6 +1389,7 @@
     static_assert((std::is_same<decltype(std::tgamma((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::tgammaf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::tgammal(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(tgamma(Ambiguous())), Ambiguous>::value), "");
     assert(std::tgamma(1) == 1);
 }
 
@@ -1266,6 +1408,7 @@
     static_assert((std::is_same<decltype(std::trunc((long double)0)), long double>::value), "");
     static_assert((std::is_same<decltype(std::truncf(0)), float>::value), "");
     static_assert((std::is_same<decltype(std::truncl(0)), long double>::value), "");
+    static_assert((std::is_same<decltype(trunc(Ambiguous())), Ambiguous>::value), "");
     assert(std::trunc(1) == 1);
 }
 
diff --git a/test/numerics/numarray/template.slice.array/slice.arr.assign/slice_array.pass.cpp b/test/numerics/numarray/template.slice.array/slice.arr.assign/slice_array.pass.cpp
index 79be4bd..72275e0 100644
--- a/test/numerics/numarray/template.slice.array/slice.arr.assign/slice_array.pass.cpp
+++ b/test/numerics/numarray/template.slice.array/slice.arr.assign/slice_array.pass.cpp
@@ -47,9 +47,8 @@
     int a1[] = {0, 1, 2};
     int a2[] = {3, 4, 3};
     std::valarray<int> v1(a1, 3);
-    const std::valarray<int> v2(a2, 3);
-    std::slice_array<int> s1 = v1[std::slice(1, 2, 3)];
-    std::slice_array<int> s2 = v1[std::slice(2, 2, 3)];
+    std::slice_array<int> s1 = v1[std::slice(1, 1, 1)];
+    std::slice_array<int> s2 = v1[std::slice(0, 1, 1)];
     std::slice_array<int> const & s3 = (s1 = s2);
     assert(&s1 == &s3);
     }
diff --git a/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp b/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp
index 3bfd2af..85ff2ac 100644
--- a/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp
+++ b/test/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/eval.pass.cpp
@@ -322,6 +322,17 @@
         assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
     }
     {
+        const int N = 100000;
+        std::mt19937 gen1;
+        std::mt19937 gen2;
+
+        std::binomial_distribution<>         dist1(5, 0.1);
+        std::binomial_distribution<unsigned> dist2(5, 0.1);
+
+        for(int i = 0; i < N; ++i)
+            assert(dist1(gen1) == dist2(gen2));
+    }
+    {
         typedef std::binomial_distribution<> D;
         typedef std::mt19937 G;
         G g;
diff --git a/test/re/re.alg/re.alg.match/basic.pass.cpp b/test/re/re.alg/re.alg.match/basic.pass.cpp
index d63817d..4139cea 100644
--- a/test/re/re.alg/re.alg.match/basic.pass.cpp
+++ b/test/re/re.alg/re.alg.match/basic.pass.cpp
@@ -18,6 +18,9 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/re/re.alg/re.alg.match/ecma.pass.cpp b/test/re/re.alg/re.alg.match/ecma.pass.cpp
index 67df410..3854056 100644
--- a/test/re/re.alg/re.alg.match/ecma.pass.cpp
+++ b/test/re/re.alg/re.alg.match/ecma.pass.cpp
@@ -18,6 +18,9 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/re/re.alg/re.alg.match/extended.pass.cpp b/test/re/re.alg/re.alg.match/extended.pass.cpp
index 733c16e..c54825d 100644
--- a/test/re/re.alg/re.alg.match/extended.pass.cpp
+++ b/test/re/re.alg/re.alg.match/extended.pass.cpp
@@ -18,6 +18,9 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/re/re.alg/re.alg.match/lookahead_capture.pass.cpp b/test/re/re.alg/re.alg.match/lookahead_capture.pass.cpp
index 78e1e65..949739b 100644
--- a/test/re/re.alg/re.alg.match/lookahead_capture.pass.cpp
+++ b/test/re/re.alg/re.alg.match/lookahead_capture.pass.cpp
@@ -27,10 +27,10 @@
 int main()
 {
     {
-        std::regex re{"^(?=(.))a$"};
+        std::regex re("^(?=(.))a$");
         assert(re.mark_count() == 1);
 
-        std::string s{"a"};
+        std::string s("a");
         std::smatch m;
         assert(std::regex_match(s, m, re));
         assert(m.size() == 2);
@@ -39,10 +39,10 @@
     }
 
     {
-        std::regex re{"^(a)(?=(.))(b)$"};
+        std::regex re("^(a)(?=(.))(b)$");
         assert(re.mark_count() == 3);
 
-        std::string s{"ab"};
+        std::string s("ab");
         std::smatch m;
         assert(std::regex_match(s, m, re));
         assert(m.size() == 4);
@@ -53,10 +53,10 @@
     }
 
     {
-        std::regex re{"^(.)(?=(.)(?=.(.)))(...)$"};
+        std::regex re("^(.)(?=(.)(?=.(.)))(...)$");
         assert(re.mark_count() == 4);
 
-        std::string s{"abcd"};
+        std::string s("abcd");
         std::smatch m;
         assert(std::regex_match(s, m, re));
         assert(m.size() == 5);
@@ -68,10 +68,10 @@
     }
 
     {
-        std::regex re{"^(a)(?!([^b]))(.c)$"};
+        std::regex re("^(a)(?!([^b]))(.c)$");
         assert(re.mark_count() == 3);
 
-        std::string s{"abc"};
+        std::string s("abc");
         std::smatch m;
         assert(std::regex_match(s, m, re));
         assert(m.size() == 4);
@@ -82,10 +82,10 @@
     }
 
     {
-        std::regex re{"^(?!((b)))(?=(.))(?!(abc)).b$"};
+        std::regex re("^(?!((b)))(?=(.))(?!(abc)).b$");
         assert(re.mark_count() == 4);
 
-        std::string s{"ab"};
+        std::string s("ab");
         std::smatch m;
         assert(std::regex_match(s, m, re));
         assert(m.size() == 5);
diff --git a/test/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp b/test/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
index 6a45418..0b4c694 100644
--- a/test/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
+++ b/test/re/re.alg/re.alg.match/parse_curly_brackets.pass.cpp
@@ -25,9 +25,9 @@
 void
 test1()
 {
-    std::string re{"\\{a\\}"};
-    std::string target{"{a}"};
-    std::regex regex{re};
+    std::string re("\\{a\\}");
+    std::string target("{a}");
+    std::regex regex(re);
     std::smatch smatch;
     assert((std::regex_match(target, smatch, regex)));
 }
@@ -35,9 +35,9 @@
 void
 test2()
 {
-    std::string re{"\\{a\\}"};
-    std::string target{"{a}"};
-    std::regex regex{re, std::regex::extended};
+    std::string re("\\{a\\}");
+    std::string target("{a}");
+    std::regex regex(re, std::regex::extended);
     std::smatch smatch;
     assert((std::regex_match(target, smatch, regex)));
 }
@@ -45,9 +45,9 @@
 void
 test3()
 {
-    std::string re{"\\{a\\}"};
-    std::string target{"{a}"};
-    std::regex regex{re, std::regex::awk};
+    std::string re("\\{a\\}");
+    std::string target("{a}");
+    std::regex regex(re, std::regex::awk);
     std::smatch smatch;
     assert((std::regex_match(target, smatch, regex)));
 }
@@ -55,9 +55,9 @@
 void
 test4()
 {
-    std::string re{"\\{a\\}"};
-    std::string target{"{a}"};
-    std::regex regex{re, std::regex::egrep};
+    std::string re("\\{a\\}");
+    std::string target("{a}");
+    std::regex regex(re, std::regex::egrep);
     std::smatch smatch;
     assert((std::regex_match(target, smatch, regex)));
 }
diff --git a/test/re/re.alg/re.alg.search/awk.pass.cpp b/test/re/re.alg/re.alg.search/awk.pass.cpp
index 74c25c1..521e98b 100644
--- a/test/re/re.alg/re.alg.search/awk.pass.cpp
+++ b/test/re/re.alg/re.alg.search/awk.pass.cpp
@@ -18,6 +18,9 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/re/re.alg/re.alg.search/backup.pass.cpp b/test/re/re.alg/re.alg.search/backup.pass.cpp
index 6bfad42..7da5860 100644
--- a/test/re/re.alg/re.alg.search/backup.pass.cpp
+++ b/test/re/re.alg/re.alg.search/backup.pass.cpp
@@ -26,10 +26,10 @@
     // This regex_iterator uses regex_search(__wrap_iter<_Iter> __first, ...)
     // Test for http://llvm.org/bugs/show_bug.cgi?id=16240 fixed in r185273.
     {
-        std::string s{"aaaa a"};
-        std::regex re{"\\ba"};
-        std::sregex_iterator it{s.begin(), s.end(), re};
-        std::sregex_iterator end{};
+        std::string s("aaaa a");
+        std::regex re("\\ba");
+        std::sregex_iterator it(s.begin(), s.end(), re);
+        std::sregex_iterator end = std::sregex_iterator();
 
         assert(it->position(0) == 0);
         assert(it->length(0) == 1);
@@ -44,11 +44,11 @@
 
     // This regex_iterator uses regex_search(_BidirectionalIterator __first, ...)
     {
-        std::string s{"aaaa a"};
-        std::list<char> l{s.begin(), s.end()};
-        std::regex re{"\\ba"};
-        std::regex_iterator<std::list<char>::iterator> it{l.begin(), l.end(), re};
-        std::regex_iterator<std::list<char>::iterator> end{};
+        std::string s("aaaa a");
+        std::list<char> l(s.begin(), s.end());
+        std::regex re("\\ba");
+        std::regex_iterator<std::list<char>::iterator> it(l.begin(), l.end(), re);
+        std::regex_iterator<std::list<char>::iterator> end = std::regex_iterator<std::list<char>::iterator>();
 
         assert(it->position(0) == 0);
         assert(it->length(0) == 1);
diff --git a/test/re/re.alg/re.alg.search/basic.pass.cpp b/test/re/re.alg/re.alg.search/basic.pass.cpp
index c8a5051..838294e 100644
--- a/test/re/re.alg/re.alg.search/basic.pass.cpp
+++ b/test/re/re.alg/re.alg.search/basic.pass.cpp
@@ -18,6 +18,9 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/re/re.alg/re.alg.search/ecma.pass.cpp b/test/re/re.alg/re.alg.search/ecma.pass.cpp
index 965c29d..2796850 100644
--- a/test/re/re.alg/re.alg.search/ecma.pass.cpp
+++ b/test/re/re.alg/re.alg.search/ecma.pass.cpp
@@ -18,6 +18,9 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/re/re.alg/re.alg.search/extended.pass.cpp b/test/re/re.alg/re.alg.search/extended.pass.cpp
index c181cff..a8a121b 100644
--- a/test/re/re.alg/re.alg.search/extended.pass.cpp
+++ b/test/re/re.alg/re.alg.search/extended.pass.cpp
@@ -18,6 +18,9 @@
 //                  const basic_regex<charT, traits>& e,
 //                  regex_constants::match_flag_type flags = regex_constants::match_default);
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/re/re.alg/re.alg.search/no_update_pos.pass.cpp b/test/re/re.alg/re.alg.search/no_update_pos.pass.cpp
index 63fcdaf..ef9cec5 100644
--- a/test/re/re.alg/re.alg.search/no_update_pos.pass.cpp
+++ b/test/re/re.alg/re.alg.search/no_update_pos.pass.cpp
@@ -25,9 +25,9 @@
     // of the text.
 
     const char *text = "aaa\naa";
-    std::regex re{"^a"};
-    std::cregex_iterator it{text, text+6, re};
-    std::cregex_iterator end{};
+    std::regex re("^a");
+    std::cregex_iterator it(text, text+6, re);
+    std::cregex_iterator end = std::cregex_iterator();
 
     assert(it->str() == "a");
     assert(it->position(0) == 0);
diff --git a/test/re/re.regex/re.regex.construct/awk_oct.pass.cpp b/test/re/re.regex/re.regex.construct/awk_oct.pass.cpp
index 11fce3f..4b7e5e6 100644
--- a/test/re/re.regex/re.regex.construct/awk_oct.pass.cpp
+++ b/test/re/re.regex/re.regex.construct/awk_oct.pass.cpp
@@ -21,8 +21,8 @@
 {
     using std::regex_constants::awk;
 
-    assert(std::regex_match("\4", std::regex{"\\4", awk}));
-    assert(std::regex_match("\41", std::regex{"\\41", awk}));
-    assert(std::regex_match("\141", std::regex{"\\141", awk}));
-    assert(std::regex_match("\1411", std::regex{"\\1411", awk}));
+    assert(std::regex_match("\4", std::regex("\\4", awk)));
+    assert(std::regex_match("\41", std::regex("\\41", awk)));
+    assert(std::regex_match("\141", std::regex("\\141", awk)));
+    assert(std::regex_match("\1411", std::regex("\\1411", awk)));
 }
diff --git a/test/re/re.traits/lookup_collatename.pass.cpp b/test/re/re.traits/lookup_collatename.pass.cpp
index 049246e..d495f8a 100644
--- a/test/re/re.traits/lookup_collatename.pass.cpp
+++ b/test/re/re.traits/lookup_collatename.pass.cpp
@@ -17,6 +17,9 @@
 //   string_type
 //   lookup_collatename(ForwardIterator first, ForwardIterator last) const;
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <iterator>
 #include <cassert>
diff --git a/test/re/re.traits/translate_nocase.pass.cpp b/test/re/re.traits/translate_nocase.pass.cpp
index a490b52..0692e00 100644
--- a/test/re/re.traits/translate_nocase.pass.cpp
+++ b/test/re/re.traits/translate_nocase.pass.cpp
@@ -8,18 +8,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: android
-// XFAIL: androideabi
-
 // <regex>
 
 // template <class charT> struct regex_traits;
 
 // charT translate_nocase(charT c) const;
 
+// REQUIRES: locale.en_US.UTF-8
+
 // XFAIL: with_system_lib=x86_64-apple-darwin11
 // XFAIL: with_system_lib=x86_64-apple-darwin12
 
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
 #include <regex>
 #include <cassert>
 
diff --git a/test/strings/basic.string/string.capacity/max_size.pass.cpp b/test/strings/basic.string/string.capacity/max_size.pass.cpp
index e6a3aa4..f426425 100644
--- a/test/strings/basic.string/string.capacity/max_size.pass.cpp
+++ b/test/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -11,6 +11,13 @@
 
 // size_type max_size() const;
 
+// NOTE: asan and msan will fail for one of two reasons
+// 1. If allocator_may_return_null=0 then they will fail because the allocation
+//    returns null.
+// 2. If allocator_may_return_null=1 then they will fail because the allocation
+//    is too large to succeed.
+// UNSUPPORTED: asan, msan
+
 #include <string>
 #include <cassert>
 
@@ -40,23 +47,11 @@
 
 template <class S>
 void
-test3(const S& s)
-{
-    S s2(s);
-    const size_t sz = s2.max_size() + 1;
-    try { s2.resize(sz, 'x'); }
-    catch ( const std::length_error & ) { return ; }
-    assert ( false );
-}
-
-template <class S>
-void
 test(const S& s)
 {
     assert(s.max_size() >= s.size());
     test1(s);
     test2(s);
-    test3(s);
 }
 
 int main()
diff --git a/test/strings/basic.string/string.capacity/over_max_size.pass.cpp b/test/strings/basic.string/string.capacity/over_max_size.pass.cpp
new file mode 100644
index 0000000..bbadb9c
--- /dev/null
+++ b/test/strings/basic.string/string.capacity/over_max_size.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// size_type max_size() const;
+
+#include <string>
+#include <cassert>
+
+#include "min_allocator.h"
+
+template <class S>
+void
+test(const S& s)
+{
+    assert(s.max_size() >= s.size());
+    S s2(s);
+    const size_t sz = s2.max_size() + 1;
+    try { s2.resize(sz, 'x'); }
+    catch ( const std::length_error & ) { return ; }
+    assert ( false );
+}
+
+int main()
+{
+    {
+    typedef std::string S;
+    test(S());
+    test(S("123"));
+    test(S("12345678901234567890123456789012345678901234567890"));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    test(S());
+    test(S("123"));
+    test(S("12345678901234567890123456789012345678901234567890"));
+    }
+#endif
+}
diff --git a/test/support/asan_testing.h b/test/support/asan_testing.h
index c8797bd..45ad04b 100644
--- a/test/support/asan_testing.h
+++ b/test/support/asan_testing.h
@@ -19,7 +19,7 @@
 template <typename T, typename Alloc>
 bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c )
 {
-    if ( std::is_same<Alloc, std::allocator<T>>::value && c.data() != NULL)
+    if ( std::is_same<Alloc, std::allocator<T> >::value && c.data() != NULL)
         return __sanitizer_verify_contiguous_container (
             c.data(), c.data() + c.size(), c.data() + c.capacity()) != 0;
     return true;
@@ -34,4 +34,4 @@
 #endif
  
 
-#endif  // ASAN_TESTING_H
\ No newline at end of file
+#endif  // ASAN_TESTING_H
diff --git a/test/support/counting_predicates.hpp b/test/support/counting_predicates.hpp
index e825848..aab6a97 100644
--- a/test/support/counting_predicates.hpp
+++ b/test/support/counting_predicates.hpp
@@ -14,33 +14,33 @@
 template <typename Predicate, typename Arg>
 struct unary_counting_predicate : public std::unary_function<Arg, bool>  {
 public:
-	unary_counting_predicate(Predicate p) : p_(p), count_(0) {}
-	~unary_counting_predicate() {}
-	
-	bool operator () (const Arg &a) const { ++count_; return p_(a); }
-	size_t count() const { return count_; }
-	void reset() { count_ = 0; }
-	
+    unary_counting_predicate(Predicate p) : p_(p), count_(0) {}
+    ~unary_counting_predicate() {}
+    
+    bool operator () (const Arg &a) const { ++count_; return p_(a); }
+    size_t count() const { return count_; }
+    void reset() { count_ = 0; }
+    
 private:
-	Predicate p_;
-	mutable size_t count_;
-	};
+    Predicate p_;
+    mutable size_t count_;
+    };
 
 
 template <typename Predicate, typename Arg1, typename Arg2=Arg1>
 struct binary_counting_predicate : public std::binary_function<Arg1, Arg2, bool> {
 public:
 
-	binary_counting_predicate ( Predicate p ) : p_(p), count_(0) {}
-	~binary_counting_predicate() {}
-	
-	bool operator () (const Arg1 &a1, const Arg2 &a2) const { ++count_; return p_(a1, a2); }
-	size_t count() const { return count_; }
-	void reset() { count_ = 0; }
+    binary_counting_predicate ( Predicate p ) : p_(p), count_(0) {}
+    ~binary_counting_predicate() {}
+    
+    bool operator () (const Arg1 &a1, const Arg2 &a2) const { ++count_; return p_(a1, a2); }
+    size_t count() const { return count_; }
+    void reset() { count_ = 0; }
 
 private:
-	Predicate p_;
-	mutable size_t count_;
-	};
+    Predicate p_;
+    mutable size_t count_;
+    };
 
 #endif // __COUNTING_PREDICATES_H
diff --git a/test/support/test_iterators.h b/test/support/test_iterators.h
index 5bd6df7..e09fd83 100644
--- a/test/support/test_iterators.h
+++ b/test/support/test_iterators.h
@@ -11,6 +11,13 @@
 #define ITERATORS_H
 
 #include <iterator>
+#include <cassert>
+
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION
+#endif
 
 template <class It>
 class output_iterator
@@ -37,6 +44,9 @@
     output_iterator& operator++() {++it_; return *this;}
     output_iterator operator++(int)
         {output_iterator tmp(*this); ++(*this); return tmp;}
+
+    template <class T>
+    void operator,(T const &) DELETE_FUNCTION;
 };
 
 template <class It>
@@ -70,6 +80,9 @@
         {return x.it_ == y.it_;}
     friend bool operator!=(const input_iterator& x, const input_iterator& y)
         {return !(x == y);}
+
+    template <class T>
+    void operator,(T const &) DELETE_FUNCTION;
 };
 
 template <class T, class U>
@@ -119,6 +132,9 @@
         {return x.it_ == y.it_;}
     friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
         {return !(x == y);}
+
+    template <class T>
+    void operator,(T const &) DELETE_FUNCTION;
 };
 
 template <class T, class U>
@@ -167,6 +183,9 @@
     bidirectional_iterator& operator--() {--it_; return *this;}
     bidirectional_iterator operator--(int)
         {bidirectional_iterator tmp(*this); --(*this); return tmp;}
+
+    template <class T>
+    void operator,(T const &) DELETE_FUNCTION;
 };
 
 template <class T, class U>
@@ -226,6 +245,9 @@
         {random_access_iterator tmp(*this); tmp -= n; return tmp;}
 
     reference operator[](difference_type n) const {return it_[n];}
+
+    template <class T>
+    void operator,(T const &) DELETE_FUNCTION;
 };
 
 template <class T, class U>
@@ -302,4 +324,6 @@
 template <class Iter>    // everything else
 inline Iter base(Iter i) { return i; }
 
+#undef DELETE_FUNCTION
+
 #endif  // ITERATORS_H
diff --git a/test/thread/futures/futures.async/async.pass.cpp b/test/thread/futures/futures.async/async.pass.cpp
index f67abe4..c8a7425 100644
--- a/test/thread/futures/futures.async/async.pass.cpp
+++ b/test/thread/futures/futures.async/async.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.errors/default_error_condition.pass.cpp b/test/thread/futures/futures.errors/default_error_condition.pass.cpp
index 35afe5a..7f28b8a 100644
--- a/test/thread/futures/futures.errors/default_error_condition.pass.cpp
+++ b/test/thread/futures/futures.errors/default_error_condition.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp b/test/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp
index 1f1cf40..cd00176 100644
--- a/test/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp
+++ b/test/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp b/test/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp
index 06fdce1..05ad1ec 100644
--- a/test/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp
+++ b/test/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.errors/future_category.pass.cpp b/test/thread/futures/futures.errors/future_category.pass.cpp
index 515946c..7f407a0 100644
--- a/test/thread/futures/futures.errors/future_category.pass.cpp
+++ b/test/thread/futures/futures.errors/future_category.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.errors/make_error_code.pass.cpp b/test/thread/futures/futures.errors/make_error_code.pass.cpp
index f904c46..3c14add 100644
--- a/test/thread/futures/futures.errors/make_error_code.pass.cpp
+++ b/test/thread/futures/futures.errors/make_error_code.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.errors/make_error_condition.pass.cpp b/test/thread/futures/futures.errors/make_error_condition.pass.cpp
index fd0f1c5..52972aa 100644
--- a/test/thread/futures/futures.errors/make_error_condition.pass.cpp
+++ b/test/thread/futures/futures.errors/make_error_condition.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.future_error/code.pass.cpp b/test/thread/futures/futures.future_error/code.pass.cpp
index fdbfa4e..e02af48 100644
--- a/test/thread/futures/futures.future_error/code.pass.cpp
+++ b/test/thread/futures/futures.future_error/code.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.future_error/types.pass.cpp b/test/thread/futures/futures.future_error/types.pass.cpp
index af8e219..e741dd0 100644
--- a/test/thread/futures/futures.future_error/types.pass.cpp
+++ b/test/thread/futures/futures.future_error/types.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.future_error/what.pass.cpp b/test/thread/futures/futures.future_error/what.pass.cpp
index 5e54350..1a66e4a 100644
--- a/test/thread/futures/futures.future_error/what.pass.cpp
+++ b/test/thread/futures/futures.future_error/what.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // LWG 2056 changed the values of future_errc, so if we're using new headers
 // with an old library we'll get incorrect messages.
diff --git a/test/thread/futures/futures.overview/future_errc.pass.cpp b/test/thread/futures/futures.overview/future_errc.pass.cpp
index 7b3b70a..1e6fcb7 100644
--- a/test/thread/futures/futures.overview/future_errc.pass.cpp
+++ b/test/thread/futures/futures.overview/future_errc.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.overview/future_status.pass.cpp b/test/thread/futures/futures.overview/future_status.pass.cpp
index 0b6d32c..2c196aa 100644
--- a/test/thread/futures/futures.overview/future_status.pass.cpp
+++ b/test/thread/futures/futures.overview/future_status.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp b/test/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp
index 85b7993..499de52 100644
--- a/test/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp
+++ b/test/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.overview/launch.pass.cpp b/test/thread/futures/futures.overview/launch.pass.cpp
index 5f4663c..da54f7e 100644
--- a/test/thread/futures/futures.overview/launch.pass.cpp
+++ b/test/thread/futures/futures.overview/launch.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/alloc_ctor.pass.cpp b/test/thread/futures/futures.promise/alloc_ctor.pass.cpp
index dca399f..70a4e00 100644
--- a/test/thread/futures/futures.promise/alloc_ctor.pass.cpp
+++ b/test/thread/futures/futures.promise/alloc_ctor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
@@ -18,6 +20,7 @@
 #include <cassert>
 
 #include "../test_allocator.h"
+#include "min_allocator.h"
 
 int main()
 {
@@ -46,4 +49,36 @@
         assert(f.valid());
     }
     assert(test_alloc_base::count == 0);
+    // Test with a minimal allocator
+    {
+        std::promise<int> p(std::allocator_arg, bare_allocator<void>());
+        std::future<int> f = p.get_future();
+        assert(f.valid());
+    }
+    {
+        std::promise<int&> p(std::allocator_arg, bare_allocator<void>());
+        std::future<int&> f = p.get_future();
+        assert(f.valid());
+    }
+    {
+        std::promise<void> p(std::allocator_arg, bare_allocator<void>());
+        std::future<void> f = p.get_future();
+        assert(f.valid());
+    }
+    // Test with a minimal allocator that returns class-type pointers
+    {
+        std::promise<int> p(std::allocator_arg, min_allocator<void>());
+        std::future<int> f = p.get_future();
+        assert(f.valid());
+    }
+    {
+        std::promise<int&> p(std::allocator_arg, min_allocator<void>());
+        std::future<int&> f = p.get_future();
+        assert(f.valid());
+    }
+    {
+        std::promise<void> p(std::allocator_arg, min_allocator<void>());
+        std::future<void> f = p.get_future();
+        assert(f.valid());
+    }
 }
diff --git a/test/thread/futures/futures.promise/default.pass.cpp b/test/thread/futures/futures.promise/default.pass.cpp
index 47aec02..95c9657 100644
--- a/test/thread/futures/futures.promise/default.pass.cpp
+++ b/test/thread/futures/futures.promise/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/dtor.pass.cpp b/test/thread/futures/futures.promise/dtor.pass.cpp
index cd4fafb..78912f1 100644
--- a/test/thread/futures/futures.promise/dtor.pass.cpp
+++ b/test/thread/futures/futures.promise/dtor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/get_future.pass.cpp b/test/thread/futures/futures.promise/get_future.pass.cpp
index e7e78c7..a7d084e 100644
--- a/test/thread/futures/futures.promise/get_future.pass.cpp
+++ b/test/thread/futures/futures.promise/get_future.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/move_assign.pass.cpp b/test/thread/futures/futures.promise/move_assign.pass.cpp
index c378495..c3097df 100644
--- a/test/thread/futures/futures.promise/move_assign.pass.cpp
+++ b/test/thread/futures/futures.promise/move_assign.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/move_ctor.pass.cpp b/test/thread/futures/futures.promise/move_ctor.pass.cpp
index 4bd013a..eeec4fb 100644
--- a/test/thread/futures/futures.promise/move_ctor.pass.cpp
+++ b/test/thread/futures/futures.promise/move_ctor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_exception.pass.cpp b/test/thread/futures/futures.promise/set_exception.pass.cpp
index 13c9aa9..51c05eb 100644
--- a/test/thread/futures/futures.promise/set_exception.pass.cpp
+++ b/test/thread/futures/futures.promise/set_exception.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp b/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
index 7f9e418..5e57692 100644
--- a/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
+++ b/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_lvalue.pass.cpp b/test/thread/futures/futures.promise/set_lvalue.pass.cpp
index 4ee5fbb..cdc3777 100644
--- a/test/thread/futures/futures.promise/set_lvalue.pass.cpp
+++ b/test/thread/futures/futures.promise/set_lvalue.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp b/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
index eef353a..18f87c5 100644
--- a/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
+++ b/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/thread/futures/futures.promise/set_rvalue.pass.cpp
index 3cbacea..dab4bf7 100644
--- a/test/thread/futures/futures.promise/set_rvalue.pass.cpp
+++ b/test/thread/futures/futures.promise/set_rvalue.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp b/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
index 1e3108c..8f3b768 100644
--- a/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
+++ b/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp b/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
index bf8f21b..ec50cc3 100644
--- a/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
+++ b/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp b/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
index ee6f62f..8c09208 100644
--- a/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
+++ b/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_value_const.pass.cpp b/test/thread/futures/futures.promise/set_value_const.pass.cpp
index 94a9f92..6673f63 100644
--- a/test/thread/futures/futures.promise/set_value_const.pass.cpp
+++ b/test/thread/futures/futures.promise/set_value_const.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/set_value_void.pass.cpp b/test/thread/futures/futures.promise/set_value_void.pass.cpp
index c3b7e78..5012e0b 100644
--- a/test/thread/futures/futures.promise/set_value_void.pass.cpp
+++ b/test/thread/futures/futures.promise/set_value_void.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/swap.pass.cpp b/test/thread/futures/futures.promise/swap.pass.cpp
index 5e292b0..1ed3e64 100644
--- a/test/thread/futures/futures.promise/swap.pass.cpp
+++ b/test/thread/futures/futures.promise/swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.promise/uses_allocator.pass.cpp b/test/thread/futures/futures.promise/uses_allocator.pass.cpp
index 1f30682..458826e 100644
--- a/test/thread/futures/futures.promise/uses_allocator.pass.cpp
+++ b/test/thread/futures/futures.promise/uses_allocator.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/copy_assign.pass.cpp b/test/thread/futures/futures.shared_future/copy_assign.pass.cpp
index e6b86d1..b23ba19 100644
--- a/test/thread/futures/futures.shared_future/copy_assign.pass.cpp
+++ b/test/thread/futures/futures.shared_future/copy_assign.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/copy_ctor.pass.cpp b/test/thread/futures/futures.shared_future/copy_ctor.pass.cpp
index 445c189..425d1f9 100644
--- a/test/thread/futures/futures.shared_future/copy_ctor.pass.cpp
+++ b/test/thread/futures/futures.shared_future/copy_ctor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/ctor_future.pass.cpp b/test/thread/futures/futures.shared_future/ctor_future.pass.cpp
index 207473e..3a78b80 100644
--- a/test/thread/futures/futures.shared_future/ctor_future.pass.cpp
+++ b/test/thread/futures/futures.shared_future/ctor_future.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/default.pass.cpp b/test/thread/futures/futures.shared_future/default.pass.cpp
index dc056e8..92927f5 100644
--- a/test/thread/futures/futures.shared_future/default.pass.cpp
+++ b/test/thread/futures/futures.shared_future/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/dtor.pass.cpp b/test/thread/futures/futures.shared_future/dtor.pass.cpp
index a06a313..baa89cb 100644
--- a/test/thread/futures/futures.shared_future/dtor.pass.cpp
+++ b/test/thread/futures/futures.shared_future/dtor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/get.pass.cpp b/test/thread/futures/futures.shared_future/get.pass.cpp
index 16723ea..c5ee234 100644
--- a/test/thread/futures/futures.shared_future/get.pass.cpp
+++ b/test/thread/futures/futures.shared_future/get.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/move_assign.pass.cpp b/test/thread/futures/futures.shared_future/move_assign.pass.cpp
index 36e0168..6b58f41 100644
--- a/test/thread/futures/futures.shared_future/move_assign.pass.cpp
+++ b/test/thread/futures/futures.shared_future/move_assign.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/move_ctor.pass.cpp b/test/thread/futures/futures.shared_future/move_ctor.pass.cpp
index 35b8221..32b8fd7 100644
--- a/test/thread/futures/futures.shared_future/move_ctor.pass.cpp
+++ b/test/thread/futures/futures.shared_future/move_ctor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/wait.pass.cpp b/test/thread/futures/futures.shared_future/wait.pass.cpp
index b14d703..4293fca 100644
--- a/test/thread/futures/futures.shared_future/wait.pass.cpp
+++ b/test/thread/futures/futures.shared_future/wait.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/wait_for.pass.cpp b/test/thread/futures/futures.shared_future/wait_for.pass.cpp
index ae678ff..e5a4754 100644
--- a/test/thread/futures/futures.shared_future/wait_for.pass.cpp
+++ b/test/thread/futures/futures.shared_future/wait_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.shared_future/wait_until.pass.cpp b/test/thread/futures/futures.shared_future/wait_until.pass.cpp
index 1a0c9b3..258f9bf 100644
--- a/test/thread/futures/futures.shared_future/wait_until.pass.cpp
+++ b/test/thread/futures/futures.shared_future/wait_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
index a0f711a..18786f4 100644
--- a/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
index f53b26e..7690496 100644
--- a/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
index 58e9982..2eee2cb 100644
--- a/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
index e7070c5..3aac2b2 100644
--- a/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
@@ -18,6 +20,7 @@
 #include <cassert>
 
 #include "../../test_allocator.h"
+#include "min_allocator.h"
 
 class A
 {
@@ -92,4 +95,30 @@
         assert(f.get() == 4);
     }
     assert(test_alloc_base::count == 0);
+    A::n_copies = 0;
+    A::n_moves  = 0;
+    {
+        std::packaged_task<double(int, char)> p(std::allocator_arg,
+                                                bare_allocator<void>(), A(5));
+        assert(p.valid());
+        std::future<double> f = p.get_future();
+        p(3, 'a');
+        assert(f.get() == 105.0);
+        assert(A::n_copies == 0);
+        assert(A::n_moves > 0);
+    }
+    A::n_copies = 0;
+    A::n_moves  = 0;
+    {
+        std::packaged_task<double(int, char)> p(std::allocator_arg,
+                                                min_allocator<void>(), A(5));
+        assert(p.valid());
+        std::future<double> f = p.get_future();
+        p(3, 'a');
+        assert(f.get() == 105.0);
+        assert(A::n_copies == 0);
+        assert(A::n_moves > 0);
+    }
+    A::n_copies = 0;
+    A::n_moves  = 0;
 }
diff --git a/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
index c668a67..88f0722 100644
--- a/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
index 9b76934..e24232d 100644
--- a/test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
index d6efbf1..13b5db1 100644
--- a/test/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
index accbd75..61a6a4f 100644
--- a/test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
index b77cf31..2a09353 100644
--- a/test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
index 3ca3d14..9d38d9b 100644
--- a/test/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
index 9f549aa..33763be 100644
--- a/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
index ef99f61..668732b 100644
--- a/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
index 130390f..986f71e 100644
--- a/test/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
+++ b/test/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.tas/types.pass.cpp b/test/thread/futures/futures.tas/types.pass.cpp
index c66f359..dd1724d 100644
--- a/test/thread/futures/futures.tas/types.pass.cpp
+++ b/test/thread/futures/futures.tas/types.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/default.pass.cpp b/test/thread/futures/futures.unique_future/default.pass.cpp
index 915f118..84cb846 100644
--- a/test/thread/futures/futures.unique_future/default.pass.cpp
+++ b/test/thread/futures/futures.unique_future/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/dtor.pass.cpp b/test/thread/futures/futures.unique_future/dtor.pass.cpp
index 1bc141b..5e9697b 100644
--- a/test/thread/futures/futures.unique_future/dtor.pass.cpp
+++ b/test/thread/futures/futures.unique_future/dtor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/get.pass.cpp b/test/thread/futures/futures.unique_future/get.pass.cpp
index 1b0ee2b..758e38a 100644
--- a/test/thread/futures/futures.unique_future/get.pass.cpp
+++ b/test/thread/futures/futures.unique_future/get.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/move_assign.pass.cpp b/test/thread/futures/futures.unique_future/move_assign.pass.cpp
index 79dcd7d..8d38b81 100644
--- a/test/thread/futures/futures.unique_future/move_assign.pass.cpp
+++ b/test/thread/futures/futures.unique_future/move_assign.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/move_ctor.pass.cpp b/test/thread/futures/futures.unique_future/move_ctor.pass.cpp
index af23e4d..e12c920 100644
--- a/test/thread/futures/futures.unique_future/move_ctor.pass.cpp
+++ b/test/thread/futures/futures.unique_future/move_ctor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/share.pass.cpp b/test/thread/futures/futures.unique_future/share.pass.cpp
index a19ce2e..794b5ce 100644
--- a/test/thread/futures/futures.unique_future/share.pass.cpp
+++ b/test/thread/futures/futures.unique_future/share.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/wait.pass.cpp b/test/thread/futures/futures.unique_future/wait.pass.cpp
index 68c0d14..e10d37c 100644
--- a/test/thread/futures/futures.unique_future/wait.pass.cpp
+++ b/test/thread/futures/futures.unique_future/wait.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/wait_for.pass.cpp b/test/thread/futures/futures.unique_future/wait_for.pass.cpp
index 2a81a2c..0a381d9 100644
--- a/test/thread/futures/futures.unique_future/wait_for.pass.cpp
+++ b/test/thread/futures/futures.unique_future/wait_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/futures.unique_future/wait_until.pass.cpp b/test/thread/futures/futures.unique_future/wait_until.pass.cpp
index 8ac0bc8..70d7e57 100644
--- a/test/thread/futures/futures.unique_future/wait_until.pass.cpp
+++ b/test/thread/futures/futures.unique_future/wait_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/futures/version.pass.cpp b/test/thread/futures/version.pass.cpp
index 5ac4e0f..6730a14 100644
--- a/test/thread/futures/version.pass.cpp
+++ b/test/thread/futures/version.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <future>
 
diff --git a/test/thread/macro.pass.cpp b/test/thread/macro.pass.cpp
index 243640d..c1b1377 100644
--- a/test/thread/macro.pass.cpp
+++ b/test/thread/macro.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.condition/cv_status.pass.cpp b/test/thread/thread.condition/cv_status.pass.cpp
index d5e0947..fe5fa05 100644
--- a/test/thread/thread.condition/cv_status.pass.cpp
+++ b/test/thread/thread.condition/cv_status.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/notify_all_at_thread_exit.pass.cpp b/test/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
index e4f193a..2b8772f 100644
--- a/test/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
+++ b/test/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/default.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/default.pass.cpp
index a912413..6f43564 100644
--- a/test/thread/thread.condition/thread.condition.condvar/default.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp
index 9828fbb..437ed96 100644
--- a/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
index 52b73c0..bf28e01 100644
--- a/test/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp
index 0b50e26..fd80ee9 100644
--- a/test/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
index c112585..6236a13 100644
--- a/test/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/wait.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/wait.pass.cpp
index c4afc53..236eecc 100644
--- a/test/thread/thread.condition/thread.condition.condvar/wait.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/wait.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
index 038c946..ca48eee 100644
--- a/test/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp
index ef7a9b6..0ee40d1 100644
--- a/test/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp
index 22b82d2..45e0b81 100644
--- a/test/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp
index 476cec5..d87a188 100644
--- a/test/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp b/test/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp
index b7a4b3a..90ffb1d 100644
--- a/test/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/default.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
index 853fc1a..210060a 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp
index a14c568..6bdca7b 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp
index 389d4bc..27ead95 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
index 8ad0ca3..98f6c43 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp
index dd4879d..522c61b 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp
@@ -1,3 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
 #include <thread>
 #include <condition_variable>
 #include <mutex>
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp
index b611167..f5c8926 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp
index 7eb4b33..1906b58 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp
@@ -1,3 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
 #include <thread>
 #include <condition_variable>
 #include <mutex>
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp
index 89759ac..a4b4ed9 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp
index bc4b7c3..b240307 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp
index 9b4fab3..921ad69 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp
index 15bf809..1994ebd 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp b/test/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp
index 1490e11..c0fea03 100644
--- a/test/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp
+++ b/test/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.condition/version.pass.cpp b/test/thread/thread.condition/version.pass.cpp
index 517c93b..12a775e 100644
--- a/test/thread/thread.condition/version.pass.cpp
+++ b/test/thread/thread.condition/version.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <condition_variable>
 
diff --git a/test/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp b/test/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
index 14c79a1..f67ca21 100644
--- a/test/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp b/test/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
index bdb76c6..f0c54b7 100644
--- a/test/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
index 6f68884..8327100 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
index d47222d..a15405f 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
index 20aa62e..5238ed6 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
index 2713680..2c1c665 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
index 73936b7..8676f2c 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp
index cf63861..f59d2e8 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
index 01bfbfd..c8a0287 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
index b4f6025..9082e57 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp
index 3a8b61a..bbc38fc 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
index ffe329c..9816e57 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
index baf08de..5d188ab 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
index 9d06d3f..f2d4e0d 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
index ecac479..f150065 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
index d65fbfa..82b1ff8 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
index d076e52..5867465 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
index 8efffc4..9d38983 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
index 9e4b3c8..eb08a45 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
index 6a7a39e..8505763 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
index 03bf5e8..057dbc4 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
index a836b35..65ddca6 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
index 4b4f6c6..4eb75d8 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
index 177a69e..d079d2d 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
index a10c588..d64b0aa 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
index 3537357..c153b45 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
index 55038c7..a49bc50 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
index 2eb1c3a..4dff853 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
index f36600c..aa640ee 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
index 4b08aca..1f7217a 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
index ff8043b..9c3a7b6 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
index f475ec1..bf62231 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
index 8370c56..33e400b 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
index 8faf88f..2ead670 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
index b6c64f5..cea58c5 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
index c101d89..f5408df 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
index 40d9489..bd88577 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
index 3e7d13a..558f079 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
index 2b435e0..24e4d10 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
index 1318c86..bbabfc4 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
index fd3931a..598d53a 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
index d74247e..3fc8c28 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
index 4252de1..89c28e6 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
index 78b0c6a..bc1e3e5 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
index 0d2e362..7004ac0 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
index 2e2db5d..f53af35 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp b/test/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp
index aba22a7..f8bcb6d 100644
--- a/test/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.lock/types.pass.cpp b/test/thread/thread.mutex/thread.lock/types.pass.cpp
index 8a34bcb..64df068 100644
--- a/test/thread/thread.mutex/thread.lock/types.pass.cpp
+++ b/test/thread/thread.mutex/thread.lock/types.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp
index 704d716..4de42fb 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp
index 8fde818..ba2d54d 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
index 59c762a..12c80f0 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp
index 6ef0160..fe8f351 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp
index bc775ed..8c5d266 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp
index cd48151..abebe90 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
index fb95294..10626bc 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp
index f63e0ef..ff546d4 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
index f45382d..a90b6c9 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
index 153ce62..b4f9ba3 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
index 724a7b0..ac5e206 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
index aa6f5fb..33b0696 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
index e97b313..98cd8f9 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
index a34633e..a006e17 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
index 528c69a..b2cc15e 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
index a6238e3..d1b1121 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
index 8670fbf..5a8e624 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <shared_mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp
index 5956540..33320a7 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp
index a4b41ac..fe2dd82 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp
index d5a06bf..b32a266 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp
index 5e4d5f1..46222a7 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp
index f19dec2..6c9c442 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp
index a4c5110..56e1874 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp
index 32bedb3..91f747b 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp
index d56e8bc..63c3cfe 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp
index 972fc63..3c1d6dd 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp
index e5e9166..066eb7b 100644
--- a/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp
+++ b/test/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
diff --git a/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
index b4f76b4..5395c85 100644
--- a/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
+++ b/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <mutex>
 
@@ -133,7 +135,15 @@
 
 class MoveOnly
 {
+#if !defined(__clang__)
+   // GCC 4.8 complains about the following being private
+public:
+    MoveOnly(const MoveOnly&)
+    {
+    }
+#else
     MoveOnly(const MoveOnly&);
+#endif
 public:
     MoveOnly() {}
     MoveOnly(MoveOnly&&) {}
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
index 9a7f8dc..476ca0c 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
index 1a5f320..94a30e7 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
@@ -14,8 +16,6 @@
 // thread& operator=(thread&& t);
 
 #include <thread>
-#include <new>
-#include <cstdlib>
 #include <cassert>
 
 class G
@@ -29,13 +29,6 @@
     G(const G& g) : alive_(g.alive_) {++n_alive;}
     ~G() {alive_ = 0; --n_alive;}
 
-    void operator()()
-    {
-        assert(alive_ == 1);
-        assert(n_alive >= 1);
-        op_run = true;
-    }
-
     void operator()(int i, double j)
     {
         assert(alive_ == 1);
@@ -49,15 +42,9 @@
 int G::n_alive = 0;
 bool G::op_run = false;
 
-void f1()
-{
-    std::exit(0);
-}
-
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    std::set_terminate(f1);
     {
         assert(G::n_alive == 0);
         assert(!G::op_run);
@@ -71,12 +58,5 @@
         assert(G::n_alive == 0);
         assert(G::op_run);
     }
-    {
-        std::thread t0(G(), 5, 5.5);
-        std::thread::id id = t0.get_id();
-        std::thread t1;
-        t0 = std::move(t1);
-        assert(false);
-    }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
new file mode 100644
index 0000000..8cb2cb1
--- /dev/null
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// NOTE: std::terminate is called so the destructors are not invoked and the
+// memory is not freed. This will cause ASAN to fail.
+// XFAIL: asan
+
+// <thread>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#include <thread>
+#include <exception>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+    int alive_;
+public:
+    static int n_alive;
+    static bool op_run;
+
+    G() : alive_(1) {++n_alive;}
+    G(const G& g) : alive_(g.alive_) {++n_alive;}
+    ~G() {alive_ = 0; --n_alive;}
+
+    void operator()()
+    {
+        assert(alive_ == 1);
+        assert(n_alive >= 1);
+        op_run = true;
+    }
+
+    void operator()(int i, double j)
+    {
+        assert(alive_ == 1);
+        assert(n_alive >= 1);
+        assert(i == 5);
+        assert(j == 5.5);
+        op_run = true;
+    }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+void f1()
+{
+    std::exit(0);
+}
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    std::set_terminate(f1);
+    {
+        std::thread t0(G(), 5, 5.5);
+        std::thread::id id = t0.get_id();
+        std::thread t1;
+        t0 = std::move(t1);
+        assert(false);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
index e5568ba..0f5d5aa 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
@@ -13,6 +15,8 @@
 
 // template <class F, class ...Args> thread(F&& f, Args&&... args);
 
+// UNSUPPORTED: asan, msan
+
 #include <thread>
 #include <new>
 #include <cstdlib>
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp
index cd9c2c4..64d5a93 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
index 17268ab..36e0fbd 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
index e068c04..20c8da1 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp
index b8727d0..585f7ea 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp
index 6d17dfc..e8c3801 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp
index b315473..0037deb 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
index 2ff273c..6dd4c3e 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
index 099781f..de52b1d 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
index 54fc739..126965f 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp
index d407dfc..bb7f2aa 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <functional>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
index dbb98b5..5a31232 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
index 6af4f3b..a5ea55a 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
index 32faef4..2559303 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
index 9c90eb7..351c1cf 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
index 1aae922..37c2d9c 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
index 820091e..e8dede1 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp b/test/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp
index 256edc2..4d1ffad 100644
--- a/test/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.class/types.pass.cpp b/test/thread/thread.threads/thread.thread.class/types.pass.cpp
index e5094f7..a5bf770 100644
--- a/test/thread/thread.threads/thread.thread.class/types.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.class/types.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.this/get_id.pass.cpp b/test/thread/thread.threads/thread.thread.this/get_id.pass.cpp
index ef6615b..3b4b782 100644
--- a/test/thread/thread.threads/thread.thread.this/get_id.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.this/get_id.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp b/test/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
index f66b962..bffb5f3 100644
--- a/test/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp b/test/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
index 2f3bb9a..9f3941b 100644
--- a/test/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/thread.thread.this/yield.pass.cpp b/test/thread/thread.threads/thread.thread.this/yield.pass.cpp
index 52f53a6..daf5b0c 100644
--- a/test/thread/thread.threads/thread.thread.this/yield.pass.cpp
+++ b/test/thread/thread.threads/thread.thread.this/yield.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/thread/thread.threads/version.pass.cpp b/test/thread/thread.threads/version.pass.cpp
index 6d272c7..d16b0eb 100644
--- a/test/thread/thread.threads/version.pass.cpp
+++ b/test/thread/thread.threads/version.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <thread>
 
diff --git a/test/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp b/test/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp
index 537fb90..dbfaa97 100644
--- a/test/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp
+++ b/test/utilities/allocator.adaptor/allocator.adaptor.types/allocator_pointers.pass.cpp
@@ -103,13 +103,13 @@
 
 int main()
 {
-	test_pointer<std::scoped_allocator_adaptor<std::allocator<char>>> ();
-	test_pointer<std::scoped_allocator_adaptor<std::allocator<int>>> ();
-	test_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> ();
+    test_pointer<std::scoped_allocator_adaptor<std::allocator<char>>> ();
+    test_pointer<std::scoped_allocator_adaptor<std::allocator<int>>> ();
+    test_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> ();
 
-	test_void_pointer<std::scoped_allocator_adaptor<std::allocator<char>>> ();
-	test_void_pointer<std::scoped_allocator_adaptor<std::allocator<int>>> ();
-	test_void_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> ();	
+    test_void_pointer<std::scoped_allocator_adaptor<std::allocator<char>>> ();
+    test_void_pointer<std::scoped_allocator_adaptor<std::allocator<int>>> ();
+    test_void_pointer<std::scoped_allocator_adaptor<std::allocator<Foo>>> ();   
 }
 #else
 int main() {}
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
index 44252b4..b8995bf 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.alg/swap.pass.cpp
@@ -14,6 +14,8 @@
 // template <MoveConstructible  R, MoveConstructible ... ArgTypes>
 //   void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
index 92f99cd..3a43be7 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
@@ -13,6 +13,8 @@
 
 // function(nullptr_t);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
index de16998..ba65cd3 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
@@ -16,6 +16,8 @@
 //         && Convertible<Callable<F, ArgTypes...>::result_type
 //   operator=(F f);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
index f758a4d..38e65fc 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
@@ -13,6 +13,8 @@
 
 // template<class A> function(allocator_arg_t, const A&, const function&);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
index 570c27e..2180b89 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
@@ -13,6 +13,8 @@
 
 // template<class A> function(allocator_arg_t, const A&, function&&);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <cassert>
 
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp
index cf7b963..2fbd7cf 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy.pass.cpp
@@ -13,6 +13,8 @@
 
 // function(const function& f);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
index 544ec43..cfa79e2 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/copy_assign.pass.cpp
@@ -13,6 +13,8 @@
 
 // function& operator=(const function& f);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp
index 12a2b6e..b8c597b 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/nullptr_t_assign.pass.cpp
@@ -13,6 +13,8 @@
 
 // function& operator=(nullptr_t);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
index dc56574..3c012d1 100644
--- a/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
+++ b/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp
@@ -13,6 +13,8 @@
 
 // void swap(function& other);
 
+// UNSUPPORTED: asan, msan
+
 #include <functional>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp b/test/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp
index 5a95097..4033e67 100644
--- a/test/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp
+++ b/test/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp
@@ -35,9 +35,9 @@
     unary_counting_predicate<bool(*)(int), int> cp(is5);
     assert(!cp(6));
     assert(cp.count() == 1);
-	assert(call_pred(cp));
+    assert(call_pred(cp));
     assert(cp.count() == 1);
-	assert(call_pred(std::ref(cp)));
+    assert(call_pred(std::ref(cp)));
     assert(cp.count() == 2);
-	}
+    }
 }
diff --git a/test/utilities/function.objects/refwrap/type_properties.pass.cpp b/test/utilities/function.objects/refwrap/type_properties.pass.cpp
new file mode 100644
index 0000000..61e0bfa
--- /dev/null
+++ b/test/utilities/function.objects/refwrap/type_properties.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// reference_wrapper
+
+// Test that reference wrapper meets the requirements of TriviallyCopyable,
+// CopyConstructible and CopyAssignable.
+
+#include <functional>
+#include <type_traits>
+#include <string>
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+class MoveOnly
+{
+    MoveOnly(const MoveOnly&);
+    MoveOnly& operator=(const MoveOnly&);
+
+    int data_;
+public:
+    MoveOnly(int data = 1) : data_(data) {}
+    MoveOnly(MoveOnly&& x)
+        : data_(x.data_) {x.data_ = 0;}
+    MoveOnly& operator=(MoveOnly&& x)
+        {data_ = x.data_; x.data_ = 0; return *this;}
+
+    int get() const {return data_;}
+};
+#endif
+
+
+template <class T>
+void test()
+{
+    typedef std::reference_wrapper<T> Wrap;
+    static_assert(std::is_copy_constructible<Wrap>::value, "");
+    static_assert(std::is_copy_assignable<Wrap>::value, "");
+    // Extension up for standardization: See N4151.
+    static_assert(std::is_trivially_copyable<Wrap>::value, "");
+}
+
+int main()
+{
+    test<int>();
+    test<double>();
+    test<std::string>(); 
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    test<MoveOnly>(); 
+#endif
+}
diff --git a/test/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp b/test/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
index f881805..a4a84e8 100644
--- a/test/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
+++ b/test/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp
@@ -12,6 +12,8 @@
 // allocator:
 // pointer allocate(size_type n, allocator<void>::const_pointer hint=0);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp b/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
index 7e1500b..b9a1749 100644
--- a/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
+++ b/test/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
@@ -12,6 +12,8 @@
 // allocator:
 // template <class... Args> void construct(pointer p, Args&&... args);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/memory/default.allocator/allocator_pointers.pass.cpp b/test/utilities/memory/default.allocator/allocator_pointers.pass.cpp
index b894e45..5a8f7a2 100644
--- a/test/utilities/memory/default.allocator/allocator_pointers.pass.cpp
+++ b/test/utilities/memory/default.allocator/allocator_pointers.pass.cpp
@@ -103,13 +103,13 @@
 
 int main()
 {
-	test_pointer<std::allocator<char>> ();
-	test_pointer<std::allocator<int>> ();
-	test_pointer<std::allocator<Foo>> ();	
+    test_pointer<std::allocator<char>> ();
+    test_pointer<std::allocator<int>> ();
+    test_pointer<std::allocator<Foo>> ();   
 
-	test_void_pointer<std::allocator<char>> ();
-	test_void_pointer<std::allocator<int>> ();
-	test_void_pointer<std::allocator<Foo>> ();	
+    test_void_pointer<std::allocator<char>> ();
+    test_void_pointer<std::allocator<int>> ();
+    test_void_pointer<std::allocator<Foo>> ();  
 }
 #else
 int main() {}
diff --git a/test/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp b/test/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
index 00a08bc..95350a6 100644
--- a/test/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
+++ b/test/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
@@ -15,12 +15,15 @@
 
 // default unique_ptr ctor should require default Deleter ctor
 
+// USE_VERIFY
+
 #include <memory>
 
 class Deleter
 {
-
-    Deleter() {}
+    // expected-error@memory:* {{base class 'Deleter' has private default constructor}}
+    // expected-note@memory:* + {{in instantiation of member function}}
+    Deleter() {} // expected-note {{implicitly declared private here}}
 
 public:
 
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp
index 0c80324..cd79fdb 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp
index 9f93ae8..2fd9d5a 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_strong_explicit.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp
index 1c274d1..5c082cc 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp
index 7741223..f53f442 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_compare_exchange_weak_explicit.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp
index 6e6f635..fc4c47a 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp
index f6a2085..19482dc 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_exchange_explicit.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp
index 0420734..e3ac84a 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_is_lock_free.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
 
 // <memory>
 
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp
index 49fd1b6..566e95a 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp
index 94d0615..b423604 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_load_explicit.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp
index 83ee45f..f65f3eb 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp
index 2b3bb8b..6864200 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared.atomic/atomic_store_explicit.pass.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
+// UNSUPPORTED: libcpp-has-no-threads
+//
 // This test uses new symbols that were not defined in the libc++ shipped on
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h b/test/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h
index 7af7468..0263061 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/test_deleter.h
@@ -19,6 +19,12 @@
 #include <type_traits>
 #include <cassert>
 
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define DELETE_FUNCTION = delete
+#else
+#define DELETE_FUNCTION { assert(false); }
+#endif
+
 struct test_deleter_base
 {
     static int count;
@@ -46,6 +52,8 @@
     void set_state(int i) {state_ = i;}
 
     void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;}
+   
+    test_deleter* operator&() const DELETE_FUNCTION;
 };
 
 template <class T>
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp
index 27046cf..28e49d6 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp
@@ -11,6 +11,8 @@
 
 // template<class Y> explicit shared_ptr(auto_ptr<Y>&& r);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
index 7966e00..b67f31e 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../test_deleter.h"
 #include "test_allocator.h"
+#include "min_allocator.h"
 
 struct A
 {
@@ -47,4 +48,38 @@
     assert(test_deleter<A>::dealloc_count == 1);
     assert(test_allocator<A>::count == 0);
     assert(test_allocator<A>::alloc_count == 0);
+    test_deleter<A>::dealloc_count = 0;
+    // Test an allocator with a minimal interface
+    {
+    std::shared_ptr<A> p(nullptr, test_deleter<A>(1), bare_allocator<void>());
+    assert(A::count == 0);
+    assert(p.use_count() == 1);
+    assert(p.get() == 0);
+    test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
+    assert(test_deleter<A>::count ==1);
+    assert(test_deleter<A>::dealloc_count == 0);
+    assert(d);
+    assert(d->state() == 1);
+    }
+    assert(A::count == 0);
+    assert(test_deleter<A>::count == 0);
+    assert(test_deleter<A>::dealloc_count == 1);
+    test_deleter<A>::dealloc_count = 0;
+#if __cplusplus >= 201103L
+    // Test an allocator that returns class-type pointers
+    {
+    std::shared_ptr<A> p(nullptr, test_deleter<A>(1), min_allocator<void>());
+    assert(A::count == 0);
+    assert(p.use_count() == 1);
+    assert(p.get() == 0);
+    test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
+    assert(test_deleter<A>::count ==1);
+    assert(test_deleter<A>::dealloc_count == 0);
+    assert(d);
+    assert(d->state() == 1);
+    }
+    assert(A::count == 0);
+    assert(test_deleter<A>::count == 0);
+    assert(test_deleter<A>::dealloc_count == 1);
+#endif
 }
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
index e8365ae..a8588cc 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
@@ -13,6 +13,8 @@
 
 // template<class D> shared_ptr(nullptr_t, D d);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <cassert>
 #include <new>
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
index 23d3f10..1a9c09c 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../test_deleter.h"
 #include "test_allocator.h"
+#include "min_allocator.h"
 
 struct A
 {
@@ -27,6 +28,7 @@
 
 int A::count = 0;
 
+
 int main()
 {
     {
@@ -48,4 +50,40 @@
     assert(test_deleter<A>::dealloc_count == 1);
     assert(test_allocator<A>::count == 0);
     assert(test_allocator<A>::alloc_count == 0);
+    test_deleter<A>::dealloc_count = 0;
+    // Test an allocator with a minimal interface
+    {
+    A* ptr = new A;
+    std::shared_ptr<A> p(ptr, test_deleter<A>(3), bare_allocator<void>());
+    assert(A::count == 1);
+    assert(p.use_count() == 1);
+    assert(p.get() == ptr);
+    test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
+    assert(test_deleter<A>::count == 1);
+    assert(test_deleter<A>::dealloc_count == 0);
+    assert(d);
+    assert(d->state() == 3);
+    }
+    assert(A::count == 0);
+    assert(test_deleter<A>::count == 0);
+    assert(test_deleter<A>::dealloc_count == 1);
+    test_deleter<A>::dealloc_count = 0;
+#if __cplusplus >= 201103L
+    // Test an allocator that returns class-type pointers
+    {
+    A* ptr = new A;
+    std::shared_ptr<A> p(ptr, test_deleter<A>(3), min_allocator<void>());
+    assert(A::count == 1);
+    assert(p.use_count() == 1);
+    assert(p.get() == ptr);
+    test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
+    assert(test_deleter<A>::count == 1);
+    assert(test_deleter<A>::dealloc_count == 0);
+    assert(d);
+    assert(d->state() == 3);
+    }
+    assert(A::count == 0);
+    assert(test_deleter<A>::count == 0);
+    assert(test_deleter<A>::dealloc_count == 1);
+#endif
 }
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
index 79aaa58..b024f7e 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
@@ -13,6 +13,8 @@
 
 // template<class Y, class D> shared_ptr(Y* p, D d);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <cassert>
 #include <new>
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
index d50d91c..28fb8bf 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
@@ -11,6 +11,8 @@
 
 // template<class Y> explicit shared_ptr(Y* p);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
index b841833..dc2a6af 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
@@ -11,6 +11,8 @@
 
 // template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <new>
 #include <cstdlib>
@@ -53,6 +55,9 @@
 
 int A::count = 0;
 
+void fn ( const std::shared_ptr<int> &) {}
+void fn ( const std::shared_ptr<B> &) { assert (false); }
+
 int main()
 {
     {
@@ -89,4 +94,10 @@
     }
     }
     assert(A::count == 0);
+
+    // LWG 2399
+    {
+    throw_next = false;
+    fn(std::unique_ptr<int>(new int));
+    }
 }
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
index e019837..aa77dab 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.pass.cpp
@@ -19,6 +19,7 @@
 #include <cstdlib>
 #include <cassert>
 #include "test_allocator.h"
+#include "min_allocator.h"
 
 int new_count = 0;
 
@@ -54,4 +55,24 @@
     }
     assert(A::count == 0);
     assert(test_allocator<A>::alloc_count == 0);
+#if __cplusplus >= 201103L
+    {
+    int i = 67;
+    char c = 'e';
+    std::shared_ptr<A> p = std::allocate_shared<A>(min_allocator<void>(), i, c);
+    assert(A::count == 1);
+    assert(p->get_int() == 67);
+    assert(p->get_char() == 'e');
+    }
+    assert(A::count == 0);
+    {
+    int i = 68;
+    char c = 'f';
+    std::shared_ptr<A> p = std::allocate_shared<A>(bare_allocator<void>(), i, c);
+    assert(A::count == 1);
+    assert(p->get_int() == 68);
+    assert(p->get_char() == 'f');
+    }
+    assert(A::count == 0);
+#endif
 }
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
new file mode 100644
index 0000000..8dcd50e
--- /dev/null
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_no_variadics.pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// shared_ptr
+
+// template<class T, class A, class... Args>
+//    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
+
+#define _LIBCPP_HAS_NO_VARIADICS
+#include <memory>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+struct Zero
+{
+    static int count;
+    Zero() {++count;}
+    Zero(Zero const &) {++count;}
+    ~Zero() {--count;}
+};
+
+int Zero::count = 0;
+
+struct One
+{
+    static int count;
+    int value;
+    explicit One(int v) : value(v) {++count;}
+    One(One const & o) : value(o.value) {++count;}
+    ~One() {--count;}
+};
+
+int One::count = 0;
+
+
+struct Two
+{
+    static int count;
+    int value;
+    Two(int v, int) : value(v) {++count;}
+    Two(Two const & o) : value(o.value) {++count;}
+    ~Two() {--count;}
+};
+
+int Two::count = 0;
+
+struct Three
+{
+    static int count;
+    int value;
+    Three(int v, int, int) : value(v) {++count;}
+    Three(Three const & o) : value(o.value) {++count;}
+    ~Three() {--count;}
+};
+
+int Three::count = 0;
+
+template <class Alloc>
+void test()
+{
+    int const bad = -1;
+    {
+    std::shared_ptr<Zero> p = std::allocate_shared<Zero>(Alloc());
+    assert(Zero::count == 1);
+    }
+    assert(Zero::count == 0);
+    {
+    int const i = 42;
+    std::shared_ptr<One> p = std::allocate_shared<One>(Alloc(), i);
+    assert(One::count == 1);
+    assert(p->value == i);
+    }
+    assert(One::count == 0);
+    {
+    int const i = 42;
+    std::shared_ptr<Two> p = std::allocate_shared<Two>(Alloc(), i, bad);
+    assert(Two::count == 1);
+    assert(p->value == i);
+    }
+    assert(Two::count == 0);
+    {
+    int const i = 42;
+    std::shared_ptr<Three> p = std::allocate_shared<Three>(Alloc(), i, bad, bad);
+    assert(Three::count == 1);
+    assert(p->value == i);
+    }
+    assert(Three::count == 0);
+}
+
+int main()
+{
+    {
+    int i = 67;
+    int const bad = -1;
+    std::shared_ptr<Two> p = std::allocate_shared<Two>(test_allocator<Two>(54), i, bad);
+    assert(test_allocator<Two>::alloc_count == 1);
+    assert(Two::count == 1);
+    assert(p->value == 67);
+    }
+    assert(Two::count == 0);
+    assert(test_allocator<Two>::alloc_count == 0);
+
+    test<bare_allocator<void> >();
+#if __cplusplus >= 201103L
+    test<min_allocator<void> >();
+#endif
+}
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
index eda148c..30a4984 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
@@ -13,6 +13,8 @@
 
 // template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
 
+// UNSUPPORTED: asan, msan
+
 #include <memory>
 #include <new>
 #include <cstdlib>
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp
index 1fdf883..75bf3df 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr.pass.cpp
@@ -55,8 +55,10 @@
 template <class T>
 std::weak_ptr<T> source (std::shared_ptr<T> p) { return std::weak_ptr<T>(p); }
 
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 template <class T>
 void sink (std::weak_ptr<T> &&) {}
+#endif
 
 int main()
 {
@@ -98,6 +100,7 @@
     assert(B::count == 0);
     assert(A::count == 0);
 
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     {
         std::shared_ptr<A> ps(new A);
         std::weak_ptr<A> pA = source(ps);
@@ -107,4 +110,5 @@
     }
     assert(B::count == 0);
     assert(A::count == 0);
+#endif
 }
diff --git a/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp b/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp
index 70ad11b..51a8fa5 100644
--- a/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp
+++ b/test/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/weak_ptr_Y.pass.cpp
@@ -55,9 +55,6 @@
 template <class T>
 std::weak_ptr<T> source (std::shared_ptr<T> p) { return std::weak_ptr<T>(p); }
 
-template <class T>
-void sink (std::weak_ptr<T> &&) {}
-
 int main()
 {
     static_assert(( std::is_convertible<std::weak_ptr<A>, std::weak_ptr<B> >::value), "");
diff --git a/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp b/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
index 01a2f65..6ea1cac 100644
--- a/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
+++ b/test/utilities/meta/meta.unary.prop.query/alignment_of.pass.cpp
@@ -39,7 +39,7 @@
     test_alignment_of<int, 4>();
     test_alignment_of<double, 8>();
 #if (defined(__ppc__) && !defined(__ppc64__))
-    test_alignment_of<bool, 4>();	// 32-bit PPC has four byte bool
+    test_alignment_of<bool, 4>();   // 32-bit PPC has four byte bool
 #else
     test_alignment_of<bool, 1>();
 #endif
diff --git a/test/utilities/meta/meta.unary.prop.query/void_t.pass.cpp b/test/utilities/meta/meta.unary.prop.query/void_t.pass.cpp
new file mode 100644
index 0000000..1f99a74
--- /dev/null
+++ b/test/utilities/meta/meta.unary.prop.query/void_t.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// void_t
+
+#include <type_traits>
+
+#if _LIBCPP_STD_VER <= 14
+int main () {}
+#else
+
+template <class T>
+void test1()
+{
+    static_assert( std::is_same<void, std::void_t<T>>::value, "");
+    static_assert( std::is_same<void, std::void_t<const T>>::value, "");
+    static_assert( std::is_same<void, std::void_t<volatile T>>::value, "");
+    static_assert( std::is_same<void, std::void_t<const volatile T>>::value, "");
+}
+
+template <class T, class U>
+void test2()
+{
+    static_assert( std::is_same<void, std::void_t<T, U>>::value, "");
+    static_assert( std::is_same<void, std::void_t<const T, U>>::value, "");
+    static_assert( std::is_same<void, std::void_t<volatile T, U>>::value, "");
+    static_assert( std::is_same<void, std::void_t<const volatile T, U>>::value, "");
+
+    static_assert( std::is_same<void, std::void_t<T, const U>>::value, "");
+    static_assert( std::is_same<void, std::void_t<const T, const U>>::value, "");
+    static_assert( std::is_same<void, std::void_t<volatile T, const U>>::value, "");
+    static_assert( std::is_same<void, std::void_t<const volatile T, const U>>::value, "");
+}
+
+class Class
+{
+public:
+    ~Class();
+};
+
+int main()
+{
+    static_assert( std::is_same<void, std::void_t<>>::value, "");
+
+	test1<void>();
+	test1<int>();
+	test1<double>();
+	test1<int&>();
+	test1<Class>();
+	test1<Class[]>();
+	test1<Class[5]>();
+	
+	test2<void, int>();
+	test2<double, int>();
+	test2<int&, int>();
+	test2<Class&, bool>();
+	test2<void *, int&>();
+
+    static_assert( std::is_same<void, std::void_t<int, double const &, Class, volatile int[], void>>::value, "");
+}
+#endif
diff --git a/test/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp
index d619701..691e353 100644
--- a/test/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.cat/nullptr.pass.cpp
@@ -10,7 +10,7 @@
 // type_traits
 
 // nullptr_t
-//	is_null_pointer
+//  is_null_pointer
 
 #include <type_traits>
 
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp
index de27b98..1c715e0 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/__has_operator_addressof.pass.cpp
@@ -40,6 +40,20 @@
     constexpr C operator&() const;
 };
 
+struct F {};
+constexpr F* operator&(F const &) { return nullptr; }
+
+struct G {};
+constexpr G* operator&(G &&) { return nullptr; }
+
+struct H {};
+constexpr H* operator&(H const &&) { return nullptr; }
+
+struct J
+{
+    constexpr J* operator&() const &&;
+};
+
 #endif  // _LIBCPP_HAS_NO_CONSTEXPR
 
 int main()
@@ -49,5 +63,9 @@
     static_assert(std::__has_operator_addressof<A>::value == false, "");
     static_assert(std::__has_operator_addressof<B>::value == true, "");
     static_assert(std::__has_operator_addressof<E>::value == true, "");
+    static_assert(std::__has_operator_addressof<F>::value == true, "");
+    static_assert(std::__has_operator_addressof<G>::value == true, "");
+    static_assert(std::__has_operator_addressof<H>::value == true, "");
+    static_assert(std::__has_operator_addressof<J>::value == true, "");
 #endif  // _LIBCPP_HAS_NO_CONSTEXPR
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp
index 92fd336..685d30d 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/has_virtual_destructor.pass.cpp
@@ -69,7 +69,7 @@
     test_has_not_virtual_destructor<int*>();
     test_has_not_virtual_destructor<const int*>();
     test_has_not_virtual_destructor<char[3]>();
-    test_has_not_virtual_destructor<char[3]>();
+    test_has_not_virtual_destructor<char[]>();
     test_has_not_virtual_destructor<bit_zero>();
 
     test_has_virtual_destructor<Abstract>();
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp
index cba575f..f2a8c23 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_abstract.pass.cpp
@@ -61,7 +61,7 @@
     test_is_not_abstract<int*>();
     test_is_not_abstract<const int*>();
     test_is_not_abstract<char[3]>();
-    test_is_not_abstract<char[3]>();
+    test_is_not_abstract<char[]>();
     test_is_not_abstract<Union>();
     test_is_not_abstract<Empty>();
     test_is_not_abstract<bit_zero>();
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp
index 3285765..72f2ff4 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_const.pass.cpp
@@ -30,7 +30,7 @@
     test_is_const<int*>();
     test_is_const<const int*>();
     test_is_const<char[3]>();
-    test_is_const<char[3]>();
+    test_is_const<char[]>();
 
     static_assert(!std::is_const<int&>::value, "");
     static_assert(!std::is_const<const int&>::value, "");
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp
index bde44de..c43d594 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_assignable.pass.cpp
@@ -52,6 +52,11 @@
     B& operator=(const B&);
 };
 
+struct C
+{
+    void operator=(C&);  // not const
+};
+
 int main()
 {
     test_is_copy_assignable<int> ();
@@ -71,4 +76,5 @@
     test_is_not_copy_assignable<B> ();
 #endif
     test_is_not_copy_assignable<void> ();
+    test_is_not_copy_assignable<C> ();
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp
index 837d0b0..f878a50 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_copy_constructible.pass.cpp
@@ -58,6 +58,12 @@
     B(const B&);
 };
 
+struct C
+{
+    C(C&);  // not const
+    void operator=(C&);  // not const
+};
+
 int main()
 {
     test_is_copy_constructible<A>();
@@ -75,6 +81,7 @@
     test_is_not_copy_constructible<char[]>();
     test_is_not_copy_constructible<void>();
     test_is_not_copy_constructible<Abstract>();
+    test_is_not_copy_constructible<C>();
 #if __has_feature(cxx_access_control_sfinae) 
     test_is_not_copy_constructible<B>();
 #endif
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
index 584d2cc..47af3c4 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_empty.pass.cpp
@@ -56,7 +56,7 @@
     test_is_not_empty<int*>();
     test_is_not_empty<const int*>();
     test_is_not_empty<char[3]>();
-    test_is_not_empty<char[3]>();
+    test_is_not_empty<char[]>();
     test_is_not_empty<Union>();
     test_is_not_empty<NotEmpty>();
 
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
index 892ffd7..a89ee7d 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_move_assignable.pass.cpp
@@ -60,7 +60,6 @@
     test_is_not_move_assignable<const int> ();
     test_is_not_move_assignable<int[]> ();
     test_is_not_move_assignable<int[3]> ();
-    test_is_not_move_assignable<int[3]> ();
 #endif
     test_is_not_move_assignable<void> ();
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
index 3bd2b3b..8fff5f8 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_assignable.pass.cpp
@@ -34,6 +34,11 @@
     void operator=(A);
 };
 
+struct C
+{
+    void operator=(C&);  // not const
+};
+
 int main()
 {
     test_is_nothrow_assignable<int&, int&> ();
@@ -46,4 +51,5 @@
     test_is_not_nothrow_assignable<int, int> ();
     test_is_not_nothrow_assignable<B, A> ();
     test_is_not_nothrow_assignable<A, B> ();
+    test_is_not_nothrow_assignable<C, C&> ();
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
index 8978ec9..fe0b567 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_constructible.pass.cpp
@@ -70,14 +70,34 @@
     A(const A&);
 };
 
+struct C
+{
+    C(C&);  // not const
+    void operator=(C&);  // not const
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+struct Tuple {
+    Tuple(Empty&&) noexcept {}
+};
+#endif
+
 int main()
 {
     test_is_nothrow_constructible<int> ();
     test_is_nothrow_constructible<int, const int&> ();
     test_is_nothrow_constructible<Empty> ();
     test_is_nothrow_constructible<Empty, const Empty&> ();
-
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    test_is_nothrow_constructible<Tuple &&, Empty> (); // See bug #19616.
+#endif
+    
     test_is_not_nothrow_constructible<A, int> ();
     test_is_not_nothrow_constructible<A, int, double> ();
     test_is_not_nothrow_constructible<A> ();
+    test_is_not_nothrow_constructible<C> ();
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    static_assert(!std::is_constructible<Tuple&, Empty>::value, "");
+    test_is_not_nothrow_constructible<Tuple &, Empty> (); // See bug #19616.
+#endif
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp
index 7871732..8fd5bab 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp
@@ -23,7 +23,7 @@
 }
 
 template <class T>
-void test_has_not_nothrow_destructor()
+void test_is_not_nothrow_destructible()
 {
     static_assert(!std::is_nothrow_destructible<T>::value, "");
     static_assert(!std::is_nothrow_destructible<const T>::value, "");
@@ -64,9 +64,10 @@
 
 int main()
 {
-    test_has_not_nothrow_destructor<void>();
-    test_has_not_nothrow_destructor<AbstractDestructor>();
-    test_has_not_nothrow_destructor<NotEmpty>();
+    test_is_not_nothrow_destructible<void>();
+    test_is_not_nothrow_destructible<AbstractDestructor>();
+    test_is_not_nothrow_destructible<NotEmpty>();
+    test_is_not_nothrow_destructible<char[]>();
 
 #if __has_feature(cxx_noexcept)
     test_is_nothrow_destructible<A>();
@@ -83,7 +84,6 @@
     test_is_nothrow_destructible<int*>();
     test_is_nothrow_destructible<const int*>();
     test_is_nothrow_destructible<char[3]>();
-    test_is_nothrow_destructible<char[3]>();
     test_is_nothrow_destructible<Abstract>();
 #if __has_feature(cxx_noexcept)
     test_is_nothrow_destructible<bit_zero>();
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_pod.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_pod.pass.cpp
index a97685c..4ec1ae9 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_pod.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_pod.pass.cpp
@@ -48,5 +48,5 @@
     test_is_pod<int*>();
     test_is_pod<const int*>();
     test_is_pod<char[3]>();
-    test_is_pod<char[3]>();
+    test_is_pod<char[]>();
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp
index 8f5547e..6e82cdd 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_polymorphic.pass.cpp
@@ -69,7 +69,7 @@
     test_is_not_polymorphic<int*>();
     test_is_not_polymorphic<const int*>();
     test_is_not_polymorphic<char[3]>();
-    test_is_not_polymorphic<char[3]>();
+    test_is_not_polymorphic<char[]>();
     test_is_not_polymorphic<Union>();
     test_is_not_polymorphic<Empty>();
     test_is_not_polymorphic<bit_zero>();
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp
index 7de6566..479c252 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_signed.pass.cpp
@@ -45,7 +45,7 @@
     test_is_not_signed<int*>();
     test_is_not_signed<const int*>();
     test_is_not_signed<char[3]>();
-    test_is_not_signed<char[3]>();
+    test_is_not_signed<char[]>();
     test_is_not_signed<bool>();
     test_is_not_signed<unsigned>();
 
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp
index 984824a..735d05f 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_assignable.pass.cpp
@@ -34,6 +34,11 @@
     void operator=(A);
 };
 
+struct C
+{
+    void operator=(C&);  // not const
+};
+
 int main()
 {
     test_is_trivially_assignable<int&, int&> ();
@@ -44,4 +49,5 @@
     test_is_not_trivially_assignable<int, int> ();
     test_is_not_trivially_assignable<B, A> ();
     test_is_not_trivially_assignable<A, B> ();
+    test_is_not_trivially_assignable<C&, C&> ();
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_trivialially_copyable.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp
similarity index 100%
rename from test/utilities/meta/meta.unary/meta.unary.prop/is_trivialially_copyable.pass.cpp
rename to test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_copyable.pass.cpp
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp
index 1b34885..b18ace4 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp
@@ -23,7 +23,7 @@
 }
 
 template <class T>
-void test_has_not_trivial_destructor()
+void test_is_not_trivially_destructible()
 {
     static_assert(!std::is_trivially_destructible<T>::value, "");
     static_assert(!std::is_trivially_destructible<const T>::value, "");
@@ -64,10 +64,11 @@
 
 int main()
 {
-    test_has_not_trivial_destructor<void>();
-    test_has_not_trivial_destructor<A>();
-    test_has_not_trivial_destructor<AbstractDestructor>();
-    test_has_not_trivial_destructor<NotEmpty>();
+    test_is_not_trivially_destructible<void>();
+    test_is_not_trivially_destructible<A>();
+    test_is_not_trivially_destructible<AbstractDestructor>();
+    test_is_not_trivially_destructible<NotEmpty>();
+    test_is_not_trivially_destructible<char[]>();
 
     test_is_trivially_destructible<Abstract>();
     test_is_trivially_destructible<int&>();
@@ -78,6 +79,5 @@
     test_is_trivially_destructible<int*>();
     test_is_trivially_destructible<const int*>();
     test_is_trivially_destructible<char[3]>();
-    test_is_trivially_destructible<char[3]>();
     test_is_trivially_destructible<bit_zero>();
 }
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp
index 2cd4945..dfdb155 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_unsigned.pass.cpp
@@ -45,7 +45,7 @@
     test_is_not_unsigned<int*>();
     test_is_not_unsigned<const int*>();
     test_is_not_unsigned<char[3]>();
-    test_is_not_unsigned<char[3]>();
+    test_is_not_unsigned<char[]>();
     test_is_not_unsigned<int>();
     test_is_not_unsigned<double>();
 
diff --git a/test/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp b/test/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp
index 8e1fca4..f6805bc 100644
--- a/test/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp
+++ b/test/utilities/meta/meta.unary/meta.unary.prop/is_volatile.pass.cpp
@@ -30,7 +30,7 @@
     test_is_volatile<int*>();
     test_is_volatile<const int*>();
     test_is_volatile<char[3]>();
-    test_is_volatile<char[3]>();
+    test_is_volatile<char[]>();
 
     static_assert(!std::is_volatile<int&>::value, "");
     static_assert(!std::is_volatile<volatile int&>::value, "");
diff --git a/test/utilities/optional/optional.hash/hash.pass.cpp b/test/utilities/optional/optional.hash/hash.pass.cpp
index ca23d78..9e5fb55 100644
--- a/test/utilities/optional/optional.hash/hash.pass.cpp
+++ b/test/utilities/optional/optional.hash/hash.pass.cpp
@@ -20,7 +20,7 @@
 int main()
 {
 #if _LIBCPP_STD_VER > 11
-	using std::experimental::optional;
+    using std::experimental::optional;
 
     {
         typedef int T;
diff --git a/test/utilities/optional/optional.nullops/eqaul.pass.cpp b/test/utilities/optional/optional.nullops/eqaul.pass.cpp
index d137d30..54fb522 100644
--- a/test/utilities/optional/optional.nullops/eqaul.pass.cpp
+++ b/test/utilities/optional/optional.nullops/eqaul.pass.cpp
@@ -18,9 +18,9 @@
 int main()
 {
 #if _LIBCPP_STD_VER > 11
-	using std::experimental::optional;
-	using std::experimental::nullopt_t;
-	using std::experimental::nullopt;
+    using std::experimental::optional;
+    using std::experimental::nullopt_t;
+    using std::experimental::nullopt;
     
     {
     typedef int T;
diff --git a/test/utilities/optional/optional.nullops/less_than.pass.cpp b/test/utilities/optional/optional.nullops/less_than.pass.cpp
index 51c8e49..576a98a 100644
--- a/test/utilities/optional/optional.nullops/less_than.pass.cpp
+++ b/test/utilities/optional/optional.nullops/less_than.pass.cpp
@@ -18,9 +18,9 @@
 int main()
 {
 #if _LIBCPP_STD_VER > 11
-	using std::experimental::optional;
-	using std::experimental::nullopt_t;
-	using std::experimental::nullopt;
+    using std::experimental::optional;
+    using std::experimental::nullopt_t;
+    using std::experimental::nullopt;
 
     {
     typedef int T;
diff --git a/test/utilities/optional/optional.object/optional_const_void.fail.cpp b/test/utilities/optional/optional.object/optional_const_void.fail.cpp
index ccbcf2e..6999cf2 100644
--- a/test/utilities/optional/optional.object/optional_const_void.fail.cpp
+++ b/test/utilities/optional/optional.object/optional_const_void.fail.cpp
@@ -16,7 +16,7 @@
 int main()
 {
 #if _LIBCPP_STD_VER > 11
-	using std::experimental::optional;
+    using std::experimental::optional;
 
     optional<const void> opt;
 #else
diff --git a/test/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp b/test/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp
index bec6787..60c6461 100644
--- a/test/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp
+++ b/test/utilities/time/time.clock/time.clock.steady/consistency.pass.cpp
@@ -11,6 +11,7 @@
 // darwin11 and darwin12:
 // XFAIL: with_system_lib=x86_64-apple-darwin11
 // XFAIL: with_system_lib=x86_64-apple-darwin12
+// UNSUPPORTED: libcpp-has-no-monotonic-clock
 
 // <chrono>
 
diff --git a/test/utilities/time/time.clock/time.clock.steady/now.pass.cpp b/test/utilities/time/time.clock/time.clock.steady/now.pass.cpp
index 0c6ebe6..4b86d9e 100644
--- a/test/utilities/time/time.clock/time.clock.steady/now.pass.cpp
+++ b/test/utilities/time/time.clock/time.clock.steady/now.pass.cpp
@@ -6,6 +6,8 @@
 // Source Licenses. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-monotonic-clock
 
 // <chrono>
 
diff --git a/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
new file mode 100644
index 0000000..f62d2fe
--- /dev/null
+++ b/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class Tuple, __tuple_assignable<Tuple, tuple> >
+//   tuple & operator=(Tuple &&);
+
+// This test checks that we do not evaluate __make_tuple_types
+// on the array when it doesn't match the size of the tuple.
+
+#include <array>
+#include <tuple>
+
+// Use 1256 to try and blow the template instantiation depth for all compilers.
+typedef std::array<char, 1256> array_t;
+typedef std::tuple<array_t> tuple_t;
+
+int main()
+{
+    array_t arr;
+    tuple_t tup;
+    tup = arr;
+}
diff --git a/test/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp
index d6fbdae..3d8b194 100644
--- a/test/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp
+++ b/test/utilities/tuple/tuple.tuple/tuple.cnstr/UTypes.pass.cpp
@@ -16,6 +16,7 @@
 
 #include <tuple>
 #include <cassert>
+#include <type_traits>
 
 #include "../MoveOnly.h"
 
@@ -30,6 +31,71 @@
 
 #endif
 
+struct NoDefault { NoDefault() = delete; };
+
+// Make sure the _Up... constructor SFINAEs out when the types that
+// are not explicitly initialized are not all default constructible.
+// Otherwise, std::is_constructible would return true but instantiating
+// the constructor would fail.
+void test_default_constructible_extension_sfinae()
+{
+    {
+        typedef std::tuple<MoveOnly, NoDefault> Tuple;
+
+        static_assert(!std::is_constructible<
+            Tuple,
+            MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            Tuple,
+            MoveOnly, NoDefault
+        >::value, "");
+    }
+    {
+        typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
+
+        static_assert(!std::is_constructible<
+            Tuple,
+            MoveOnly, MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            Tuple,
+            MoveOnly, MoveOnly, NoDefault
+        >::value, "");
+    }
+    {
+        // Same idea as above but with a nested tuple type.
+        typedef std::tuple<MoveOnly, NoDefault> Tuple;
+        typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+        static_assert(!std::is_constructible<
+            NestedTuple,
+            MoveOnly, MoveOnly, MoveOnly, MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            NestedTuple,
+            MoveOnly, Tuple, MoveOnly, MoveOnly
+        >::value, "");
+    }
+    {
+        typedef std::tuple<MoveOnly, int> Tuple;
+        typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+        static_assert(std::is_constructible<
+            NestedTuple,
+            MoveOnly, MoveOnly, MoveOnly, MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            NestedTuple,
+            MoveOnly, Tuple, MoveOnly, MoveOnly
+        >::value, "");
+    }
+}
+
 int main()
 {
     {
@@ -72,4 +138,7 @@
         static_assert(std::get<0>(t).id_ == 3, "");
     }
 #endif
+    // Check that SFINAE is properly applied with the default reduced arity
+    // constructor extensions.
+    test_default_constructible_extension_sfinae();
 }
diff --git a/test/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp
index 667c4dd..00bc5e0 100644
--- a/test/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp
+++ b/test/utilities/tuple/tuple.tuple/tuple.cnstr/alloc_UTypes.pass.cpp
@@ -22,6 +22,71 @@
 #include "../alloc_first.h"
 #include "../alloc_last.h"
 
+struct NoDefault { NoDefault() = delete; };
+
+// Make sure the _Up... constructor SFINAEs out when the types that
+// are not explicitly initialized are not all default constructible.
+// Otherwise, std::is_constructible would return true but instantiating
+// the constructor would fail.
+void test_default_constructible_extension_sfinae()
+{
+    {
+        typedef std::tuple<MoveOnly, NoDefault> Tuple;
+
+        static_assert(!std::is_constructible<
+            Tuple,
+            std::allocator_arg_t, A1<int>, MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            Tuple,
+            std::allocator_arg_t, A1<int>, MoveOnly, NoDefault
+        >::value, "");
+    }
+    {
+        typedef std::tuple<MoveOnly, MoveOnly, NoDefault> Tuple;
+
+        static_assert(!std::is_constructible<
+            std::tuple<MoveOnly, MoveOnly, NoDefault>,
+            std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            std::tuple<MoveOnly, MoveOnly, NoDefault>,
+            std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, NoDefault
+        >::value, "");
+    }
+    {
+        // Same idea as above but with a nested tuple
+        typedef std::tuple<MoveOnly, NoDefault> Tuple;
+        typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+        static_assert(!std::is_constructible<
+            NestedTuple,
+            std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            NestedTuple,
+            std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly
+        >::value, "");
+    }
+    {
+        typedef std::tuple<MoveOnly, int> Tuple;
+        typedef std::tuple<MoveOnly, Tuple, MoveOnly, MoveOnly> NestedTuple;
+
+        static_assert(std::is_constructible<
+            NestedTuple,
+            std::allocator_arg_t, A1<int>, MoveOnly, MoveOnly, MoveOnly, MoveOnly
+        >::value, "");
+
+        static_assert(std::is_constructible<
+            NestedTuple,
+            std::allocator_arg_t, A1<int>, MoveOnly, Tuple, MoveOnly, MoveOnly
+        >::value, "");
+    }
+}
+
 int main()
 {
     {
@@ -68,4 +133,7 @@
         assert(std::get<1>(t) == MoveOnly());
         assert(std::get<2>(t) == MoveOnly());
     }
+    // Check that SFINAE is properly applied with the default reduced arity
+    // constructor extensions.
+    test_default_constructible_extension_sfinae();
 }
diff --git a/test/utilities/tuple/tuple.tuple/tuple.cnstr/default.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.cnstr/default.pass.cpp
index b72b77e..9cde90d 100644
--- a/test/utilities/tuple/tuple.tuple/tuple.cnstr/default.pass.cpp
+++ b/test/utilities/tuple/tuple.tuple/tuple.cnstr/default.pass.cpp
@@ -16,9 +16,23 @@
 #include <tuple>
 #include <string>
 #include <cassert>
+#include <type_traits>
 
 #include "DefaultOnly.h"
 
+struct NoDefault {
+    NoDefault() = delete;
+    explicit NoDefault(int) { }
+};
+
+struct NoExceptDefault {
+    NoExceptDefault() noexcept = default;
+};
+
+struct ThrowingDefault {
+    ThrowingDefault() { }
+};
+
 int main()
 {
     {
@@ -46,6 +60,20 @@
         assert(std::get<2>(t) == "");
         assert(std::get<3>(t) == DefaultOnly());
     }
+    {
+        // See bug #21157.
+        static_assert(!std::is_default_constructible<std::tuple<NoDefault>>(), "");
+        static_assert(!std::is_default_constructible<std::tuple<DefaultOnly, NoDefault>>(), "");
+        static_assert(!std::is_default_constructible<std::tuple<NoDefault, DefaultOnly, NoDefault>>(), "");
+    }
+    {
+        static_assert(noexcept(std::tuple<NoExceptDefault>()), "");
+        static_assert(noexcept(std::tuple<NoExceptDefault, NoExceptDefault>()), "");
+
+        static_assert(!noexcept(std::tuple<ThrowingDefault, NoExceptDefault>()), "");
+        static_assert(!noexcept(std::tuple<NoExceptDefault, ThrowingDefault>()), "");
+        static_assert(!noexcept(std::tuple<ThrowingDefault, ThrowingDefault>()), "");
+    }
 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
     {
         constexpr std::tuple<> t;
diff --git a/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp
new file mode 100644
index 0000000..65a1c70
--- /dev/null
+++ b/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class Tuple, __tuple_convertible<Tuple, tuple> >
+//   tuple(Tuple &&);
+//
+// template <class Tuple, __tuple_constructible<Tuple, tuple> >
+//   tuple(Tuple &&);
+
+// This test checks that we do not evaluate __make_tuple_types
+// on the array.
+
+#include <array>
+#include <tuple>
+
+// Use 1256 to try and blow the template instantiation depth for all compilers.
+typedef std::array<char, 1256> array_t;
+typedef std::tuple<array_t> tuple_t;
+
+int main()
+{
+    array_t arr;
+    tuple_t tup(arr);
+}
diff --git a/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp
index b47842d..3fca573 100644
--- a/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp
+++ b/test/utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp
@@ -213,4 +213,18 @@
         assert(std::get<3>(t3) == 4);
         assert(std::get<4>(t3) == 5);
     }
+    {
+        // See bug #19616.
+        auto t1 = std::tuple_cat(
+            std::make_tuple(std::make_tuple(1)),
+            std::make_tuple()
+        );
+        assert(t1 == std::make_tuple(std::make_tuple(1)));
+
+        auto t2 = std::tuple_cat(
+            std::make_tuple(std::make_tuple(1)),
+            std::make_tuple(std::make_tuple(2))
+        );
+        assert(t2 == std::make_tuple(std::make_tuple(1), std::make_tuple(2)));
+    }
 }
diff --git a/test/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp
new file mode 100644
index 0000000..d8a72c6
--- /dev/null
+++ b/test/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.array.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <size_t I, class... Types>
+// class tuple_element<I, tuple<Types...> >
+// {
+// public:
+//     typedef Ti type;
+// };
+//
+//  LWG #2212 says that tuple_size and tuple_element must be 
+//     available after including <utility>
+
+#include <array>
+#include <type_traits>
+
+template <class T, std::size_t N, class U, size_t idx>
+void test()
+{
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<T> >::value), "");
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<const T> >::value), "");
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<volatile T> >::value), "");
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<const volatile T> >::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, T>::type, U>::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, const T>::type, const U>::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, volatile T>::type, volatile U>::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, const volatile T>::type, const volatile U>::value), "");
+}
+
+int main()
+{
+    test<std::array<int, 5>, 5, int, 0>();
+    test<std::array<int, 5>, 5, int, 1>();
+    test<std::array<const char *, 4>, 4, const char *, 3>();
+    test<std::array<volatile int, 4>, 4, volatile int, 3>();
+    test<std::array<char *, 3>, 3, char *, 1>();
+    test<std::array<char *, 3>, 3, char *, 2>();
+}
diff --git a/test/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp
new file mode 100644
index 0000000..8c8357d
--- /dev/null
+++ b/test/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.utility.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class... Types>
+//   class tuple_size<tuple<Types...>>
+//     : public integral_constant<size_t, sizeof...(Types)> { };
+//
+//  LWG #2212 says that tuple_size and tuple_element must be 
+//     available after including <utility>
+
+#include <utility>
+#include <type_traits>
+
+template <class T, std::size_t N, class U, size_t idx>
+void test()
+{
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<T> >::value), "");
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<const T> >::value), "");
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<volatile T> >::value), "");
+    static_assert((std::is_base_of<std::integral_constant<std::size_t, N>,
+                                   std::tuple_size<const volatile T> >::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, T>::type, U>::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, const T>::type, const U>::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, volatile T>::type, volatile U>::value), "");
+    static_assert((std::is_same<typename std::tuple_element<idx, const volatile T>::type, const volatile U>::value), "");
+}
+
+int main()
+{
+    test<std::pair<int, int>, 2, int, 0>();
+    test<std::pair<int, int>, 2, int, 1>();
+    test<std::pair<const int, int>, 2, int, 1>();
+    test<std::pair<int, volatile int>, 2, volatile int, 1>();
+    test<std::pair<char *, int>, 2, char *, 0>();
+    test<std::pair<char *, int>, 2, int,    1>();
+}
diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html
new file mode 100644
index 0000000..caa750b
--- /dev/null
+++ b/www/cxx1z_status.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>libc++ C++1Z Status</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+
+<body>
+<div id="menu">
+  <div>
+    <a href="http://llvm.org/">LLVM Home</a>
+  </div>
+
+  <div class="submenu">
+    <label>libc++ Info</label>
+    <a href="/index.html">About</a>
+  </div>
+
+  <div class="submenu">
+    <label>Quick Links</label>
+    <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
+    <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+    <a href="http://llvm.org/bugs/">Bug Reports</a>
+    <a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
+    <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
+  </div>
+</div>
+
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>libc++ C++1z Status</h1>
+  <!--*********************************************************************-->
+
+  <p>In November 2014, the C++ standard committee created a draft for the next version of the C++ standard, known here as "C++1z" (probably to be C++17)</p>
+  <p>This page shows the status of libc++; the status of clang's support of the language features is <a href="http://clang.llvm.org/cxx_status.html#cxx17">here</a>.</p>
+
+  <p>The groups that have contributed papers:
+  <ul>
+    <li>LWG - Library working group</li>
+    <li>CWG - Core Language Working group</li>
+    <li>SG1 - Study group #1 (Concurrency working group)</li>
+  </ul>
+  </p>
+  
+  <h3>Paper Status</h3>
+  <table id="papers" border="1">
+	<tr><th>Paper #</th><th>Group</th><th>Paper Name</th><th>Meeting</th><th>Status</th><th>First released version</th></tr>
+<!--
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3346.pdf">3346</a></td><td>LWG</td><td>Terminology for Container Element Requirements - Rev 1</td><td>Kona</td><td>Complete</td><td>3.4</td></tr>
+-->
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3911">N3911</a></td><td>LWG</td></td><td>TransformationTrait Alias <code>void_t</code>.</td><td>Urbana</td><td>Complete</td><td>3.6</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4089">N4089</a></td><td>LWG</td></td><td>Safe conversions in <code>unique_ptr&lt;T[]&gt;</code>.</td><td>Urbana</td><td></td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169">N4169</a></td><td>LWG</td></td><td>A proposal to add invoke function template</td><td>Urbana</td><td></td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190">N4190</a></td></td><td>LWG</td><td>Removing auto_ptr, random_shuffle(), And Old <functional> Stuff.</td><td>Urbana</td><td></td><td></td></tr>
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4258.pdf">N4258</a></td><td>LWG</td></td><td>Cleaning-up noexcept in the Library.</td><td>Urbana</td><td></td><td></td></tr>
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/N4277.html">N4277</a></td><td>LWG</td></td><td>TriviallyCopyable <code>reference_wrapper</code>.</td><td>Urbana</td><td>Complete</td><td>3.2</td></tr>
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4279.html">N4279</a></td><td>LWG</td></td><td>Improved insertion interface for unique-key maps.</td><td>Urbana</td><td></td><td></td></tr>
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4280.pdf">N4280</a></td><td>LWG</td></td><td>Non-member size() and more</td><td>Urbana</td><td>Complete</td><td>3.6</td></tr>
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4284.html">N4284</a></td><td>LWG</td></td><td>Contiguous Iterators.</td><td>Urbana</td><td></td><td></td></tr>
+
+<!--  	<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> -->
+  </table>
+
+  <h3>Library Working group Issues Status</h3>
+<!--   <I>Note: "NAD" means that the issue was deemed "Not a defect"</I> -->
+  <table id="issues" border="1">
+	<tr><th>Issue #</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2016">2016</a></td><td>Allocators must be no-throw swappable</td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2376">2118</td><td><code>unique_ptr</code> for array does not support cv qualification conversion of actual argument</td><td>Urbana</td><td>Will be resolved by N4089</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2170">2170</a></td><td>Aggregates cannot be <code>DefaultConstructible</code></td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2387">2308</td><td>Clarify container destructor requirements w.r.t. <code>std::array</code></td><td>Urbana</td><td>Will be resolved by N4258</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2340">2340</a></td><td>Replacement allocation functions declared as inline</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2354">2354</a></td><td>Unnecessary copying when inserting into maps with braced-init syntax</td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2377">2377</a></td><td><code>std::align</code> requirements overly strict</td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2396">2396</a></td><td><code>underlying_type</code> doesn't say what to do for an incomplete enumeration type</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2399">2399</a></td><td><code>shared_ptr</code>'s constructor from <code>unique_ptr</code> should be constrained</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2400">2400</a></td><td><code>shared_ptr</code>'s <code>get_deleter()</code> should use <code>addressof()</code></td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2401">2401</a></td><td><code>std::function</code> needs more noexcept</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2404">2404</a></td><td><code>mismatch()</code>'s complexity needs to be updated</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2408">2408</a></td><td>SFINAE-friendly <code>common_type</code> / <code>iterator_traits</code> is missing in C++14</td><td>Urbana</td><td></td></tr>
+ 	<tr><td></td><td></td><td></td><td></td></tr>
+
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2106">2106</td><td><code>move_iterator</code> wrapping iterators returning prvalues</td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2129">2129</td><td>User specializations of <code>std::initializer_list</code></td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2212">2212</td><td><code>tuple_size</code> for <code>const pair</code> request <tuple> header</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2217">2217</td><td><code>operator==(sub_match, string)</code> slices on embedded '\0's</td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2230">2230</td><td>"see below" for <code>initializer_list</code> constructors of unordered containers</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2233">2233</td><td><code>bad_function_call::what()</code> unhelpful</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2266">2266</td><td><code>vector</code> and <code>deque</code> have incorrect insert requirements</td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2325">2325</td><td><code>minmax_element()</code>'s behavior differing from <code>max_element()</code>'s should be noted</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2361">2361</td><td>Apply 2299 resolution throughout library</td><td>Urbana</td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2365">2365</td><td>Missing noexcept in <code>shared_ptr::shared_ptr(nullptr_t)</code></td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2376">2376</td><td><code>bad_weak_ptr::what()</code> overspecified</td><td>Urbana</td><td>Complete</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2387">2387</td><td>More nested types that must be accessible and unambiguous</td><td>Urbana</td><td></td></tr>
+<!--
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1214">1214</a></td><td>Insufficient/inconsistent key immutability requirements for associative containers</td><td>Urbana</td><td></td></tr>
+-->
+<!-- 	<tr><td></td><td></td><td></td><td></td></tr> -->
+  </table>
+
+  <p>Last Updated: 18-Nov-2014</p>
+</div>
+</body>
+</html>
diff --git a/www/index.html b/www/index.html
index d4adfe7..2052ad6 100644
--- a/www/index.html
+++ b/www/index.html
@@ -126,6 +126,8 @@
    <p>LLVM and Clang can self host in C++ and C++11 mode with libc++ on Linux.</p>
    <p>libc++ is also a 100% complete C++14 implementation. A list of new features and changes for 
       C++14 can be found <a href="cxx1y_status.html">here</a>.</p>
+   <p>A list of features and changes for the next C++ standard, known here as
+      "C++1z" (probably to be C++17) can be found <a href="cxx1z_status.html">here</a>.</p>
    <p>Implementation of the post-c++14 Technical Specifications is in progress. A list of features and
       the current status of these features can be found <a href="ts1z_status.html">here</a>.</p>
    <p>
@@ -139,9 +141,6 @@
    <!--======================================================================-->
    <p>These are the libc++ build bots</p>
    <ul>
-      <li><a href="http://lab.llvm.org:8013/builders/libcxx_clang-x86_64-darwin11-RA">
-        clang-libcxxabi-x86_64-darwin11
-      </a></li>
       <li><a href="http://llvm-amd64.freebsd.your.org/b/builders/libcxx-amd64-freebsd">
         clang-libcxxrt-x86_64-freebsd10
       </a></li>
@@ -151,6 +150,9 @@
       <li><a href="http://lab.llvm.org:8011/builders/libcxx-libcxxabi-x86_64-linux-debian">
         clang-libcxxabi-x86_64-linux-debian
       </a></li>
+      <li><a href="http://lab.llvm.org:8011/builders/libcxx-libcxxabi-x86_64-linux-ubuntu">
+        clang-libcxxabi-x86_64-linux-ubuntu
+      </a></li>
     </ul>
 
   <!--=====================================================================-->
@@ -434,6 +436,37 @@
   </p>
 
   <!--=====================================================================-->
+  <h2 id="local-abi">Using a local ABI library</h2>
+  <!--=====================================================================-->
+  <p>
+    <strong>Note: This is not recommended in almost all cases.</strong><br>
+    Generally these instructions should only be used when you can't install
+    your ABI library.
+  </p>
+  <p>
+    Normally you must link libc++ against a ABI shared library that the
+    linker can find.  If you want to build and test libc++ against an ABI
+    library not in the linker's path you need to set
+    <code>-DLIBCXX_CXX_ABI_LIBRARY_PATH=/path/to/abi/lib</code> when
+    configuring CMake.
+  </p>
+  <p>
+    An example build using libc++abi would look like:
+    <ul>
+    <li><code>CC=clang CXX=clang++ cmake
+              -DLIBCXX_CXX_ABI=libc++abi
+              -DLIBCXX_LIBCXXABI_INCLUDE_PATHS="/path/to/libcxxabi/include"
+              -DLIBCXX_CXX_ABI_LIBRARY_PATH="/path/to/libcxxabi-build/lib"
+              path/to/libcxx</code></li>
+    <li><code>make</code></li>
+    </ul>
+  </p>
+  <p>
+    When testing libc++ LIT will automatically link against the proper ABI
+    library.
+  </p>
+
+  <!--=====================================================================-->
   <h2>Design Documents</h2>
   <!--=====================================================================-->
 
diff --git a/www/ts1z_status.html b/www/ts1z_status.html
index c06ef7b..95880b9 100644
--- a/www/ts1z_status.html
+++ b/www/ts1z_status.html
@@ -41,14 +41,21 @@
 
   <h3>Technical Specifications</h3>
   <table id="TS" border="1">
-	<tr><th>Paper Number</th><th>TS Title</th></tr>
+	<tr><th>Paper Number</th><th>Paper Title</th><th>TS</th></tr>
 
-	<tr><td>4023</td><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4023.html">C++ Extensions for Library Fundamentals</a></td></tr>
-	<tr><td>3940</td><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3940.html">Technical Specification - File System</a></td></tr>
-	<tr><td></td><td></td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4023.html">4023</a></td><td>C++ Extensions for Library Fundamentals</td><td>Library Fundamentals 1</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3940.html">3940</a></td><td>Technical Specification - File System</td><td>File System</td></tr>
+	<tr><td></td><td></td><td></td></tr>
+
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4273.txt">4273</a></td><td>Uniform Container Erasure.</td><td>Library Fundamentals 2</td></tr>
+	<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4061">4061</a></td><td>Greatest Common Divisor and Least Common Multiple.</td><td>Library Fundamentals 2</td></tr>
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/N4257.htm">4257</a></td><td>Delimited iterators.</td><td>Library Fundamentals 2</td></tr>
+	<tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/N4282.pdf">4282</a></td><td>The World's Dumbest Smart Pointer.</td><td>Library Fundamentals 2</td></tr>
+	<tr><td></td><td></td><td></td></tr>
+
   </table>
 
-  <h3>Features in Library Fundamentals</h3>
+  <h3>Features in Library Fundamentals 1</h3>
   <table id="Features" border="1">
 	<tr><th>Feature Name</th><th>Status</th></tr>
 	<tr><td>Uses-allocator construction</td><td>Not started</td></tr>
@@ -59,7 +66,7 @@
 	<tr><td>Additions to std::promise</td><td>Not started</td></tr>
 	<tr><td>Additions to std::packaged_task</td><td>Not started</td></tr>
   <tr><td></td><td></td></tr>
-	<tr><td>Class erased_type</td><td>Not started</td></tr>
+	<tr><td>Class erased_type</td><td>Initial implementation complete</td></tr>
 	<tr><td>Calling a function with a tuple of arguments</td><td>Not started</td></tr>
 	<tr><td>Other type transformations</td><td>Not started</td></tr>
 	<tr><td>Compile-time Rational Arithmetic</td><td>Not started</td></tr>
@@ -76,6 +83,13 @@
 
   </table>
 
+  <h3>Features in Library Fundamentals 2</h3>
+  <table id="Features" border="1">
+	<tr><th>Feature Name</th><th>Status</th></tr>
+<!--  <tr><td></td><td></td></tr> -->
+
+  </table>
+  
   <h3>Features in Filesystem</h3>
   <table id="Features" border="1">
 	<tr><th>Feature Name</th><th>Status</th></tr>