Merge commit '81241a944099014cc56929a99355cede91ada83c' into HEAD

Conflicts:
	CMakeLists.txt
	cmake/config-ix.cmake
	include/locale
	src/locale.cpp
	src/thread.cpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8228126..5713cb2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,9 +14,9 @@
 
 # Add path for custom modules
 set(CMAKE_MODULE_PATH
-  ${CMAKE_MODULE_PATH}
   "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
   "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
+  ${CMAKE_MODULE_PATH}
   )
 
 # Require out of source build.
@@ -26,6 +26,10 @@
  build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
  )
 
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+  set(LIBCXX_BUILT_STANDALONE 1)
+endif()
+
 #===============================================================================
 # Setup CMake Options
 #===============================================================================
@@ -38,14 +42,15 @@
 option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
 option(LIBCXX_ENABLE_CXX0X "Enable -std=c++0x and use of c++0x language features if the compiler supports it." ON)
 option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
+option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
 
-set(CXXABIS none libcxxabi libcxxrt libsupc++)
+set(CXXABIS none libcxxabi libcxxrt libstdc++ libsupc++)
 if (NOT DEFINED LIBCXX_CXX_ABI)
   set(LIBCXX_CXX_ABI "none")
 endif()
 set(LIBCXX_CXX_ABI "${LIBCXX_CXX_ABI}" CACHE STRING
     "Specify C++ ABI library to use." FORCE)
-set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS "";${CXXABIS})
+set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS})
 
 #===============================================================================
 # Configure System
@@ -128,17 +133,26 @@
     )
 endmacro()
 
-if ("${LIBCXX_CXX_ABI}" STREQUAL "libsupc++")
+if ("${LIBCXX_CXX_ABI}" STREQUAL "libstdc++" OR
+    "${LIBCXX_CXX_ABI}" 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
     )
-  setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS" "-D__GLIBCXX__"
-    "supc++" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
+  if ("${LIBCXX_CXX_ABI}" 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}" STREQUAL "libcxxabi")
   setup_abi_lib("LIBCXX_LIBCXXABI_INCLUDE_PATHS" ""
-    "c++abi" "cxxabi.h" "" # @LOCALMOD Removed cxa_demangle.h: doesn't exist anymore.
+    "c++abi" "cxxabi.h" ""
     )
 elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxrt")
   setup_abi_lib("LIBCXX_LIBCXXRT_INCLUDE_PATHS" "-DLIBCXXRT"
@@ -146,7 +160,7 @@
     )
 elseif (NOT "${LIBCXX_CXX_ABI}" STREQUAL "none")
   message(FATAL_ERROR
-    "Currently libsupc++, libcxxabi, libcxxrt and none are "
+    "Currently libstdc++, libsupc++, libcxxabi, libcxxrt and none are "
     "supported for c++ abi."
     )
 endif ()
@@ -180,7 +194,11 @@
 endmacro()
 
 # Get warning flags
-append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WALL_FLAG -Wall)
+if (NOT MSVC)
+  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WALL_FLAG -Wall)
+  set(LIBCXX_CXX_REQUIRED_FLAGS, -Werror=return-type)
+endif()
+
 append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_W_FLAG -W)
 append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG -Wno-unused-parameter)
 append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings)
@@ -188,6 +206,9 @@
 if (LIBCXX_ENABLE_WERROR)
   append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WERROR_FLAG -Werror)
   append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WX_FLAG -WX)
+else()
+  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_WNO_ERROR_FLAG -Wno-error)
+  append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_NO_WX_FLAG -WX-)
 endif()
 if (LIBCXX_ENABLE_PEDANTIC)
   append_if(LIBCXX_CXX_WARNING_FLAGS LIBCXX_HAS_PEDANTIC_FLAG -pedantic)
@@ -234,6 +255,10 @@
 endif()
 
 # This is the _ONLY_ place where add_definitions is called.
+if (MSVC)
+  add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+endif()
+
 add_definitions(
  ${LIBCXX_CXX_REQUIRED_FLAGS}
  ${LIBCXX_CXX_WARNING_FLAGS}
@@ -245,6 +270,7 @@
 #===============================================================================
 
 include_directories(include)
+add_subdirectory(include)
 
 # Add source code. This also contains all of the logic for deciding linker flags
 # soname, etc...
diff --git a/CREDITS.TXT b/CREDITS.TXT
index 34a901f..368b526 100644
--- a/CREDITS.TXT
+++ b/CREDITS.TXT
@@ -31,6 +31,14 @@
 N: Marshall Clow
 E: mclow.lists@gmail.com
 E: marshall@idio.com
+D: C++14 support, patches and bug fixes.
+
+N: Bill Fisher
+E: william.w.fisher@gmail.com
+D: Regex bug fixes.
+
+N: Matthew Dempsky
+E: matthew@dempsky.org
 D: Minor patches and bug fixes.
 
 N: Google Inc.
@@ -68,6 +76,10 @@
 E: breese@users.sourceforge.net
 D: Initial regex prototype
 
+N: Nico Rieck
+E: nico.rieck@gmail.com
+D: Windows fixes
+
 N: Jonathan Sauer
 D: Minor patches, mostly related to constexpr
 
@@ -97,6 +109,14 @@
 E: zhangxiongpang@gmail.com
 D: Minor patches and bug fixes.
 
+N: Xing Xue
+E: xingxue@ca.ibm.com
+D: AIX port
+
+N: Zhihao Yuan
+E: lichray@gmail.com
+D: Standard compatibility fixes.
+
 N: Jeffrey Yasskin
 E: jyasskin@gmail.com
 E: jyasskin@google.com
diff --git a/Makefile b/Makefile
index f55db43..9267023 100644
--- a/Makefile
+++ b/Makefile
@@ -39,6 +39,8 @@
 	chmod 644 $(HEADER_DIR)/c++/v1/*
 	chmod 755 $(HEADER_DIR)/c++/v1/ext
 	chmod 644 $(HEADER_DIR)/c++/v1/ext/*
+	chmod 755 $(HEADER_DIR)/c++/v1/experimental
+	chmod 644 $(HEADER_DIR)/c++/v1/experimental/*
 
 install::
 
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index f4d68af..e8d6025 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -17,10 +17,12 @@
 set(LIBCXX_HAS_WNO_LONG_LONG_FLAG 1)
 set(LIBCXX_HAS_PEDANTIC_FLAG 1)
 set(LIBCXX_HAS_WERROR_FLAG 1)
+set(LIBCXX_HAS_WNO_ERROR_FLAG 1)
 set(LIBCXX_HAS_FNO_EXCEPTIONS_FLAG 1)
 set(LIBCXX_HAS_FNO_RTTI_FLAG 1)
 # MSVC flags:
 set(LIBCXX_HAS_WX_FLAG 0)
+set(LIBCXX_HAS_NO_WX_FLAG 0)
 set(LIBCXX_HAS_EHSC_FLAG 0)
 set(LIBCXX_HAS_NO_EHS_FLAG 0)
 set(LIBCXX_HAS_NO_EHA_FLAG 0)
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644
index 0000000..0c88b7f
--- /dev/null
+++ b/include/CMakeLists.txt
@@ -0,0 +1,16 @@
+if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
+  set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE)
+endif()
+
+file(COPY .
+  DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1"
+  FILES_MATCHING
+  PATTERN "*"
+  PATTERN "CMakeLists.txt" EXCLUDE
+  PATTERN ".svn" EXCLUDE
+  ${LIBCXX_SUPPORT_HEADER_PATTERN}
+  )
+
+install(DIRECTORY "${CMAKE_BINARY_DIR}/include/c++/v1/"
+  DESTINATION include/c++/v1/
+  )
diff --git a/include/__bit_reference b/include/__bit_reference
index 1621deb..37b7923 100644
--- a/include/__bit_reference
+++ b/include/__bit_reference
@@ -40,7 +40,7 @@
     __storage_pointer __seg_;
     __storage_type    __mask_;
 
-#if defined(__clang__)
+#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
     friend typename _Cp::__self;
 #else
     friend class _Cp::__self;
@@ -82,7 +82,7 @@
 };
 
 template <class _Cp>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
 {
@@ -92,7 +92,7 @@
 }
 
 template <class _Cp, class _Dp>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
 {
@@ -102,7 +102,7 @@
 }
 
 template <class _Cp>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
 {
@@ -112,7 +112,7 @@
 }
 
 template <class _Cp>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
 {
@@ -130,7 +130,7 @@
     __storage_pointer        __seg_;
     __storage_type __mask_;
 
-#if defined(__clang__)
+#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
     friend typename _Cp::__self;
 #else
     friend class _Cp::__self;
@@ -173,6 +173,8 @@
         __storage_type __b = *__first.__seg_ & __m;
         if (__b)
             return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+        if (__n == __dn)
+            return _It(__first.__seg_, __first.__ctz_ + __n);
         __n -= __dn;
         ++__first.__seg_;
     }
@@ -207,6 +209,8 @@
         __storage_type __b = ~*__first.__seg_ & __m;
         if (__b)
             return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+        if (__n == __dn)
+            return _It(__first.__seg_, __first.__ctz_ + __n);
         __n -= __dn;
         ++__first.__seg_;
     }
@@ -333,7 +337,7 @@
     }
     // do middle whole words
     __storage_type __nw = __n / __bits_per_word;
-    _VSTD::memset(__first.__seg_, 0, __nw * sizeof(__storage_type));
+    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));
     __n -= __nw * __bits_per_word;
     // do last partial word
     if (__n > 0)
@@ -363,7 +367,7 @@
     }
     // do middle whole words
     __storage_type __nw = __n / __bits_per_word;
-    _VSTD::memset(__first.__seg_, -1, __nw * sizeof(__storage_type));
+    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));
     __n -= __nw * __bits_per_word;
     // do last partial word
     if (__n > 0)
@@ -375,7 +379,7 @@
 }
 
 template <class _Cp>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
 {
@@ -430,7 +434,9 @@
         // __first.__ctz_ == 0;
         // do middle words
         __storage_type __nw = __n / __bits_per_word;
-        _VSTD::memmove(__result.__seg_, __first.__seg_, __nw * sizeof(__storage_type));
+        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
+                       _VSTD::__to_raw_pointer(__first.__seg_),
+                       __nw * sizeof(__storage_type));
         __n -= __nw * __bits_per_word;
         __result.__seg_ += __nw;
         // do last word
@@ -569,7 +575,9 @@
         __storage_type __nw = __n / __bits_per_word;
         __result.__seg_ -= __nw;
         __last.__seg_ -= __nw;
-        _VSTD::memmove(__result.__seg_, __last.__seg_, __nw * sizeof(__storage_type));
+        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
+                       _VSTD::__to_raw_pointer(__last.__seg_),
+                       __nw * sizeof(__storage_type));
         __n -= __nw * __bits_per_word;
         // do last word
         if (__n > 0)
@@ -870,6 +878,7 @@
 {
     typedef typename _Cp::difference_type difference_type;
     typedef typename _Cp::__storage_type  __storage_type;
+    typedef typename _Cp::__storage_pointer __storage_pointer;
     typedef typename _Cp::iterator        iterator;
     static const unsigned __bits_per_word = _Cp::__bits_per_word;
     static const unsigned _Np = 4;
@@ -880,9 +889,15 @@
     _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
         {return static_cast<difference_type>(_Np * __bits_per_word);}
     _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
-    _LIBCPP_INLINE_VISIBILITY iterator begin() {return iterator(__word_, 0);}
-    _LIBCPP_INLINE_VISIBILITY iterator end()   {return iterator(__word_ + __size_ / __bits_per_word,
-                                                  static_cast<unsigned>(__size_ % __bits_per_word));}
+    _LIBCPP_INLINE_VISIBILITY iterator begin()
+    {
+        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
+    }
+    _LIBCPP_INLINE_VISIBILITY iterator end()
+    {
+        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
+                                                  static_cast<unsigned>(__size_ % __bits_per_word));
+    }
 };
 
 template <class _Cp>
@@ -1093,7 +1108,11 @@
     unsigned          __ctz_;
 
 public:
-    _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __seg_(nullptr), __ctz_(0)
+#endif
+    {}
 
     _LIBCPP_INLINE_VISIBILITY
     __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
@@ -1203,7 +1222,7 @@
     __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
         : __seg_(__s), __ctz_(__ctz) {}
 
-#if defined(__clang__)
+#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
     friend typename _Cp::__self;
 #else
     friend class _Cp::__self;
diff --git a/include/__config b/include/__config
index 7923f2f..aa8bc44 100644
--- a/include/__config
+++ b/include/__config
@@ -11,7 +11,7 @@
 #ifndef _LIBCPP_CONFIG
 #define _LIBCPP_CONFIG
 
-#ifndef _MSC_VER // explicit macro necessary because it is only defined below in this file
+#if !defined(_MSC_VER) || defined(__clang__)
 #pragma GCC system_header
 #endif
 
@@ -56,19 +56,42 @@
 # endif  // __LONG_LONG_SUPPORTED
 #endif  // __FreeBSD__
 
+#ifdef __NetBSD__
+# include <sys/endian.h>
+#  if _BYTE_ORDER == _LITTLE_ENDIAN
+#   define _LIBCPP_LITTLE_ENDIAN 1
+#   define _LIBCPP_BIG_ENDIAN    0
+# else  // _BYTE_ORDER == _LITTLE_ENDIAN
+#   define _LIBCPP_LITTLE_ENDIAN 0
+#   define _LIBCPP_BIG_ENDIAN    1
+# endif  // _BYTE_ORDER == _LITTLE_ENDIAN
+# define _LIBCPP_HAS_QUICK_EXIT
+#endif  // __NetBSD__
+
 #ifdef _WIN32
 #  define _LIBCPP_LITTLE_ENDIAN 1
 #  define _LIBCPP_BIG_ENDIAN    0
 // Compiler intrinsics (GCC or MSVC)
-#  if (defined(_MSC_VER) && _MSC_VER >= 1400) \
+#  if defined(__clang__) \
+   || (defined(_MSC_VER) && _MSC_VER >= 1400) \
    || (defined(__GNUC__) && _GNUC_VER > 403)
-#    define _LIBCP_HAS_IS_BASE_OF
+#    define _LIBCPP_HAS_IS_BASE_OF
+#  endif
+#  if defined(_MSC_VER) && !defined(__clang__)
+#    define _LIBCPP_MSVC // Using Microsoft Visual C++ compiler
+#    define _LIBCPP_TOSTRING2(x) #x
+#    define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
+#    define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x))
+#  endif
+#  // If mingw not explicitly detected, assume using MS C runtime only.
+#  ifndef __MINGW32__
+#    define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
 #  endif
 #endif  // _WIN32
 
 #ifdef __linux__
 #  if defined(__GNUC__) && _GNUC_VER >= 403
-#    define _LIBCP_HAS_IS_BASE_OF
+#    define _LIBCPP_HAS_IS_BASE_OF
 #  endif
 #endif
 
@@ -115,8 +138,11 @@
 # define _LIBCPP_TYPE_VIS
 #endif
 
+#define _LIBCPP_TYPE_VIS_ONLY
+#define _LIBCPP_FUNC_VIS_ONLY
+
 #ifndef _LIBCPP_INLINE_VISIBILITY
-# ifdef _MSC_VER
+# ifdef _LIBCPP_MSVC
 #  define _LIBCPP_INLINE_VISIBILITY __forceinline
 # else // MinGW GCC and Clang
 #  define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__))
@@ -128,7 +154,7 @@
 #endif
 
 #ifndef _LIBCPP_ALWAYS_INLINE
-# ifdef _MSC_VER
+# ifdef _LIBCPP_MSVC
 #  define _LIBCPP_ALWAYS_INLINE __forceinline
 # endif
 #endif
@@ -148,13 +174,21 @@
 #endif
 
 #ifndef _LIBCPP_TYPE_VIS
-#  if __has_attribute(type_visibility)
+#  if __has_attribute(__type_visibility__)
 #    define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default")))
 #  else
 #    define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
 #  endif
 #endif
 
+#ifndef _LIBCPP_TYPE_VIS_ONLY
+# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS
+#endif
+
+#ifndef _LIBCPP_FUNC_VIS_ONLY
+# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS
+#endif
+
 #ifndef _LIBCPP_INLINE_VISIBILITY
 #define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
 #endif
@@ -163,10 +197,6 @@
 #define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS
 #endif
 
-#ifndef _LIBCPP_CANTTHROW
-#define _LIBCPP_CANTTHROW __attribute__ ((__nothrow__))
-#endif
-
 #ifndef _LIBCPP_ALWAYS_INLINE
 #define _LIBCPP_ALWAYS_INLINE  __attribute__ ((__visibility__("hidden"), __always_inline__))
 #endif
@@ -261,7 +291,7 @@
 #endif
 
 #if __has_feature(is_base_of)
-#  define _LIBCP_HAS_IS_BASE_OF
+#  define _LIBCPP_HAS_IS_BASE_OF
 #endif
 
 // Objective-C++ features (opt-in)
@@ -278,9 +308,19 @@
 #define _LIBCPP_HAS_NO_CONSTEXPR
 #endif
 
-#if defined(__FreeBSD__) && (__ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L)
+#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
+#if defined(__FreeBSD__)
 #define _LIBCPP_HAS_QUICK_EXIT
 #define _LIBCPP_HAS_C11_FEATURES
+#elif defined(__linux__)
+#include <features.h>
+#if __GLIBC_PREREQ(2, 15)
+#define _LIBCPP_HAS_QUICK_EXIT
+#endif
+#if __GLIBC_PREREQ(2, 17)
+#define _LIBCPP_HAS_C11_FEATURES
+#endif
+#endif
 #endif
 
 #if (__has_feature(cxx_noexcept))
@@ -374,13 +414,14 @@
 using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
 }
 
-#elif defined(_MSC_VER)
+#elif defined(_LIBCPP_MSVC)
 
 #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
 #define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
 #define _LIBCPP_HAS_NO_CONSTEXPR
 #define _LIBCPP_HAS_NO_UNICODE_CHARS
 #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
 #define __alignof__ __alignof
 #define _LIBCPP_NORETURN __declspec(noreturn)
 #define _ALIGNAS(x) __declspec(align(x))
@@ -393,10 +434,43 @@
 #define _LIBCPP_END_NAMESPACE_STD  }
 #define _VSTD std
 
+#  define _LIBCPP_WEAK
 namespace std {
 }
 
-#endif // __clang__ || __GNUC___ || _MSC_VER
+#elif defined(__IBMCPP__)
+
+#define _ALIGNAS(x) __attribute__((__aligned__(x)))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ATTRIBUTE(x) __attribute__((x))
+#define _LIBCPP_NORETURN __attribute__((noreturn))
+
+#define _NOEXCEPT throw()
+#define _NOEXCEPT_(x)
+
+#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
+#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#define _LIBCPP_HAS_NO_NULLPTR
+#define _LIBCPP_HAS_NO_UNICODE_CHARS
+#define _LIBCPP_HAS_NO_STRONG_ENUMS
+#define _LIBCPP_HAS_IS_BASE_OF
+
+#if defined(_AIX)
+#define __MULTILOCALE_API
+#endif
+
+#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
+#define _LIBCPP_END_NAMESPACE_STD  } }
+#define _VSTD std::_LIBCPP_NAMESPACE
+
+namespace std {
+  inline namespace _LIBCPP_NAMESPACE {
+  }
+}
+
+#endif // __clang__ || __GNUC___ || _MSC_VER || __IBMCPP__
 
 #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
 typedef unsigned short char16_t;
@@ -459,11 +533,26 @@
 #define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
 #endif  // _LIBCPP_HAS_NO_STRONG_ENUMS
 
-#ifndef _LIBCPP_EXTERN_TEMPLATE
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+#ifdef _LIBCPP_DEBUG
+#   if _LIBCPP_DEBUG == 0
+#       define _LIBCPP_DEBUG_LEVEL 1
+#   elif _LIBCPP_DEBUG == 1
+#       define _LIBCPP_DEBUG_LEVEL 2
+#   else
+#       error Supported values for _LIBCPP_DEBUG are 0 and 1
+#   endif
+#   define _LIBCPP_EXTERN_TEMPLATE(...)
 #endif
 
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__)
+#ifndef _LIBCPP_EXTERN_TEMPLATE
+#define _LIBCPP_EXTERN_TEMPLATE(...)
+#endif
+
+#ifndef _LIBCPP_EXTERN_TEMPLATE2
+#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;
+#endif
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__) || defined(__NetBSD__)
 #define _LIBCPP_LOCALE__L_EXTENSIONS 1
 #endif
 #ifdef __FreeBSD__
@@ -478,20 +567,54 @@
 #define _LIBCPP_WCTYPE_IS_MASK
 #endif
 
-#ifdef _LIBCPP_DEBUG2
-#   if _LIBCPP_DEBUG2 == 0
-#       define _LIBCPP_DEBUG_LEVEL 1
-#   elif _LIBCPP_DEBUG2 == 1
-#       define _LIBCPP_DEBUG_LEVEL 2
-#   else
-#       error Supported values for _LIBCPP_DEBUG2 are 0 and 1
-#   endif
+#if defined(__APPLE__)
+#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
+#  define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 0
+#endif
 #endif
 
-#ifdef _LIBCPP_DEBUG2
-#   include <__debug>
+#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
+#  define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1
+#endif
+
+#ifndef _LIBCPP_STD_VER
+#  if  __cplusplus <= 201103L
+#    define _LIBCPP_STD_VER 11
+#  else
+#    define _LIBCPP_STD_VER 13  // current year, or date of c++14 ratification
+#  endif
+#endif  // _LIBCPP_STD_VER
+
+#if _LIBCPP_STD_VER > 11
+#define _LIBCPP_DEPRECATED [[deprecated]]
 #else
-#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#define _LIBCPP_DEPRECATED
+#endif
+
+#if _LIBCPP_STD_VER <= 11
+#define _LIBCPP_CONSTEXPR_AFTER_CXX11
+#define _LIBCPP_EXPLICIT_AFTER_CXX11
+#define _LIBCPP_DEPRECATED_AFTER_CXX11
+#else
+#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr
+#define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
+#define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]]
+#endif
+
+// Try to find out if RTTI is disabled.
+// g++ and cl.exe have RTTI on by default and define a macro when it is.
+// g++ only defines the macro in 4.3.2 and onwards.
+#if !defined(_LIBCPP_NO_RTTI)
+#  if defined(__GNUG__) && (__GNUC__ >= 4 && \
+   (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2)) && !defined(__GXX_RTTI)
+#    define _LIBCPP_NO_RTTI
+#  elif (defined(_MSC_VER) && !defined(__clang__)) && !defined(_CPPRTTI)
+#    define _LIBCPP_NO_RTTI
+#  endif
+#endif
+
+#ifndef _LIBCPP_WEAK
+#  define _LIBCPP_WEAK __attribute__((__weak__))
 #endif
 
 #endif  // _LIBCPP_CONFIG
diff --git a/include/__debug b/include/__debug
index 0d631bf..f1805ad 100644
--- a/include/__debug
+++ b/include/__debug
@@ -11,6 +11,10 @@
 #ifndef _LIBCPP_DEBUG_H
 #define _LIBCPP_DEBUG_H
 
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
 #if _LIBCPP_DEBUG_LEVEL >= 1
 
 #   include <cstdlib>
@@ -34,8 +38,15 @@
     __i_node* __next_;
     __c_node* __c_;
 
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
     __i_node(const __i_node&) = delete;
     __i_node& operator=(const __i_node&) = delete;
+#else
+private:
+    __i_node(const __i_node&);
+    __i_node& operator=(const __i_node&);
+public:
+#endif
     _LIBCPP_INLINE_VISIBILITY
     __i_node(void* __i, __i_node* __next, __c_node* __c)
         : __i_(__i), __next_(__next), __c_(__c) {}
@@ -50,8 +61,15 @@
     __i_node** end_;
     __i_node** cap_;
 
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
     __c_node(const __c_node&) = delete;
     __c_node& operator=(const __c_node&) = delete;
+#else
+private:
+    __c_node(const __c_node&);
+    __c_node& operator=(const __c_node&);
+public:
+#endif
     _LIBCPP_INLINE_VISIBILITY
     __c_node(void* __c, __c_node* __next)
         : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
@@ -130,8 +148,15 @@
 
     __libcpp_db();
 public:
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
     __libcpp_db(const __libcpp_db&) = delete;
     __libcpp_db& operator=(const __libcpp_db&) = delete;
+#else
+private:
+    __libcpp_db(const __libcpp_db&);
+    __libcpp_db& operator=(const __libcpp_db&);
+public:
+#endif
     ~__libcpp_db();
 
     class __db_c_iterator;
@@ -171,7 +196,7 @@
     bool __decrementable(const void* __i) const;
     bool __addable(const void* __i, ptrdiff_t __n) const;
     bool __subscriptable(const void* __i, ptrdiff_t __n) const;
-    bool __comparable(const void* __i, const void* __j) const;
+    bool __less_than_comparable(const void* __i, const void* __j) const;
 private:
     _LIBCPP_HIDDEN
     __i_node* __insert_iterator(void* __i);
diff --git a/include/__functional_03 b/include/__functional_03
index b52d692..f9a3d97 100644
--- a/include/__functional_03
+++ b/include/__functional_03
@@ -102,98 +102,98 @@
 
 template<class _Rp, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)()>
+__mem_fn<_Rp (_Tp::*)() const>
 mem_fn(_Rp (_Tp::* __pm)() const)
 {
-    return __mem_fn<_Rp (_Tp::*)()>(__pm);
+    return __mem_fn<_Rp (_Tp::*)() const>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0)>
+__mem_fn<_Rp (_Tp::*)(_A0) const>
 mem_fn(_Rp (_Tp::* __pm)(_A0) const)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0) const>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0, class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1)>
+__mem_fn<_Rp (_Tp::*)(_A0, _A1) const>
 mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>
+__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>
 mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>(__pm);
 }
 
 template<class _Rp, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)()>
+__mem_fn<_Rp (_Tp::*)() volatile>
 mem_fn(_Rp (_Tp::* __pm)() volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)()>(__pm);
+    return __mem_fn<_Rp (_Tp::*)() volatile>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0)>
+__mem_fn<_Rp (_Tp::*)(_A0) volatile>
 mem_fn(_Rp (_Tp::* __pm)(_A0) volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0) volatile>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0, class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1)>
+__mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>
 mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>
+__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>
 mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>(__pm);
 }
 
 template<class _Rp, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)()>
+__mem_fn<_Rp (_Tp::*)() const volatile>
 mem_fn(_Rp (_Tp::* __pm)() const volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)()>(__pm);
+    return __mem_fn<_Rp (_Tp::*)() const volatile>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0)>
+__mem_fn<_Rp (_Tp::*)(_A0) const volatile>
 mem_fn(_Rp (_Tp::* __pm)(_A0) const volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0) const volatile>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0, class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1)>
+__mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>
 mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>(__pm);
 }
 
 template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>
+__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>
 mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const volatile)
 {
-    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>(__pm);
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>(__pm);
 }
 
 // bad_function_call
@@ -203,7 +203,7 @@
 {
 };
 
-template<class _Fp> class _LIBCPP_TYPE_VIS function; // undefined
+template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined
 
 namespace __function
 {
@@ -644,7 +644,7 @@
 }  // __function
 
 template<class _Rp>
-class _LIBCPP_TYPE_VIS function<_Rp()>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp()>
 {
     typedef __function::__base<_Rp()> __base;
     aligned_storage<3*sizeof(void*)>::type __buf_;
@@ -928,7 +928,7 @@
 #endif  // _LIBCPP_NO_RTTI
 
 template<class _Rp, class _A0>
-class _LIBCPP_TYPE_VIS function<_Rp(_A0)>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)>
     : public unary_function<_A0, _Rp>
 {
     typedef __function::__base<_Rp(_A0)> __base;
@@ -1230,7 +1230,7 @@
 #endif  // _LIBCPP_NO_RTTI
 
 template<class _Rp, class _A0, class _A1>
-class _LIBCPP_TYPE_VIS function<_Rp(_A0, _A1)>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)>
     : public binary_function<_A0, _A1, _Rp>
 {
     typedef __function::__base<_Rp(_A0, _A1)> __base;
@@ -1532,7 +1532,7 @@
 #endif  // _LIBCPP_NO_RTTI
 
 template<class _Rp, class _A0, class _A1, class _A2>
-class _LIBCPP_TYPE_VIS function<_Rp(_A0, _A1, _A2)>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)>
 {
     typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
     aligned_storage<3*sizeof(void*)>::type __buf_;
@@ -1860,11 +1860,11 @@
 {return __x.swap(__y);}
 
 template<class _Tp> struct __is_bind_expression : public false_type {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS is_bind_expression
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
     : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
 
 template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS is_placeholder
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder
     : public __is_placeholder<typename remove_cv<_Tp>::type> {};
 
 namespace placeholders
diff --git a/include/__functional_base b/include/__functional_base
index 40a63a8..1c337d8 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -15,6 +15,7 @@
 #include <type_traits>
 #include <typeinfo>
 #include <exception>
+#include <new>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -23,21 +24,21 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Arg, class _Result>
-struct _LIBCPP_TYPE_VIS unary_function
+struct _LIBCPP_TYPE_VIS_ONLY unary_function
 {
     typedef _Arg    argument_type;
     typedef _Result result_type;
 };
 
 template <class _Arg1, class _Arg2, class _Result>
-struct _LIBCPP_TYPE_VIS binary_function
+struct _LIBCPP_TYPE_VIS_ONLY binary_function
 {
     typedef _Arg1   first_argument_type;
     typedef _Arg2   second_argument_type;
     typedef _Result result_type;
 };
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS hash;
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;
 
 template <class _Tp>
 struct __has_result_type
@@ -50,13 +51,80 @@
     static const bool value = sizeof(__test<_Tp>(0)) == 1;
 };
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS less : binary_function<_Tp, _Tp, bool>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY less : binary_function<_Tp, _Tp, bool>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x < __y;}
 };
 
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY less<void>
+{
+    template <class _T1, class _T2> 
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+// addressof
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+addressof(_Tp& __x) _NOEXCEPT
+{
+    return (_Tp*)&reinterpret_cast<const volatile char&>(__x);
+}
+
+#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)
+// Objective-C++ Automatic Reference Counting uses qualified pointers
+// that require special addressof() signatures. When
+// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
+// itself is providing these definitions. Otherwise, we provide them.
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__strong _Tp*
+addressof(__strong _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+
+#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__weak _Tp*
+addressof(__weak _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+#endif
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__autoreleasing _Tp*
+addressof(__autoreleasing _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__unsafe_unretained _Tp*
+addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+#endif
+
 #ifdef _LIBCPP_HAS_NO_VARIADICS
 
 #include <__functional_base_03>
@@ -292,7 +360,8 @@
 
 // bullets 1 and 2
 
-template <class _Fp, class _A0, class ..._Args>
+template <class _Fp, class _A0, class ..._Args,
+            class>
 inline _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
@@ -301,7 +370,8 @@
     return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...);
 }
 
-template <class _Fp, class _A0, class ..._Args>
+template <class _Fp, class _A0, class ..._Args,
+            class>
 inline _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
@@ -312,7 +382,8 @@
 
 // bullets 3 and 4
 
-template <class _Fp, class _A0>
+template <class _Fp, class _A0,
+            class>
 inline _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0)
@@ -321,7 +392,8 @@
     return _VSTD::forward<_A0>(__a0).*__f;
 }
 
-template <class _Fp, class _A0>
+template <class _Fp, class _A0,
+            class>
 inline _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0)
@@ -348,7 +420,7 @@
 };
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS reference_wrapper
+class _LIBCPP_TYPE_VIS_ONLY reference_wrapper
     : public __weak_result_type<_Tp>
 {
 public:
@@ -359,7 +431,8 @@
 
 public:
     // construct/copy/destroy
-    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT : __f_(&__f) {}
+    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT
+        : __f_(_VSTD::addressof(__f)) {}
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
 #endif
@@ -432,6 +505,111 @@
 
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp1, class _Tp2 = void>
+struct __is_transparent
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::is_transparent* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp1>(0)) == 1;
+};
+#endif
+
+// allocator_arg_t
+
+struct _LIBCPP_TYPE_VIS_ONLY allocator_arg_t { };
+
+#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
+extern const allocator_arg_t allocator_arg;
+#else
+constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+#endif
+
+// uses_allocator
+
+template <class _Tp>
+struct __has_allocator_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
+struct __uses_allocator
+    : public integral_constant<bool,
+        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
+{
+};
+
+template <class _Tp, class _Alloc>
+struct __uses_allocator<_Tp, _Alloc, false>
+    : public false_type
+{
+};
+
+template <class _Tp, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator
+    : public __uses_allocator<_Tp, _Alloc>
+{
+};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+// allocator construction
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor_imp
+{
+    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
+    static const bool __ic =
+        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
+    static const int value = __ua ? 2 - __ic : 0;
+};
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor
+    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
+    {};
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
+{
+    new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+    new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
+{ 
+    __user_alloc_construct_impl( 
+             __uses_alloc_ctor<_Tp, _Allocator>(), 
+             __storage, __a, _VSTD::forward<_Args>(__args)...
+        );
+}
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_FUNCTIONAL_BASE
diff --git a/include/__functional_base_03 b/include/__functional_base_03
index 11165a9..296dd8d 100644
--- a/include/__functional_base_03
+++ b/include/__functional_base_03
@@ -996,7 +996,7 @@
 };
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS reference_wrapper
+class _LIBCPP_TYPE_VIS_ONLY reference_wrapper
     : public __weak_result_type<_Tp>
 {
 public:
diff --git a/include/__hash_table b/include/__hash_table
index 6f6050d..4c4feb0 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -20,6 +20,12 @@
 
 #include <__undef_min_max>
 
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -33,7 +39,6 @@
 struct __hash_node_base
 {
     typedef __hash_node_base __first_node;
- //   typedef _NodePtr pointer;
 
     _NodePtr    __next_;
 
@@ -80,14 +85,14 @@
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
-template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS __hash_const_iterator;
-template <class _HashIterator> class _LIBCPP_TYPE_VIS __hash_map_iterator;
-template <class _HashIterator> class _LIBCPP_TYPE_VIS __hash_map_const_iterator;
+template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
+template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
-    class _LIBCPP_TYPE_VIS unordered_map;
+    class _LIBCPP_TYPE_VIS_ONLY unordered_map;
 
 template <class _NodePtr>
-class _LIBCPP_TYPE_VIS __hash_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_iterator
 {
     typedef _NodePtr __node_pointer;
 
@@ -106,16 +111,70 @@
 #endif
                                                          pointer;
 
-    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __node_(nullptr)
+#endif
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const {return __node_->__value_;}
+    __hash_iterator(const __hash_iterator& __i)
+        : __node_(__i.__node_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
     _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const {return _VSTD::addressof(__node_->__value_);}
+    ~__hash_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator& operator=(const __hash_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_iterator& operator++()
     {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container iterator");
+#endif
         __node_ = __node_->__next_;
         return *this;
     }
@@ -130,26 +189,37 @@
 
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)
-        {return __x.__node_ == __y.__node_;}
+    {
+        return __x.__node_ == __y.__node_;
+    }
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)
-        {return __x.__node_ != __y.__node_;}
+        {return !(__x == __y);}
 
 private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator(__node_pointer __node, const void* __c) _NOEXCEPT
+        : __node_(__node)
+        {
+            __get_db()->__insert_ic(this, __c);
+        }
+#else
     _LIBCPP_INLINE_VISIBILITY
     __hash_iterator(__node_pointer __node) _NOEXCEPT
         : __node_(__node)
         {}
+#endif
 
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_map_iterator;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
 };
 
 template <class _ConstNodePtr>
-class _LIBCPP_TYPE_VIS __hash_const_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator
 {
     typedef _ConstNodePtr __node_pointer;
 
@@ -180,20 +250,78 @@
                                                       __non_const_node_pointer;
     typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator;
 
-    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __node_(nullptr)
+#endif
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
     _LIBCPP_INLINE_VISIBILITY 
     __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
         : __node_(__x.__node_)
-        {}
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__iterator_copy(this, &__x);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const {return __node_->__value_;}
+    __hash_const_iterator(const __hash_const_iterator& __i)
+        : __node_(__i.__node_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
     _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const {return _VSTD::addressof(__node_->__value_);}
+    ~__hash_const_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator& operator=(const __hash_const_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_iterator& operator++()
     {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container const_iterator");
+#endif
         __node_ = __node_->__next_;
         return *this;
     }
@@ -208,27 +336,38 @@
 
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
-        {return __x.__node_ == __y.__node_;}
+    {
+        return __x.__node_ == __y.__node_;
+    }
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
-        {return __x.__node_ != __y.__node_;}
+        {return !(__x == __y);}
 
 private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator(__node_pointer __node, const void* __c) _NOEXCEPT
+        : __node_(__node)
+        {
+            __get_db()->__insert_ic(this, __c);
+        }
+#else
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_iterator(__node_pointer __node) _NOEXCEPT
         : __node_(__node)
         {}
+#endif
 
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_map_const_iterator;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
 };
 
-template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS __hash_const_local_iterator;
+template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
 
 template <class _NodePtr>
-class _LIBCPP_TYPE_VIS __hash_local_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator
 {
     typedef _NodePtr __node_pointer;
 
@@ -250,16 +389,71 @@
 #endif
                                                                 pointer;
 
-    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const {return __node_->__value_;}
+    __hash_local_iterator(const __hash_local_iterator& __i)
+        : __node_(__i.__node_),
+          __bucket_(__i.__bucket_),
+          __bucket_count_(__i.__bucket_count_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
     _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const {return &__node_->__value_;}
+    ~__hash_local_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator& operator=(const __hash_local_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+            __bucket_ = __i.__bucket_;
+            __bucket_count_ = __i.__bucket_count_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_local_iterator& operator++()
     {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container local_iterator");
+#endif
         __node_ = __node_->__next_;
         if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
             __node_ = nullptr;
@@ -276,12 +470,27 @@
 
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
-        {return __x.__node_ == __y.__node_;}
+    {
+        return __x.__node_ == __y.__node_;
+    }
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
-        {return __x.__node_ != __y.__node_;}
+        {return !(__x == __y);}
 
 private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator(__node_pointer __node, size_t __bucket,
+                          size_t __bucket_count, const void* __c) _NOEXCEPT
+        : __node_(__node),
+          __bucket_(__bucket),
+          __bucket_count_(__bucket_count)
+        {
+            __get_db()->__insert_ic(this, __c);
+            if (__node_ != nullptr)
+                __node_ = __node_->__next_;
+        }
+#else
     _LIBCPP_INLINE_VISIBILITY
     __hash_local_iterator(__node_pointer __node, size_t __bucket,
                           size_t __bucket_count) _NOEXCEPT
@@ -292,14 +501,14 @@
             if (__node_ != nullptr)
                 __node_ = __node_->__next_;
         }
-
+#endif
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_local_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_map_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
 };
 
 template <class _ConstNodePtr>
-class _LIBCPP_TYPE_VIS __hash_const_local_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator
 {
     typedef _ConstNodePtr __node_pointer;
 
@@ -334,22 +543,82 @@
 #endif
                                                        pointer;
 
-    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
         : __node_(__x.__node_),
           __bucket_(__x.__bucket_),
           __bucket_count_(__x.__bucket_count_)
-        {}
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__iterator_copy(this, &__x);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
 
     _LIBCPP_INLINE_VISIBILITY
-        reference operator*() const {return __node_->__value_;}
+    __hash_const_local_iterator(const __hash_const_local_iterator& __i)
+        : __node_(__i.__node_),
+          __bucket_(__i.__bucket_),
+          __bucket_count_(__i.__bucket_count_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
     _LIBCPP_INLINE_VISIBILITY
-        pointer operator->() const {return &__node_->__value_;}
+    ~__hash_const_local_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+            __bucket_ = __i.__bucket_;
+            __bucket_count_ = __i.__bucket_count_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_local_iterator& operator++()
     {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container const_local_iterator");
+#endif
         __node_ = __node_->__next_;
         if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
             __node_ = nullptr;
@@ -366,12 +635,27 @@
 
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
-        {return __x.__node_ == __y.__node_;}
+    {
+        return __x.__node_ == __y.__node_;
+    }
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
-        {return __x.__node_ != __y.__node_;}
+        {return !(__x == __y);}
 
 private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator(__node_pointer __node, size_t __bucket,
+                                size_t __bucket_count, const void* __c) _NOEXCEPT
+        : __node_(__node),
+          __bucket_(__bucket),
+          __bucket_count_(__bucket_count)
+        {
+            __get_db()->__insert_ic(this, __c);
+            if (__node_ != nullptr)
+                __node_ = __node_->__next_;
+        }
+#else
     _LIBCPP_INLINE_VISIBILITY
     __hash_const_local_iterator(__node_pointer __node, size_t __bucket,
                                 size_t __bucket_count) _NOEXCEPT
@@ -382,9 +666,9 @@
             if (__node_ != nullptr)
                 __node_ = __node_->__next_;
         }
-
+#endif
     template <class, class, class, class> friend class __hash_table;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_map_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
 };
 
 template <class _Alloc>
@@ -505,8 +789,15 @@
                                                      __node_allocator;
     typedef allocator_traits<__node_allocator>       __node_traits;
     typedef typename __node_traits::pointer          __node_pointer;
-    typedef typename __node_traits::const_pointer    __node_const_pointer;
+    typedef typename __node_traits::pointer          __node_const_pointer;
     typedef __hash_node_base<__node_pointer>         __first_node;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__first_node>
+#else
+            rebind<__first_node>::other
+#endif
+                                                     __node_base_pointer;
 
 private:
 
@@ -558,9 +849,9 @@
 
 public:
     typedef __hash_iterator<__node_pointer>                   iterator;
-    typedef __hash_const_iterator<__node_const_pointer>       const_iterator;
+    typedef __hash_const_iterator<__node_pointer>             const_iterator;
     typedef __hash_local_iterator<__node_pointer>             local_iterator;
-    typedef __hash_const_local_iterator<__node_const_pointer> const_local_iterator;
+    typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;
 
     __hash_table()
         _NOEXCEPT_(
@@ -658,7 +949,11 @@
     template <class _Key>
         _LIBCPP_INLINE_VISIBILITY
         size_type bucket(const _Key& __k) const
-            {return __constrain_hash(hash_function()(__k), bucket_count());}
+        {
+            _LIBCPP_ASSERT(bucket_count() > 0,
+                "unordered container::bucket(key) called when bucket_count() == 0");
+            return __constrain_hash(hash_function()(__k), bucket_count());
+        }
 
     template <class _Key>
         iterator       find(const _Key& __x);
@@ -706,7 +1001,7 @@
 
     _LIBCPP_INLINE_VISIBILITY
     size_type max_bucket_count() const _NOEXCEPT
-        {return __bucket_list_.get_deleter().__alloc().max_size();}
+        {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());}
     size_type bucket_size(size_type __n) const;
     _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
     {
@@ -714,16 +1009,73 @@
         return __bc != 0 ? (float)size() / __bc : 0.f;
     }
     _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
-        {max_load_factor() = _VSTD::max(__mlf, load_factor());}
+    {
+        _LIBCPP_ASSERT(__mlf > 0,
+            "unordered container::max_load_factor(lf) called with lf <= 0");
+        max_load_factor() = _VSTD::max(__mlf, load_factor());
+    }
 
-    _LIBCPP_INLINE_VISIBILITY local_iterator       begin(size_type __n)
-        {return local_iterator(__bucket_list_[__n], __n, bucket_count());}
-    _LIBCPP_INLINE_VISIBILITY local_iterator       end(size_type __n)
-        {return local_iterator(nullptr, __n, bucket_count());}
-    _LIBCPP_INLINE_VISIBILITY const_local_iterator cbegin(size_type __n) const
-        {return const_local_iterator(__bucket_list_[__n], __n, bucket_count());}
-    _LIBCPP_INLINE_VISIBILITY const_local_iterator cend(size_type __n) const
-        {return const_local_iterator(nullptr, __n, bucket_count());}
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator
+    begin(size_type __n)
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::begin(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
+#else
+        return local_iterator(__bucket_list_[__n], __n, bucket_count());
+#endif
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator
+    end(size_type __n)
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::end(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return local_iterator(nullptr, __n, bucket_count(), this);
+#else
+        return local_iterator(nullptr, __n, bucket_count());
+#endif
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator
+    cbegin(size_type __n) const
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::cbegin(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
+#else
+        return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
+#endif
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator
+    cend(size_type __n) const
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::cend(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return const_local_iterator(nullptr, __n, bucket_count(), this);
+#else
+        return const_local_iterator(nullptr, __n, bucket_count());
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 private:
     void __rehash(size_type __n);
 
@@ -807,6 +1159,9 @@
 
     void __deallocate(__node_pointer __np) _NOEXCEPT;
     __node_pointer __detach() _NOEXCEPT;
+
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
 };
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -893,7 +1248,7 @@
     if (size() > 0)
     {
         __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-            static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
         __u.__p1_.first().__next_ = nullptr;
         __u.size() = 0;
     }
@@ -917,7 +1272,7 @@
             __p1_.first().__next_ = __u.__p1_.first().__next_;
             __u.__p1_.first().__next_ = nullptr;
             __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-                static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
+                static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
             size() = __u.size();
             __u.size() = 0;
         }
@@ -930,6 +1285,9 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
 {
     __deallocate(__p1_.first().__next_);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__erase_c(this);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -971,6 +1329,21 @@
     while (__np != nullptr)
     {
         __node_pointer __next = __np->__next_;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __c_node* __c = __get_db()->__find_c_and_lock(this);
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
+        {
+            --__p;
+            iterator* __i = static_cast<iterator*>((*__p)->__i_);
+            if (__i->__node_ == __np)
+            {
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __get_db()->unlock();
+#endif
         __node_traits::destroy(__na, _VSTD::addressof(__np->__value_));
         __node_traits::deallocate(__na, __np, 1);
         __np = __next;
@@ -1014,10 +1387,13 @@
     if (size() > 0)
     {
         __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-            static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
         __u.__p1_.first().__next_ = nullptr;
         __u.size() = 0;
     }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->swap(this, &__u);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1158,7 +1534,11 @@
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__p1_.first().__next_, this);
+#else
     return iterator(__p1_.first().__next_);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1166,7 +1546,11 @@
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(nullptr, this);
+#else
     return iterator(nullptr);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1174,7 +1558,11 @@
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return const_iterator(__p1_.first().__next_, this);
+#else
     return const_iterator(__p1_.first().__next_);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1182,7 +1570,11 @@
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return const_iterator(nullptr, this);
+#else
     return const_iterator(nullptr);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1236,7 +1628,7 @@
         __node_pointer __pn = __bucket_list_[__chash];
         if (__pn == nullptr)
         {
-            __pn = static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
+            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
             __nd->__next_ = __pn->__next_;
             __pn->__next_ = __nd;
             // fix up __bucket_list_
@@ -1255,7 +1647,11 @@
         __inserted = true;
     }
 __done:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return pair<iterator, bool>(iterator(__ndptr, this), __inserted);
+#else
     return pair<iterator, bool>(iterator(__ndptr), __inserted);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1274,7 +1670,7 @@
     __node_pointer __pn = __bucket_list_[__chash];
     if (__pn == nullptr)
     {
-        __pn = static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
+        __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
         __cp->__next_ = __pn->__next_;
         __pn->__next_ = __cp;
         // fix up __bucket_list_
@@ -1312,7 +1708,11 @@
         }
     }
     ++size();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__cp, this);
+#else
     return iterator(__cp);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1320,9 +1720,14 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
         const_iterator __p, __node_pointer __cp)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
+        " referring to this unordered container");
+#endif
     if (__p != end() && key_eq()(*__p, __cp->__value_))
     {
-        __node_pointer __np = const_cast<__node_pointer>(__p.__node_);
+        __node_pointer __np = __p.__node_;
         __cp->__hash_ = __np->__hash_;
         size_type __bc = bucket_count();
         if (size()+1 > __bc * max_load_factor() || __bc == 0)
@@ -1338,7 +1743,11 @@
         __cp->__next_ = __np;
         __pp->__next_ = __cp;
         ++size();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return iterator(__cp, this);
+#else
         return iterator(__cp);
+#endif
     }
     return __node_insert_multi(__cp);
 }
@@ -1380,7 +1789,7 @@
         __node_pointer __pn = __bucket_list_[__chash];
         if (__pn == nullptr)
         {
-            __pn = static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
+            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
             __h->__next_ = __pn->__next_;
             __pn->__next_ = __h.get();
             // fix up __bucket_list_
@@ -1399,7 +1808,11 @@
         __inserted = true;
     }
 __done:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return pair<iterator, bool>(iterator(__nd, this), __inserted);
+#else
     return pair<iterator, bool>(iterator(__nd), __inserted);
+#endif
 }
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1434,6 +1847,11 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
         const_iterator __p, _Args&&... __args)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
+        " referring to this unordered container");
+#endif
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     iterator __r = __node_insert_multi(__p, __h.get());
     __h.release();
@@ -1475,6 +1893,11 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
                                                          _Pp&& __x)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::insert(const_iterator, rvalue) called with an iterator not"
+        " referring to this unordered container");
+#endif
     __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
     iterator __r = __node_insert_multi(__p, __h.get());
     __h.release();
@@ -1498,6 +1921,11 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
                                                          const value_type& __x)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::insert(const_iterator, lvalue) called with an iterator not"
+        " referring to this unordered container");
+#endif
     __node_holder __h = __construct_node(__x);
     iterator __r = __node_insert_multi(__p, __h.get());
     __h.release();
@@ -1534,6 +1962,9 @@
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__invalidate_all(this);
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
     __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
     __bucket_list_.reset(__nbc > 0 ?
                       __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
@@ -1542,7 +1973,7 @@
     {
         for (size_type __i = 0; __i < __nbc; ++__i)
             __bucket_list_[__i] = nullptr;
-        __node_pointer __pp(static_cast<__node_pointer>(_VSTD::addressof(__p1_.first())));
+        __node_pointer __pp(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())));
         __node_pointer __cp = __pp->__next_;
         if (__cp != nullptr)
         {
@@ -1599,7 +2030,11 @@
                                                            __nd = __nd->__next_)
             {
                 if (key_eq()(__nd->__value_, __k))
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                    return iterator(__nd, this);
+#else
                     return iterator(__nd);
+#endif
             }
         }
     }
@@ -1624,7 +2059,11 @@
                                                            __nd = __nd->__next_)
             {
                 if (key_eq()(__nd->__value_, __k))
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                    return const_iterator(__nd, this);
+#else
                     return const_iterator(__nd);
+#endif
             }
         }
 
@@ -1662,7 +2101,7 @@
     __h.get_deleter().__value_constructed = true;
     __h->__hash_ = __hash;
     __h->__next_ = nullptr;
-    return _VSTD::move(__h);
+    return __h;
 }
 
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1677,7 +2116,7 @@
     __h.get_deleter().__value_constructed = true;
     __h->__hash_ = hash_function()(__h->__value_);
     __h->__next_ = nullptr;
-    return _VSTD::move(__h);
+    return _VSTD::move(__h);  // explicitly moved for C++03
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1693,15 +2132,24 @@
     __h.get_deleter().__value_constructed = true;
     __h->__hash_ = __hash;
     __h->__next_ = nullptr;
-    return _VSTD::move(__h);
+    return _VSTD::move(__h);  // explicitly moved for C++03
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
 {
-    __node_pointer __np = const_cast<__node_pointer>(__p.__node_);
+    __node_pointer __np = __p.__node_;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container erase(iterator) called with an iterator not"
+        " referring to this container");
+    _LIBCPP_ASSERT(__p != end(),
+        "unordered container erase(iterator) called with a non-dereferenceable iterator");
+    iterator __r(__np, this);
+#else
     iterator __r(__np);
+#endif
     ++__r;
     remove(__p);
     return __r;
@@ -1712,13 +2160,25 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
                                                 const_iterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+        "unodered container::erase(iterator, iterator) called with an iterator not"
+        " referring to this unodered container");
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,
+        "unodered container::erase(iterator, iterator) called with an iterator not"
+        " referring to this unodered container");
+#endif
     for (const_iterator __p = __first; __first != __last; __p = __first)
     {
         ++__first;
         erase(__p);
     }
-    __node_pointer __np = const_cast<__node_pointer>(__last.__node_);
+    __node_pointer __np = __last.__node_;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator (__np, this);
+#else
     return iterator (__np);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
@@ -1757,7 +2217,7 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
 {
     // current node
-    __node_pointer __cn = const_cast<__node_pointer>(__p.__node_);
+    __node_pointer __cn = __p.__node_;
     size_type __bc = bucket_count();
     size_t __chash = __constrain_hash(__cn->__hash_, __bc);
     // find previous node
@@ -1767,7 +2227,8 @@
     // Fix up __bucket_list_
         // if __pn is not in same bucket (before begin is not in same bucket) &&
         //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
-    if (__pn == _VSTD::addressof(__p1_.first()) || __constrain_hash(__pn->__hash_, __bc) != __chash)
+    if (__pn == static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))
+                            || __constrain_hash(__pn->__hash_, __bc) != __chash)
     {
         if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash)
             __bucket_list_[__chash] = nullptr;
@@ -1783,6 +2244,21 @@
     __pn->__next_ = __cn->__next_;
     __cn->__next_ = nullptr;
     --size();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    for (__i_node** __p = __c->end_; __p != __c->beg_; )
+    {
+        --__p;
+        iterator* __i = static_cast<iterator*>((*__p)->__i_);
+        if (__i->__node_ == __cn)
+        {
+            (*__p)->__c_ = nullptr;
+            if (--__c->end_ != __p)
+                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+        }
+    }
+    __get_db()->unlock();
+#endif
     return __node_holder(__cn, _Dp(__node_alloc(), true));
 }
 
@@ -1907,16 +2383,21 @@
     __p3_.swap(__u.__p3_);
     if (size() > 0)
         __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
-            static_cast<__node_pointer>(_VSTD::addressof(__p1_.first()));
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
     if (__u.size() > 0)
         __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] =
-            static_cast<__node_pointer>(_VSTD::addressof(__u.__p1_.first()));
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__u.__p1_.first()));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->swap(this, &__u);
+#endif
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
 {
+    _LIBCPP_ASSERT(__n < bucket_count(),
+        "unordered container::bucket_size(n) called with n >= bucket_count()");
     __node_const_pointer __np = __bucket_list_[__n];
     size_type __bc = bucket_count();
     size_type __r = 0;
@@ -1940,6 +2421,37 @@
     __x.swap(__y);
 }
 
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const
+{
+    return __i->__node_ != nullptr;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const
+{
+    return false;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
+{
+    return false;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
+{
+    return false;
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP__HASH_TABLE
diff --git a/include/__locale b/include/__locale
index 29b1b48..e78c8ee 100644
--- a/include/__locale
+++ b/include/__locale
@@ -19,11 +19,13 @@
 #include <cstdint>
 #include <cctype>
 #include <locale.h>
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
 # include <support/win32/locale_win32.h>
-#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)) || defined(EMSCRIPTEN)
+#elif _AIX
+# include <support/ibm/xlocale.h>
+#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)) || defined(EMSCRIPTEN) || defined(__IBMCPP__)
 # include <xlocale.h>
-#endif  // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || EMSCRIPTEN
+#endif  // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || EMSCRIPTEN || __IBMCPP__
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -235,7 +237,7 @@
 // template <class _CharT> class collate;
 
 template <class _CharT>
-class _LIBCPP_TYPE_VIS collate
+class _LIBCPP_TYPE_VIS_ONLY collate
     : public locale::facet
 {
 public:
@@ -314,12 +316,12 @@
     return static_cast<long>(__h);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS collate<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS collate<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
 
 // template <class CharT> class collate_byname;
 
-template <class _CharT> class _LIBCPP_TYPE_VIS collate_byname;
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;
 
 template <>
 class _LIBCPP_TYPE_VIS collate_byname<char>
@@ -399,12 +401,12 @@
     static const mask punct  = _PUNCT;
     static const mask xdigit = _HEX;
     static const mask blank  = _BLANK;
-#elif (defined(__APPLE__) || defined(__FreeBSD__)) || defined(EMSCRIPTEN)
+#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(EMSCRIPTEN) || defined(__NetBSD__)
 #ifdef __APPLE__
     typedef __uint32_t mask;
 #elif defined(__FreeBSD__)
     typedef unsigned long mask;
-#elif defined(EMSCRIPTEN)
+#elif defined(EMSCRIPTEN) ||  defined(__NetBSD__)
     typedef unsigned short mask;
 #endif
     static const mask space  = _CTYPE_S;
@@ -416,8 +418,12 @@
     static const mask digit  = _CTYPE_D;
     static const mask punct  = _CTYPE_P;
     static const mask xdigit = _CTYPE_X;
+# if defined(__NetBSD__)
+    static const mask blank  = _CTYPE_BL;
+# else
     static const mask blank  = _CTYPE_B;
-#elif defined(__sun__)
+# endif
+#elif defined(__sun__) || defined(_AIX)
     typedef unsigned int mask;
     static const mask space  = _ISSPACE;
     static const mask print  = _ISPRINT;
@@ -463,7 +469,7 @@
     _LIBCPP_ALWAYS_INLINE ctype_base() {}
 };
 
-template <class _CharT> class _LIBCPP_TYPE_VIS ctype;
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
 
 template <>
 class _LIBCPP_TYPE_VIS ctype<wchar_t>
@@ -581,7 +587,7 @@
     _LIBCPP_ALWAYS_INLINE
     bool is(mask __m, char_type __c) const
     {
-        return isascii(__c) ? __tab_[static_cast<int>(__c)] & __m : false;
+        return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
     }
 
     _LIBCPP_ALWAYS_INLINE
@@ -671,6 +677,10 @@
     static const int* __classic_upper_table() _NOEXCEPT;
     static const int* __classic_lower_table() _NOEXCEPT;
 #endif
+#if defined(__NetBSD__)
+    static const short* __classic_upper_table() _NOEXCEPT;
+    static const short* __classic_lower_table() _NOEXCEPT;
+#endif
 
 protected:
     ~ctype();
@@ -686,7 +696,7 @@
 
 // template <class CharT> class ctype_byname;
 
-template <class _CharT> class _LIBCPP_TYPE_VIS ctype_byname;
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype_byname;
 
 template <>
 class _LIBCPP_TYPE_VIS ctype_byname<char>
@@ -847,7 +857,7 @@
 
 // template <class internT, class externT, class stateT> class codecvt;
 
-template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS codecvt;
+template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS_ONLY codecvt;
 
 // template <> class codecvt<char, char, mbstate_t>
 
@@ -1193,7 +1203,7 @@
 // template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
 
 template <class _InternT, class _ExternT, class _StateT>
-class _LIBCPP_TYPE_VIS codecvt_byname
+class _LIBCPP_TYPE_VIS_ONLY codecvt_byname
     : public codecvt<_InternT, _ExternT, _StateT>
 {
 public:
@@ -1212,10 +1222,10 @@
 {
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<char, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<wchar_t, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<char16_t, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<char32_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
 
 _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
 
@@ -1401,7 +1411,7 @@
 
 // template <class charT> class numpunct
 
-template <class _CharT> class _LIBCPP_TYPE_VIS numpunct;
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct;
 
 template <>
 class _LIBCPP_TYPE_VIS numpunct<char>
@@ -1467,7 +1477,7 @@
 
 // template <class charT> class numpunct_byname
 
-template <class charT> class _LIBCPP_TYPE_VIS numpunct_byname;
+template <class charT> class _LIBCPP_TYPE_VIS_ONLY numpunct_byname;
 
 template <>
 class _LIBCPP_TYPE_VIS numpunct_byname<char>
diff --git a/include/__mutex_base b/include/__mutex_base
index 0583df9..d4023a6 100644
--- a/include/__mutex_base
+++ b/include/__mutex_base
@@ -20,16 +20,6 @@
 #pragma GCC system_header
 #endif
 
-#ifdef _LIBCPP_SHARED_LOCK
-
-namespace ting {
-template <class _Mutex> class shared_lock;
-template <class _Mutex> class upgrade_lock;
-}
-
-#endif  // _LIBCPP_SHARED_LOCK
-
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 class _LIBCPP_TYPE_VIS mutex
@@ -77,7 +67,7 @@
 #endif
 
 template <class _Mutex>
-class _LIBCPP_TYPE_VIS lock_guard
+class _LIBCPP_TYPE_VIS_ONLY lock_guard
 {
 public:
     typedef _Mutex mutex_type;
@@ -101,7 +91,7 @@
 };
 
 template <class _Mutex>
-class _LIBCPP_TYPE_VIS unique_lock
+class _LIBCPP_TYPE_VIS_ONLY unique_lock
 {
 public:
     typedef _Mutex mutex_type;
@@ -162,27 +152,6 @@
             return *this;
         }
 
-#ifdef _LIBCPP_SHARED_LOCK
-
-    unique_lock(ting::shared_lock<mutex_type>&&, try_to_lock_t);
-    template <class _Clock, class _Duration>
-        unique_lock(ting::shared_lock<mutex_type>&&,
-                    const chrono::time_point<_Clock, _Duration>&);
-    template <class _Rep, class _Period>
-        unique_lock(ting::shared_lock<mutex_type>&&,
-                    const chrono::duration<_Rep, _Period>&);
-
-    explicit unique_lock(ting::upgrade_lock<mutex_type>&&);
-    unique_lock(ting::upgrade_lock<mutex_type>&&, try_to_lock_t);
-    template <class _Clock, class _Duration>
-        unique_lock(ting::upgrade_lock<mutex_type>&&,
-                    const chrono::time_point<_Clock, _Duration>&);
-    template <class _Rep, class _Period>
-        unique_lock(ting::upgrade_lock<mutex_type>&&,
-                    const chrono::duration<_Rep, _Period>&);
-
-#endif  // _LIBCPP_SHARED_LOCK
-
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
     void lock();
diff --git a/include/__split_buffer b/include/__split_buffer
index e0aa13b..1d529cb 100644
--- a/include/__split_buffer
+++ b/include/__split_buffer
@@ -285,16 +285,16 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)
 {
     while (__begin_ != __new_begin)
-        __alloc_traits::destroy(__alloc(), __begin_++);
+        __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++));
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)
 {
@@ -302,16 +302,16 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT
 {
     while (__new_last != __end_)
-        __alloc_traits::destroy(__alloc(), --__end_);
+        __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_));
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT
 {
@@ -320,7 +320,7 @@
 
 template <class _Tp, class _Allocator>
 __split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
-    : __end_cap_(0, __a)
+    : __end_cap_(nullptr, __a)
 {
     __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr;
     __begin_ = __end_ = __first_ + __start;
@@ -328,24 +328,24 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 __split_buffer<_Tp, _Allocator>::__split_buffer()
     _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-    : __first_(0), __begin_(0), __end_(0), __end_cap_(0)
+    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr)
 {
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 __split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
-    : __first_(0), __begin_(0), __end_(0), __end_cap_(0, __a)
+    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
 {
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 __split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
-    : __first_(0), __begin_(0), __end_(0), __end_cap_(0, __a)
+    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
 {
 }
 
@@ -541,7 +541,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 __split_buffer<_Tp, _Allocator>::push_back(const_reference __x)
 {
@@ -640,7 +640,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y)
         _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
diff --git a/include/__std_stream b/include/__std_stream
index 8ca413e..5403ada 100644
--- a/include/__std_stream
+++ b/include/__std_stream
@@ -55,6 +55,8 @@
     const codecvt<char_type, char, state_type>* __cv_;
     state_type* __st_;
     int __encoding_;
+    int_type __last_consumed_;
+    bool __last_consumed_is_next_;
     bool __always_noconv_;
 
     __stdinbuf(const __stdinbuf&);
@@ -66,7 +68,9 @@
 template <class _CharT>
 __stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
     : __file_(__fp),
-      __st_(__st)
+      __st_(__st),
+      __last_consumed_(traits_type::eof()),
+      __last_consumed_is_next_(false)
 {
     imbue(this->getloc());
 }
@@ -100,6 +104,16 @@
 typename __stdinbuf<_CharT>::int_type
 __stdinbuf<_CharT>::__getchar(bool __consume)
 {
+    if (__last_consumed_is_next_)
+    {
+        int_type __result = __last_consumed_;
+        if (__consume)
+        {
+            __last_consumed_ = traits_type::eof();
+            __last_consumed_is_next_ = false;
+        }
+        return __result;
+    }
     char __extbuf[__limit];
     int __nread = _VSTD::max(1, __encoding_);
     for (int __i = 0; __i < __nread; ++__i)
@@ -154,6 +168,8 @@
                 return traits_type::eof();
         }
     }
+    else
+        __last_consumed_ = traits_type::to_int_type(__1buf);
     return traits_type::to_int_type(__1buf);
 }
 
@@ -162,28 +178,41 @@
 __stdinbuf<_CharT>::pbackfail(int_type __c)
 {
     if (traits_type::eq_int_type(__c, traits_type::eof()))
-        return __c;
-    char __extbuf[__limit];
-    char* __enxt;
-    const char_type __ci = traits_type::to_char_type(__c);
-    const char_type* __inxt;
-    switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
-                              __extbuf, __extbuf + sizeof(__extbuf), __enxt))
     {
-    case _VSTD::codecvt_base::ok:
-        break;
-    case _VSTD::codecvt_base::noconv:
-        __extbuf[0] = static_cast<char>(__c);
-        __enxt = __extbuf + 1;
-        break;
-    case codecvt_base::partial:
-    case codecvt_base::error:
-        return traits_type::eof();
+        if (!__last_consumed_is_next_)
+        {
+            __c = __last_consumed_;
+            __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_,
+                                                                 traits_type::eof());
+        }
+        return __c;
     }
-    while (__enxt > __extbuf)
-        if (ungetc(*--__enxt, __file_) == EOF)
+    if (__last_consumed_is_next_)
+    {
+        char __extbuf[__limit];
+        char* __enxt;
+        const char_type __ci = traits_type::to_char_type(__last_consumed_);
+        const char_type* __inxt;
+        switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
+                                  __extbuf, __extbuf + sizeof(__extbuf), __enxt))
+        {
+        case _VSTD::codecvt_base::ok:
+            break;
+        case _VSTD::codecvt_base::noconv:
+            __extbuf[0] = static_cast<char>(__last_consumed_);
+            __enxt = __extbuf + 1;
+            break;
+        case codecvt_base::partial:
+        case codecvt_base::error:
             return traits_type::eof();
- return traits_type::not_eof(__c);
+        }
+        while (__enxt > __extbuf)
+            if (ungetc(*--__enxt, __file_) == EOF)
+                return traits_type::eof();
+    }
+    __last_consumed_ = __c;
+    __last_consumed_is_next_ = true;
+    return __c;
 }
 
 // __stdoutbuf
@@ -204,6 +233,7 @@
 
 protected:
     virtual int_type overflow (int_type __c = traits_type::eof());
+    virtual streamsize xsputn(const char_type* __s, streamsize __n);
     virtual int sync();
     virtual void imbue(const locale& __loc);
 
@@ -234,30 +264,31 @@
     char_type __1buf;
     if (!traits_type::eq_int_type(__c, traits_type::eof()))
     {
-        this->setp(&__1buf, &__1buf+1);
-        *this->pptr() = traits_type::to_char_type(__c);
-        this->pbump(1);
+        __1buf = traits_type::to_char_type(__c);
         if (__always_noconv_)
         {
-            if (fwrite(this->pbase(), sizeof(char_type), 1, __file_) != 1)
+            if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1)
                 return traits_type::eof();
         }
         else
         {
             char* __extbe = __extbuf;
             codecvt_base::result __r;
+            char_type* pbase = &__1buf;
+            char_type* pptr = pbase + 1;
+            char_type* epptr = pptr;
             do
             {
                 const char_type* __e;
-                __r = __cv_->out(*__st_, this->pbase(), this->pptr(), __e,
+                __r = __cv_->out(*__st_, pbase, pptr, __e,
                                         __extbuf,
                                         __extbuf + sizeof(__extbuf),
                                         __extbe);
-                if (__e == this->pbase())
+                if (__e == pbase)
                     return traits_type::eof();
                 if (__r == codecvt_base::noconv)
                 {
-                    if (fwrite(this->pbase(), 1, 1, __file_) != 1)
+                    if (fwrite(pbase, 1, 1, __file_) != 1)
                         return traits_type::eof();
                 }
                 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
@@ -267,20 +298,31 @@
                         return traits_type::eof();
                     if (__r == codecvt_base::partial)
                     {
-                        this->setp((char_type*)__e, this->pptr());
-                        this->pbump(static_cast<int>(this->epptr() - this->pbase()));
+                        pbase = (char_type*)__e;
                     }
                 }
                 else
                     return traits_type::eof();
             } while (__r == codecvt_base::partial);
         }
-        this->setp(0, 0);
     }
     return traits_type::not_eof(__c);
 }
 
 template <class _CharT>
+streamsize
+__stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n)
+{
+    if (__always_noconv_)
+        return fwrite(__s, sizeof(char_type), __n, __file_);
+    streamsize __i = 0;
+    for (; __i < __n; ++__i, ++__s)
+        if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof())
+            break;
+    return __i;
+}
+
+template <class _CharT>
 int
 __stdoutbuf<_CharT>::sync()
 {
diff --git a/include/__tree b/include/__tree
index cd6d7ef..acf8759 100644
--- a/include/__tree
+++ b/include/__tree
@@ -25,17 +25,17 @@
 
 template <class _Tp, class _Compare, class _Allocator> class __tree;
 template <class _Tp, class _NodePtr, class _DiffType>
-    class _LIBCPP_TYPE_VIS __tree_iterator;
+    class _LIBCPP_TYPE_VIS_ONLY __tree_iterator;
 template <class _Tp, class _ConstNodePtr, class _DiffType>
-    class _LIBCPP_TYPE_VIS __tree_const_iterator;
+    class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
 template <class _Key, class _Tp, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS map;
+    class _LIBCPP_TYPE_VIS_ONLY map;
 template <class _Key, class _Tp, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS multimap;
+    class _LIBCPP_TYPE_VIS_ONLY multimap;
 template <class _Key, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS set;
+    class _LIBCPP_TYPE_VIS_ONLY set;
 template <class _Key, class _Compare, class _Allocator>
-    class _LIBCPP_TYPE_VIS multiset;
+    class _LIBCPP_TYPE_VIS_ONLY multiset;
 
 /*
 
@@ -614,11 +614,11 @@
 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
 };
 
-template <class _TreeIterator> class _LIBCPP_TYPE_VIS __map_iterator;
-template <class _TreeIterator> class _LIBCPP_TYPE_VIS __map_const_iterator;
+template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
+template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
 
 template <class _Tp, class _NodePtr, class _DiffType>
-class _LIBCPP_TYPE_VIS __tree_iterator
+class _LIBCPP_TYPE_VIS_ONLY __tree_iterator
 {
     typedef _NodePtr                                              __node_pointer;
     typedef typename pointer_traits<__node_pointer>::element_type __node;
@@ -641,10 +641,15 @@
 #endif
                                        pointer;
 
-    _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __ptr_(nullptr)
+#endif
+    {}
 
     _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
-    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return &__ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
+        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
     __tree_iterator& operator++()
@@ -673,20 +678,20 @@
     _LIBCPP_INLINE_VISIBILITY
     explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
     template <class, class, class> friend class __tree;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS __tree_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __map_iterator;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS map;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS multimap;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS set;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS multiset;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
 };
 
 template <class _Tp, class _ConstNodePtr, class _DiffType>
-class _LIBCPP_TYPE_VIS __tree_const_iterator
+class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator
 {
     typedef _ConstNodePtr                                         __node_pointer;
     typedef typename pointer_traits<__node_pointer>::element_type __node;
-    typedef const typename __node::base                           __node_base;
+    typedef typename __node::base                                 __node_base;
     typedef typename pointer_traits<__node_pointer>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
             rebind<__node_base>
@@ -711,7 +716,12 @@
 #endif
                                        pointer;
 
-    _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() {}
+    _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __ptr_(nullptr)
+#endif
+    {}
+
 private:
     typedef typename remove_const<__node>::type  __non_const_node;
     typedef typename pointer_traits<__node_pointer>::template
@@ -729,7 +739,8 @@
         : __ptr_(__p.__ptr_) {}
 
     _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
-    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return &__ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
+        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
     __tree_const_iterator& operator++()
@@ -759,11 +770,11 @@
     explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
         : __ptr_(__p) {}
     template <class, class, class> friend class __tree;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS map;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS multimap;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS set;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS multiset;
-    template <class> friend class _LIBCPP_TYPE_VIS __map_const_iterator;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
 };
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -779,8 +790,10 @@
     typedef typename __alloc_traits::size_type       size_type;
     typedef typename __alloc_traits::difference_type difference_type;
 
-    typedef __tree_node<value_type, typename __alloc_traits::void_pointer> __node;
-    typedef __tree_node_base<typename __alloc_traits::void_pointer> __node_base;
+    typedef typename __alloc_traits::void_pointer  __void_pointer;
+
+    typedef __tree_node<value_type, __void_pointer> __node;
+    typedef __tree_node_base<__void_pointer>        __node_base;
     typedef typename __alloc_traits::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
             rebind_alloc<__node>
@@ -790,9 +803,9 @@
                                                      __node_allocator;
     typedef allocator_traits<__node_allocator>       __node_traits;
     typedef typename __node_traits::pointer          __node_pointer;
-    typedef typename __node_traits::const_pointer    __node_const_pointer;
+    typedef typename __node_traits::pointer          __node_const_pointer;
     typedef typename __node_base::pointer            __node_base_pointer;
-    typedef typename __node_base::const_pointer      __node_base_const_pointer;
+    typedef typename __node_base::pointer            __node_base_const_pointer;
 private:
     typedef typename __node_base::base __end_node_t;
     typedef typename pointer_traits<__node_pointer>::template
@@ -804,9 +817,9 @@
                                                      __end_node_ptr;
     typedef typename pointer_traits<__node_pointer>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<const __end_node_t>
+            rebind<__end_node_t>
 #else
-            rebind<const __end_node_t>::other
+            rebind<__end_node_t>::other
 #endif
                                                      __end_node_const_ptr;
 
@@ -828,7 +841,7 @@
     {
         return static_cast<__node_const_pointer>
                (
-                   pointer_traits<__end_node_const_ptr>::pointer_to(__pair1_.first())
+                   pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first()))
                );
     }
     _LIBCPP_INLINE_VISIBILITY
@@ -865,7 +878,7 @@
         {return static_cast<__node_const_pointer>(__end_node()->__left_);}
 
     typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
-    typedef __tree_const_iterator<value_type, __node_const_pointer, difference_type> const_iterator;
+    typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
 
     explicit __tree(const value_compare& __comp)
         _NOEXCEPT_(
@@ -1102,6 +1115,9 @@
 
     __node_pointer __detach();
     static __node_pointer __detach(__node_pointer);
+
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
 };
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -1161,7 +1177,7 @@
 {
     if (__cache->__parent_ == nullptr)
         return nullptr;
-    if (__tree_is_left_child(__cache))
+    if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
     {
         __cache->__parent_->__left_ = nullptr;
         __cache = static_cast<__node_pointer>(__cache->__parent_);
@@ -1294,7 +1310,7 @@
         __begin_node() = __end_node();
     else
     {
-        __end_node()->__left_->__parent_ = __end_node();
+        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
         __t.__begin_node() = __t.__end_node();
         __t.__end_node()->__left_ = nullptr;
         __t.size() = 0;
@@ -1314,7 +1330,7 @@
         {
             __begin_node() = __t.__begin_node();
             __end_node()->__left_ = __t.__end_node()->__left_;
-            __end_node()->__left_->__parent_ = __end_node();
+            __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
             size() = __t.size();
             __t.__begin_node() = __t.__end_node();
             __t.__end_node()->__left_ = nullptr;
@@ -1342,7 +1358,7 @@
         __begin_node() = __end_node();
     else
     {
-        __end_node()->__left_->__parent_ = __end_node();
+        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
         __t.__begin_node() = __t.__end_node();
         __t.__end_node()->__left_ = nullptr;
         __t.size() = 0;
@@ -1447,11 +1463,11 @@
     if (size() == 0)
         __begin_node() = __end_node();
     else
-        __end_node()->__left_->__parent_ = __end_node();
+        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
     if (__t.size() == 0)
         __t.__begin_node() = __t.__end_node();
     else
-        __t.__end_node()->__left_->__parent_ = __t.__end_node();
+        __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node());
 }
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -1483,7 +1499,7 @@
                     __nd = static_cast<__node_pointer>(__nd->__right_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__right_;
                 }
             }
@@ -1493,13 +1509,13 @@
                     __nd = static_cast<__node_pointer>(__nd->__left_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__left_;
                 }
             }
         }
     }
-    __parent = __end_node();
+    __parent = static_cast<__node_base_pointer>(__end_node());
     return __parent->__left_;
 }
 
@@ -1522,7 +1538,7 @@
                     __nd = static_cast<__node_pointer>(__nd->__left_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__left_;
                 }
             }
@@ -1532,13 +1548,13 @@
                     __nd = static_cast<__node_pointer>(__nd->__right_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__right_;
                 }
             }
         }
     }
-    __parent = __end_node();
+    __parent = static_cast<__node_base_pointer>(__end_node());
     return __parent->__left_;
 }
 
@@ -1563,12 +1579,12 @@
             // *prev(__hint) <= __v <= *__hint
             if (__hint.__ptr_->__left_ == nullptr)
             {
-                __parent = const_cast<__node_pointer&>(__hint.__ptr_);
+                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
                 return __parent->__left_;
             }
             else
             {
-                __parent = const_cast<__node_pointer&>(__prior.__ptr_);
+                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
                 return __parent->__right_;
             }
         }
@@ -1600,7 +1616,7 @@
                     __nd = static_cast<__node_pointer>(__nd->__left_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__left_;
                 }
             }
@@ -1610,18 +1626,18 @@
                     __nd = static_cast<__node_pointer>(__nd->__right_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__right_;
                 }
             }
             else
             {
-                __parent = __nd;
+                __parent = static_cast<__node_base_pointer>(__nd);
                 return __parent;
             }
         }
     }
-    __parent = __end_node();
+    __parent = static_cast<__node_base_pointer>(__end_node());
     return __parent->__left_;
 }
 
@@ -1648,12 +1664,12 @@
             // *prev(__hint) < __v < *__hint
             if (__hint.__ptr_->__left_ == nullptr)
             {
-                __parent = const_cast<__node_pointer&>(__hint.__ptr_);
+                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
                 return __parent->__left_;
             }
             else
             {
-                __parent = const_cast<__node_pointer&>(__prior.__ptr_);
+                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
                 return __parent->__right_;
             }
         }
@@ -1669,12 +1685,12 @@
             // *__hint < __v < *_VSTD::next(__hint)
             if (__hint.__ptr_->__right_ == nullptr)
             {
-                __parent = const_cast<__node_pointer&>(__hint.__ptr_);
+                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
                 return __parent->__right_;
             }
             else
             {
-                __parent = const_cast<__node_pointer&>(__next.__ptr_);
+                __parent = static_cast<__node_base_pointer>(__next.__ptr_);
                 return __parent->__left_;
             }
         }
@@ -1682,7 +1698,7 @@
         return __find_equal(__parent, __v);
     }
     // else __v == *__hint
-    __parent = const_cast<__node_pointer&>(__hint.__ptr_);
+    __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
     return __parent;
 }
 
@@ -1729,7 +1745,7 @@
     bool __inserted = false;
     if (__child == nullptr)
     {
-        __insert_node_at(__parent, __child, __h.get());
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
         __r = __h.release();
         __inserted = true;
     }
@@ -1747,7 +1763,7 @@
     __node_pointer __r = static_cast<__node_pointer>(__child);
     if (__child == nullptr)
     {
-        __insert_node_at(__parent, __child, __h.get());
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
         __r = __h.release();
     }
     return iterator(__r);
@@ -1761,7 +1777,7 @@
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
-    __insert_node_at(__parent, __child, __h.get());
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(static_cast<__node_pointer>(__h.release()));
 }
 
@@ -1774,7 +1790,7 @@
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
-    __insert_node_at(__parent, __child, __h.get());
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(static_cast<__node_pointer>(__h.release()));
 }
 
@@ -1812,7 +1828,7 @@
     __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
-    __insert_node_at(__parent, __child, __h.get());
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(__h.release());
 }
 
@@ -1824,7 +1840,7 @@
     __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
-    __insert_node_at(__parent, __child, __h.get());
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(__h.release());
 }
 
@@ -1838,7 +1854,7 @@
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
     __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
     __h.get_deleter().__value_constructed = true;
-    return _VSTD::move(__h);
+    return _VSTD::move(__h);  // explicitly moved for C++03
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1854,7 +1870,7 @@
     if (__child == nullptr)
     {
         __node_holder __h = __construct_node(__v);
-        __insert_node_at(__parent, __child, __h.get());
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
         __r = __h.release();
         __inserted = true;
     }
@@ -1871,7 +1887,7 @@
     if (__child == nullptr)
     {
         __node_holder __h = __construct_node(__v);
-        __insert_node_at(__parent, __child, __h.get());
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
         __r = __h.release();
     }
     return iterator(__r);
@@ -1884,7 +1900,7 @@
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf_high(__parent, __v);
     __node_holder __h = __construct_node(__v);
-    __insert_node_at(__parent, __child, __h.get());
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(__h.release());
 }
 
@@ -1895,7 +1911,7 @@
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf(__p, __parent, __v);
     __node_holder __h = __construct_node(__v);
-    __insert_node_at(__parent, __child, __h.get());
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     return iterator(__h.release());
 }
 
@@ -1909,7 +1925,7 @@
     bool __inserted = false;
     if (__child == nullptr)
     {
-        __insert_node_at(__parent, __child, __nd);
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
         __r = __nd;
         __inserted = true;
     }
@@ -1926,7 +1942,7 @@
     __node_pointer __r = static_cast<__node_pointer>(__child);
     if (__child == nullptr)
     {
-        __insert_node_at(__parent, __child, __nd);
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
         __r = __nd;
     }
     return iterator(__r);
@@ -1938,7 +1954,7 @@
 {
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
-    __insert_node_at(__parent, __child, __nd);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
     return iterator(__nd);
 }
 
@@ -1949,7 +1965,7 @@
 {
     __node_base_pointer __parent;
     __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
-    __insert_node_at(__parent, __child, __nd);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
     return iterator(__nd);
 }
 
@@ -1957,7 +1973,7 @@
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
 {
-    __node_pointer __np = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer __np = __p.__ptr_;
     iterator __r(__np);
     ++__r;
     if (__begin_node() == __np)
@@ -1977,7 +1993,7 @@
 {
     while (__f != __l)
         __f = erase(__f);
-    return iterator(const_cast<__node_pointer>(__l.__ptr_));
+    return iterator(__l.__ptr_);
 }
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -2264,7 +2280,7 @@
 typename __tree<_Tp, _Compare, _Allocator>::__node_holder
 __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
 {
-    __node_pointer __np = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer __np = __p.__ptr_;
     if (__begin_node() == __np)
     {
         if (__np->__right_ != nullptr)
diff --git a/include/__tuple b/include/__tuple
index 1213262..de35cb8 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -27,46 +27,46 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> class _LIBCPP_TYPE_VIS tuple_size;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS tuple_size<const _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp>
     : public tuple_size<_Tp> {};
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS tuple_size<volatile _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp>
     : public tuple_size<_Tp> {};
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS tuple_size<const volatile _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp>
     : public tuple_size<_Tp> {};
 
-template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS tuple_element;
+template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
 
 template <size_t _Ip, class _Tp>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, const _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp>
 {
 public:
     typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
 template <size_t _Ip, class _Tp>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, volatile _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp>
 {
 public:
     typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
 template <size_t _Ip, class _Tp>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, const volatile _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp>
 {
 public:
     typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
 };
 
-template <class ..._Tp> class _LIBCPP_TYPE_VIS tuple;
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS pair;
-template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS array;
+template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
+template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;
 
 template <class _Tp> struct __tuple_like : false_type {};
 
@@ -79,47 +79,47 @@
 template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
 
 template <size_t _Ip, class ..._Tp>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, tuple<_Tp...> >::type&
 get(tuple<_Tp...>&) _NOEXCEPT;
 
 template <size_t _Ip, class ..._Tp>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
 get(const tuple<_Tp...>&) _NOEXCEPT;
 
 template <size_t _Ip, class ..._Tp>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
 get(tuple<_Tp...>&&) _NOEXCEPT;
 
 template <size_t _Ip, class _T1, class _T2>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
 get(pair<_T1, _T2>&) _NOEXCEPT;
 
 template <size_t _Ip, class _T1, class _T2>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
 get(const pair<_T1, _T2>&) _NOEXCEPT;
 
 template <size_t _Ip, class _T1, class _T2>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
 get(pair<_T1, _T2>&&) _NOEXCEPT;
 
 template <size_t _Ip, class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&
 get(array<_Tp, _Size>&) _NOEXCEPT;
 
 template <size_t _Ip, class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Tp&
 get(const array<_Tp, _Size>&) _NOEXCEPT;
 
 template <size_t _Ip, class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&&
 get(array<_Tp, _Size>&&) _NOEXCEPT;
 
@@ -154,7 +154,7 @@
 template <class ..._Tp> struct __tuple_types {};
 
 template <size_t _Ip>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, __tuple_types<> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> >
 {
 public:
     static_assert(_Ip == 0, "tuple_element index out of range");
@@ -162,21 +162,21 @@
 };
 
 template <class _Hp, class ..._Tp>
-class _LIBCPP_TYPE_VIS tuple_element<0, __tuple_types<_Hp, _Tp...> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> >
 {
 public:
     typedef _Hp type;
 };
 
 template <size_t _Ip, class _Hp, class ..._Tp>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, __tuple_types<_Hp, _Tp...> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> >
 {
 public:
     typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type;
 };
 
 template <class ..._Tp>
-class _LIBCPP_TYPE_VIS tuple_size<__tuple_types<_Tp...> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> >
     : public integral_constant<size_t, sizeof...(_Tp)>
 {
 };
diff --git a/include/__tuple_03 b/include/__tuple_03
index 605d84d..b91c2cd 100644
--- a/include/__tuple_03
+++ b/include/__tuple_03
@@ -19,8 +19,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp> class _LIBCPP_TYPE_VIS tuple_size;
-template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS tuple_element;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
+template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/__undef_min_max b/include/__undef_min_max
index b1e80d1..5df9412 100644
--- a/include/__undef_min_max
+++ b/include/__undef_min_max
@@ -9,11 +9,21 @@
 //===----------------------------------------------------------------------===//
 
 #ifdef min
+#if defined(_MSC_VER) && ! defined(__clang__)
+_LIBCPP_WARNING("macro min is incompatible with C++.  Try #define NOMINMAX "
+                "before any Windows header. #undefing min")
+#else
 #warning: macro min is incompatible with C++.  #undefing min
+#endif
 #undef min
 #endif
 
 #ifdef max
+#if defined(_MSC_VER) && ! defined(__clang__)
+_LIBCPP_WARNING("macro max is incompatible with C++.  Try #define NOMINMAX "
+                "before any Windows header. #undefing max")
+#else
 #warning: macro max is incompatible with C++.  #undefing max
+#endif
 #undef max
 #endif
diff --git a/include/algorithm b/include/algorithm
index 39191db..367489f 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -87,30 +87,63 @@
     pair<InputIterator1, InputIterator2>
     mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
 
+template <class InputIterator1, class InputIterator2>
+    pair<InputIterator1, InputIterator2>
+    mismatch(InputIterator1 first1, InputIterator1 last1, 
+             InputIterator2 first2, InputIterator2 last2); // **C++14**
+
 template <class InputIterator1, class InputIterator2, class BinaryPredicate>
     pair<InputIterator1, InputIterator2>
     mismatch(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, BinaryPredicate pred);
 
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+    pair<InputIterator1, InputIterator2>
+    mismatch(InputIterator1 first1, InputIterator1 last1,
+             InputIterator2 first2, InputIterator2 last2,
+             BinaryPredicate pred); // **C++14**
+
 template <class InputIterator1, class InputIterator2>
     bool
     equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
 
+template <class InputIterator1, class InputIterator2>
+    bool
+    equal(InputIterator1 first1, InputIterator1 last1, 
+          InputIterator2 first2, InputIterator2 last2); // **C++14**
+
 template <class InputIterator1, class InputIterator2, class BinaryPredicate>
     bool
     equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, BinaryPredicate pred);
 
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+    bool
+    equal(InputIterator1 first1, InputIterator1 last1,
+          InputIterator2 first2, InputIterator2 last2,
+          BinaryPredicate pred); // **C++14**
+
 template<class ForwardIterator1, class ForwardIterator2>
     bool
     is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2);
 
+template<class ForwardIterator1, class ForwardIterator2>
+    bool
+    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
+                   ForwardIterator2 first2, ForwardIterator2 last2); // **C++14**
+
 template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
     bool
     is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2, BinaryPredicate pred);
 
+template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
+    bool
+    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
+                   ForwardIterator2 first2, ForwardIterator2 last2,
+                   BinaryPredicate pred);  // **C++14**
+
 template <class ForwardIterator1, class ForwardIterator2>
     ForwardIterator1
     search(ForwardIterator1 first1, ForwardIterator1 last1,
@@ -595,6 +628,13 @@
 #include <iterator>
 #include <cstddef>
 
+#if defined(__IBMCPP__)
+#include "support/ibm/support.h"
+#endif
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+#include "support/win32/support.h"
+#endif
+
 #include <__undef_min_max>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -677,7 +717,7 @@
     bool operator()(const _T1& __x, const _T2& __y) {return !__p_(__x, __y);}
 };
 
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
 
 template <class _Compare>
 struct __debug_less
@@ -694,7 +734,7 @@
     }
 };
 
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 
 // Precondition:  __x != 0
 inline _LIBCPP_INLINE_VISIBILITY
@@ -792,7 +832,7 @@
 {
     for (; __first != __last; ++__first)
         __f(*__first);
-    return _VSTD::move(__f);
+    return _VSTD::move(__f);  // explicitly moved for (emulated) C++03
 }
 
 // find
@@ -1087,6 +1127,32 @@
     return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIterator1, _InputIterator2>
+mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
+         _InputIterator2 __first2, _InputIterator2 __last2,
+         _BinaryPredicate __pred)
+{
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            break;
+    return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIterator1, _InputIterator2>
+mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
+         _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+#endif
+
 // equal
 
 template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
@@ -1110,6 +1176,60 @@
     return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__equal(_InputIterator1 __first1, _InputIterator1 __last1, 
+        _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred,
+        input_iterator_tag, input_iterator_tag )
+{
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            return false;
+    return __first1 == __last1 && __first2 == __last2;
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 
+        _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 
+      random_access_iterator_tag, random_access_iterator_tag )
+{
+    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
+        return false;
+    return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
+                        typename add_lvalue_reference<_BinaryPredicate>::type>
+                       (__first1, __last1, __first2, __pred );
+}
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, 
+      _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred )
+{
+    return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type>
+       (__first1, __last1, __first2, __last2, __pred, 
+        typename iterator_traits<_InputIterator1>::iterator_category(),
+        typename iterator_traits<_InputIterator2>::iterator_category());
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, 
+      _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
+        typename iterator_traits<_InputIterator1>::iterator_category(),
+        typename iterator_traits<_InputIterator2>::iterator_category());
+}
+#endif
+
 // is_permutation
 
 template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
@@ -1169,6 +1289,100 @@
     return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
 }
 
+#if _LIBCPP_STD_VER > 11
+template<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
+bool
+__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+                 _ForwardIterator2 __first2, _ForwardIterator2 __last2, 
+                 _BinaryPredicate __pred,
+                 forward_iterator_tag, forward_iterator_tag )
+{
+    // shorten sequences as much as possible by lopping of any equal parts
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            goto __not_done;
+    return __first1 == __last1 && __first2 == __last2;
+__not_done:
+    // __first1 != __last1 && __first2 != __last2 && *__first1 != *__first2
+    typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
+    _D1 __l1 = _VSTD::distance(__first1, __last1);
+
+    typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;
+    _D2 __l2 = _VSTD::distance(__first2, __last2);
+    if (__l1 != __l2)
+        return false;
+
+    // For each element in [f1, l1) see if there are the same number of
+    //    equal elements in [f2, l2)
+    for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
+    {
+        // Have we already counted the number of *__i in [f1, l1)?
+        for (_ForwardIterator1 __j = __first1; __j != __i; ++__j)
+            if (__pred(*__j, *__i))
+                goto __next_iter;
+        {
+            // Count number of *__i in [f2, l2)
+            _D1 __c2 = 0;
+            for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
+                if (__pred(*__i, *__j))
+                    ++__c2;
+            if (__c2 == 0)
+                return false;
+            // Count number of *__i in [__i, l1) (we can start with 1)
+            _D1 __c1 = 1;
+            for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
+                if (__pred(*__i, *__j))
+                    ++__c1;
+            if (__c1 != __c2)
+                return false;
+        }
+__next_iter:;
+    }
+    return true;
+}
+
+template<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+bool
+__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,
+               _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, 
+               _BinaryPredicate __pred,
+               random_access_iterator_tag, random_access_iterator_tag )
+{
+    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
+        return false;
+    return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,
+                                 typename add_lvalue_reference<_BinaryPredicate>::type>
+                                (__first1, __last1, __first2, __pred );
+}
+
+template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+               _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+               _BinaryPredicate __pred )
+{
+    return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type>
+       (__first1, __last1, __first2, __last2, __pred,
+        typename iterator_traits<_ForwardIterator1>::iterator_category(),
+        typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+
+template<class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+               _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+{
+    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+    return _VSTD::__is_permutation(__first1, __last1, __first2, __last2,
+        __equal_to<__v1, __v2>(),
+        typename iterator_traits<_ForwardIterator1>::iterator_category(),
+        typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+#endif
+
 // search
 
 template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
@@ -1481,6 +1695,8 @@
     return __i.base();
 }
 
+#if _LIBCPP_DEBUG_LEVEL < 2
+
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
@@ -1493,6 +1709,8 @@
     return __i.base();
 }
 
+#endif  // _LIBCPP_DEBUG_LEVEL < 2
+
 template <class _InputIterator, class _OutputIterator>
 inline _LIBCPP_INLINE_VISIBILITY
 _OutputIterator
@@ -1780,17 +1998,23 @@
 template <class _OutputIterator, class _Size, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 _OutputIterator
-__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_, false_type)
+__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
 {
     for (; __n > 0; ++__first, --__n)
         *__first = __value_;
     return __first;
 }
 
-template <class _OutputIterator, class _Size, class _Tp>
+template <class _Tp, class _Size, class _Up>
 inline _LIBCPP_INLINE_VISIBILITY
-_OutputIterator
-__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_, true_type)
+typename enable_if
+<
+    is_integral<_Tp>::value && sizeof(_Tp) == 1 &&
+    !is_same<_Tp, bool>::value &&
+    is_integral<_Up>::value && sizeof(_Up) == 1,
+    _Tp*
+>::type
+__fill_n(_Tp* __first, _Size __n,_Up __value_)
 {
     if (__n > 0)
         _VSTD::memset(__first, (unsigned char)__value_, (size_t)(__n));
@@ -1802,10 +2026,7 @@
 _OutputIterator
 fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
 {
-   return _VSTD::__fill_n(__first, __n, __value_, integral_constant<bool,
-                                              is_pointer<_OutputIterator>::value &&
-                                              is_trivially_copy_assignable<_Tp>::value     &&
-                                              sizeof(_Tp) == 1>());
+   return _VSTD::__fill_n(__first, __n, __value_);
 }
 
 // fill
@@ -2754,11 +2975,11 @@
     return static_cast<result_type>(__u + __p.a());
 }
 
-class __rs_default;
+class _LIBCPP_TYPE_VIS __rs_default;
 
-__rs_default __rs_get();
+_LIBCPP_FUNC_VIS __rs_default __rs_get();
 
-class __rs_default
+class _LIBCPP_TYPE_VIS __rs_default
 {
     static unsigned __c_;
 
@@ -2777,10 +2998,10 @@
     static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
     static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
 
-    friend __rs_default __rs_get();
+    friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
 };
 
-__rs_default __rs_get();
+_LIBCPP_FUNC_VIS __rs_default __rs_get();
 
 template <class _RandomAccessIterator>
 void
@@ -3735,14 +3956,14 @@
 void
 sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __sort<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __sort<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -3778,46 +3999,46 @@
     _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp);
 }
 
-#ifdef _MSC_VER
+#ifdef _LIBCPP_MSVC
 #pragma warning( push )
 #pragma warning( disable: 4231)
-#endif // _MSC_VER
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
-_LIBCPP_EXTERN_TEMPLATE(void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
+#endif // _LIBCPP_MSVC
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
 
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
-_LIBCPP_EXTERN_TEMPLATE(bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
 
-_LIBCPP_EXTERN_TEMPLATE(unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
-#ifdef _MSC_VER
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
+#ifdef _LIBCPP_MSVC
 #pragma warning( pop )
-#endif  // _MSC_VER
+#endif  // _LIBCPP_MSVC
 
 // lower_bound
 
@@ -3848,14 +4069,14 @@
 _ForwardIterator
 lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __lower_bound<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _ForwardIterator, class _Tp>
@@ -3896,14 +4117,14 @@
 _ForwardIterator
 upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __upper_bound<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _ForwardIterator, class _Tp>
@@ -3956,14 +4177,14 @@
 pair<_ForwardIterator, _ForwardIterator>
 equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __equal_range<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __equal_range<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _ForwardIterator, class _Tp>
@@ -3991,14 +4212,14 @@
 bool
 binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __binary_search<_Comp_ref>(__first, __last, __value_, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __binary_search<_Comp_ref>(__first, __last, __value_, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _ForwardIterator, class _Tp>
@@ -4041,14 +4262,14 @@
 merge(_InputIterator1 __first1, _InputIterator1 __last1,
       _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
@@ -4215,16 +4436,16 @@
         __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
         __h.reset(__buf.first);
     }
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __c, __len1, __len2,
                                             __buf.first, __buf.second);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
                                             __buf.first, __buf.second);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _BidirectionalIterator>
@@ -4426,14 +4647,14 @@
         __buf = _VSTD::get_temporary_buffer<value_type>(__len);
         __h.reset(__buf.first);
     }
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __stable_sort<_Comp_ref>(__first, __last, __c, __len, __buf.first, __buf.second);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -4575,14 +4796,14 @@
 void
 push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __push_heap_back<_Comp_ref>(__first, __last, __c, __last - __first);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __push_heap_back<_Comp_ref>(__first, __last, __comp, __last - __first);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -4613,14 +4834,14 @@
 void
 pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __pop_heap<_Comp_ref>(__first, __last, __c, __last - __first);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -4653,14 +4874,14 @@
 void
 make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __make_heap<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __make_heap<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -4687,14 +4908,14 @@
 void
 sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __sort_heap<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __sort_heap<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -4731,14 +4952,14 @@
 partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
              _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __partial_sort<_Comp_ref>(__first, __middle, __last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __partial_sort<_Comp_ref>(__first, __middle, __last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -4781,14 +5002,14 @@
 partial_sort_copy(_InputIterator __first, _InputIterator __last,
                   _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator, class _RandomAccessIterator>
@@ -4995,14 +5216,14 @@
 void
 nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     __nth_element<_Comp_ref>(__first, __nth, __last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     __nth_element<_Comp_ref>(__first, __nth, __last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _RandomAccessIterator>
@@ -5036,14 +5257,14 @@
 includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
          _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator1, class _InputIterator2>
@@ -5089,14 +5310,14 @@
 set_union(_InputIterator1 __first1, _InputIterator1 __last1,
           _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
@@ -5141,14 +5362,14 @@
 set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
                  _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
@@ -5195,14 +5416,14 @@
 set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
                _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
@@ -5254,14 +5475,14 @@
 set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
                          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
@@ -5298,14 +5519,14 @@
 lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
                         _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _InputIterator1, class _InputIterator2>
@@ -5353,14 +5574,14 @@
 bool
 next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __next_permutation<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __next_permutation<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _BidirectionalIterator>
@@ -5406,14 +5627,14 @@
 bool
 prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
 {
-#ifdef _LIBCPP_DEBUG2
+#ifdef _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
     __debug_less<_Compare> __c(__comp);
     return __prev_permutation<_Comp_ref>(__first, __last, __c);
-#else  // _LIBCPP_DEBUG2
+#else  // _LIBCPP_DEBUG
     typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
     return __prev_permutation<_Comp_ref>(__first, __last, __comp);
-#endif  // _LIBCPP_DEBUG2
+#endif  // _LIBCPP_DEBUG
 }
 
 template <class _BidirectionalIterator>
diff --git a/include/array b/include/array
index bcf5347..d37075d 100644
--- a/include/array
+++ b/include/array
@@ -59,14 +59,14 @@
 
     // element access:
     reference operator[](size_type n);
-    const_reference operator[](size_type n) const;
-    const_reference at(size_type n) const;
+    const_reference operator[](size_type n) const; // constexpr in C++14
+    const_reference at(size_type n) const; // constexpr in C++14
     reference at(size_type n);
 
     reference front();
-    const_reference front() const;
+    const_reference front() const; // constexpr in C++14
     reference back();
-    const_reference back() const;
+    const_reference back() const; // constexpr in C++14
 
     T* data() noexcept;
     const T* data() const noexcept;
@@ -92,9 +92,9 @@
 template <int I, class T> class tuple_element;
 template <class T, size_t N> struct tuple_size<array<T, N>>;
 template <int I, class T, size_t N> struct tuple_element<I, array<T, N>>;
-template <int I, class T, size_t N> T& get(array<T, N>&) noexcept;
-template <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept;
-template <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept;
+template <int I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
+template <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
+template <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
 
 }  // std
 
@@ -118,7 +118,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, size_t _Size>
-struct _LIBCPP_TYPE_VIS array
+struct _LIBCPP_TYPE_VIS_ONLY array
 {
     // types:
     typedef array __self;
@@ -181,14 +181,14 @@
 
     // element access:
     _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}
-    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __elems_[__n];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];}
     reference at(size_type __n);
-    const_reference at(size_type __n) const;
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;
 
     _LIBCPP_INLINE_VISIBILITY reference front()             {return __elems_[0];}
-    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return __elems_[0];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];}
     _LIBCPP_INLINE_VISIBILITY reference back()              {return __elems_[_Size > 0 ? _Size-1 : 0];}
-    _LIBCPP_INLINE_VISIBILITY const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
 
     _LIBCPP_INLINE_VISIBILITY
     value_type* data() _NOEXCEPT {return __elems_;}
@@ -210,6 +210,7 @@
 }
 
 template <class _Tp, size_t _Size>
+_LIBCPP_CONSTEXPR_AFTER_CXX11
 typename array<_Tp, _Size>::const_reference
 array<_Tp, _Size>::at(size_type __n) const
 {
@@ -223,7 +224,7 @@
 }
 
 template <class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
@@ -231,7 +232,7 @@
 }
 
 template <class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
@@ -239,7 +240,7 @@
 }
 
 template <class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
@@ -247,7 +248,7 @@
 }
 
 template <class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
@@ -255,7 +256,7 @@
 }
 
 template <class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
@@ -263,7 +264,7 @@
 }
 
 template <class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
 {
@@ -271,7 +272,7 @@
 }
 
 template <class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
     __is_swappable<_Tp>::value,
@@ -284,54 +285,54 @@
 }
 
 template <class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS tuple_size<array<_Tp, _Size> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >
     : public integral_constant<size_t, _Size> {};
 
 template <class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS tuple_size<const array<_Tp, _Size> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<const array<_Tp, _Size> >
     : public integral_constant<size_t, _Size> {};
 
 template <size_t _Ip, class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, array<_Tp, _Size> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >
 {
 public:
     typedef _Tp type;
 };
 
 template <size_t _Ip, class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, const array<_Tp, _Size> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const array<_Tp, _Size> >
 {
 public:
     typedef const _Tp type;
 };
 
 template <size_t _Ip, class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&
 get(array<_Tp, _Size>& __a) _NOEXCEPT
 {
     static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
-    return __a[_Ip];
+    return __a.__elems_[_Ip];
 }
 
 template <size_t _Ip, class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Tp&
 get(const array<_Tp, _Size>& __a) _NOEXCEPT
 {
     static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
-    return __a[_Ip];
+    return __a.__elems_[_Ip];
 }
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <size_t _Ip, class _Tp, size_t _Size>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&&
 get(array<_Tp, _Size>&& __a) _NOEXCEPT
 {
     static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
-    return _VSTD::move(__a[_Ip]);
+    return _VSTD::move(__a.__elems_[_Ip]);
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
diff --git a/include/bitset b/include/bitset
index dd9be4f..4cc7dbd 100644
--- a/include/bitset
+++ b/include/bitset
@@ -632,11 +632,11 @@
 {
 }
 
-template <size_t _Size> class _LIBCPP_TYPE_VIS bitset;
-template <size_t _Size> struct _LIBCPP_TYPE_VIS hash<bitset<_Size> >;
+template <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset;
+template <size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >;
 
 template <size_t _Size>
-class _LIBCPP_TYPE_VIS bitset
+class _LIBCPP_TYPE_VIS_ONLY bitset
     : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size>
 {
 public:
@@ -1060,7 +1060,7 @@
 }
 
 template <size_t _Size>
-struct _LIBCPP_TYPE_VIS hash<bitset<_Size> >
+struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >
     : public unary_function<bitset<_Size>, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
diff --git a/include/cctype b/include/cctype
index e33244e..b647903 100644
--- a/include/cctype
+++ b/include/cctype
@@ -37,9 +37,9 @@
 
 #include <__config>
 #include <ctype.h>
-#if defined(_MSC_VER)
+#if defined(_LIBCPP_MSVCRT)
 #include "support/win32/support.h"
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
diff --git a/include/chrono b/include/chrono
index 3b96e81..2c65eee 100644
--- a/include/chrono
+++ b/include/chrono
@@ -111,16 +111,16 @@
     duration d_;  // exposition only
 
 public:
-    time_point();  // has value "epoch"
-    explicit time_point(const duration& d);  // same as time_point() + d
+    time_point();  // has value "epoch" // constexpr in C++14
+    explicit time_point(const duration& d);  // same as time_point() + d // constexpr in C++14
 
     // conversions
     template <class Duration2>
-       time_point(const time_point<clock, Duration2>& t);
+       time_point(const time_point<clock, Duration2>& t); // constexpr in C++14
 
     // observer
 
-    duration time_since_epoch() const;
+    duration time_since_epoch() const; // constexpr in C++14
 
     // arithmetic
 
@@ -194,7 +194,7 @@
 template <class ToDuration, class Rep, class Period>
   ToDuration duration_cast(const duration<Rep, Period>& d);
 
-// time_point arithmetic
+// time_point arithmetic (all constexpr in C++14)
 template <class Clock, class Duration1, class Rep2, class Period2>
   time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
   operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
@@ -208,7 +208,7 @@
   typename common_type<Duration1, Duration2>::type
   operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
 
-// time_point comparisons
+// time_point comparisons (all constexpr in C++14)
 template <class Clock, class Duration1, class Duration2>
    bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
 template <class Clock, class Duration1, class Duration2>
@@ -222,7 +222,7 @@
 template <class Clock, class Duration1, class Duration2>
    bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
 
-// time_point_cast
+// time_point_cast (constexpr in C++14)
 
 template <class ToDuration, class Clock, class Duration>
   time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
@@ -236,7 +236,7 @@
     typedef duration::rep                    rep;
     typedef duration::period                 period;
     typedef chrono::time_point<system_clock> time_point;
-    static const bool is_steady =            false;
+    static const bool is_steady =            false; // constexpr in C++14
 
     static time_point now() noexcept;
     static time_t     to_time_t  (const time_point& __t) noexcept;
@@ -250,7 +250,7 @@
     typedef duration::rep                                 rep;
     typedef duration::period                              period;
     typedef chrono::time_point<steady_clock, duration>    time_point;
-    static const bool is_steady =                         true;
+    static const bool is_steady =                         true; // constexpr in C++14
 
     static time_point now() noexcept;
 };
@@ -259,6 +259,19 @@
 
 }  // chrono
 
+constexpr chrono::hours                                 operator "" h(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , ratio<3600,1>> operator "" h(long double); // C++14
+constexpr chrono::minutes                               operator "" min(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , ratio<60,1>>   operator "" min(long double); // C++14
+constexpr chrono::seconds                               operator "" s(unsigned long long); // C++14
+constexpr chrono::duration<unspecified >                operator "" s(long double); // C++14
+constexpr chrono::milliseconds                          operator "" ms(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , milli>         operator "" ms(long double); // C++14
+constexpr chrono::microseconds                          operator "" us(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , micro>         operator "" us(long double); // C++14
+constexpr chrono::nanoseconds                           operator "" ns(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , nano>          operator "" ns(long double); // C++14
+
 }  // std
 */
 
@@ -279,7 +292,7 @@
 namespace chrono
 {
 
-template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TYPE_VIS duration;
+template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TYPE_VIS_ONLY duration;
 
 template <class _Tp>
 struct __is_duration : false_type {};
@@ -299,8 +312,8 @@
 } // chrono
 
 template <class _Rep1, class _Period1, class _Rep2, class _Period2>
-struct _LIBCPP_TYPE_VIS common_type<chrono::duration<_Rep1, _Period1>,
-                                   chrono::duration<_Rep2, _Period2> >
+struct _LIBCPP_TYPE_VIS_ONLY common_type<chrono::duration<_Rep1, _Period1>,
+                                         chrono::duration<_Rep2, _Period2> >
 {
     typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
                              typename __ratio_gcd<_Period1, _Period2>::type> type;
@@ -377,10 +390,10 @@
 }
 
 template <class _Rep>
-struct _LIBCPP_TYPE_VIS treat_as_floating_point : is_floating_point<_Rep> {};
+struct _LIBCPP_TYPE_VIS_ONLY treat_as_floating_point : is_floating_point<_Rep> {};
 
 template <class _Rep>
-struct _LIBCPP_TYPE_VIS duration_values
+struct _LIBCPP_TYPE_VIS_ONLY duration_values
 {
 public:
     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() {return _Rep(0);}
@@ -391,11 +404,42 @@
 // duration
 
 template <class _Rep, class _Period>
-class _LIBCPP_TYPE_VIS duration
+class _LIBCPP_TYPE_VIS_ONLY duration
 {
     static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration");
     static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio");
     static_assert(_Period::num > 0, "duration period must be positive");
+
+    template <class _R1, class _R2>
+    struct __no_overflow
+    {
+    private:
+        static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
+        static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+        static const intmax_t __n1 = _R1::num / __gcd_n1_n2;
+        static const intmax_t __d1 = _R1::den / __gcd_d1_d2;
+        static const intmax_t __n2 = _R2::num / __gcd_n1_n2;
+        static const intmax_t __d2 = _R2::den / __gcd_d1_d2;
+        static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
+
+        template <intmax_t _Xp, intmax_t _Yp, bool __overflow>
+        struct __mul    // __overflow == false
+        {
+            static const intmax_t value = _Xp * _Yp;
+        };
+
+        template <intmax_t _Xp, intmax_t _Yp>
+        struct __mul<_Xp, _Yp, true>
+        {
+            static const intmax_t value = 1;
+        };
+
+    public:
+        static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1);
+        typedef ratio<__mul<__n1, __d2, !value>::value,
+                      __mul<__n2, __d1, !value>::value> type;
+    };
+    
 public:
     typedef _Rep rep;
     typedef _Period period;
@@ -403,7 +447,13 @@
     rep __rep_;
 public:
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR duration() {} // = default;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+        duration() = default;
+#else
+        duration() {}
+#endif
+
     template <class _Rep2>
         _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
         explicit duration(const _Rep2& __r,
@@ -421,9 +471,10 @@
         duration(const duration<_Rep2, _Period2>& __d,
             typename enable_if
             <
+                __no_overflow<_Period2, period>::value && (
                 treat_as_floating_point<rep>::value ||
-                (ratio_divide<_Period2, period>::type::den == 1 &&
-                 !treat_as_floating_point<_Rep2>::value)
+                (__no_overflow<_Period2, period>::type::den == 1 &&
+                 !treat_as_floating_point<_Rep2>::value))
             >::type* = 0)
                 : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
 
@@ -468,7 +519,7 @@
 struct __duration_eq
 {
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs)
+    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
         {
             typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
             return _Ct(__lhs).count() == _Ct(__rhs).count();
@@ -479,7 +530,7 @@
 struct __duration_eq<_LhsDuration, _LhsDuration>
 {
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs)
+    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
         {return __lhs.count() == __rhs.count();}
 };
 
@@ -509,7 +560,7 @@
 struct __duration_lt
 {
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs)
+    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
         {
             typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
             return _Ct(__lhs).count() < _Ct(__rhs).count();
@@ -520,7 +571,7 @@
 struct __duration_lt<_LhsDuration, _LhsDuration>
 {
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs)
+    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
         {return __lhs.count() < __rhs.count();}
 };
 
@@ -696,7 +747,7 @@
 //////////////////////////////////////////////////////////
 
 template <class _Clock, class _Duration = typename _Clock::duration>
-class _LIBCPP_TYPE_VIS time_point
+class _LIBCPP_TYPE_VIS_ONLY time_point
 {
     static_assert(__is_duration<_Duration>::value,
                   "Second template parameter of time_point must be a std::chrono::duration");
@@ -709,12 +760,12 @@
     duration __d_;
 
 public:
-    _LIBCPP_INLINE_VISIBILITY time_point() : __d_(duration::zero()) {}
-    _LIBCPP_INLINE_VISIBILITY explicit time_point(const duration& __d) : __d_(__d) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {}
 
     // conversions
     template <class _Duration2>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     time_point(const time_point<clock, _Duration2>& t,
         typename enable_if
         <
@@ -724,12 +775,12 @@
 
     // observer
 
-    _LIBCPP_INLINE_VISIBILITY duration time_since_epoch() const {return __d_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;}
 
     // arithmetic
 
-	_LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}
-	_LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;}
+    _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}
+    _LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;}
 
     // special values
 
@@ -740,8 +791,8 @@
 } // chrono
 
 template <class _Clock, class _Duration1, class _Duration2>
-struct _LIBCPP_TYPE_VIS common_type<chrono::time_point<_Clock, _Duration1>,
-                                   chrono::time_point<_Clock, _Duration2> >
+struct _LIBCPP_TYPE_VIS_ONLY common_type<chrono::time_point<_Clock, _Duration1>,
+                                         chrono::time_point<_Clock, _Duration2> >
 {
     typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
 };
@@ -749,7 +800,7 @@
 namespace chrono {
 
 template <class _ToDuration, class _Clock, class _Duration>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 time_point<_Clock, _ToDuration>
 time_point_cast(const time_point<_Clock, _Duration>& __t)
 {
@@ -759,7 +810,7 @@
 // time_point ==
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -769,7 +820,7 @@
 // time_point !=
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -779,7 +830,7 @@
 // time_point <
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -789,7 +840,7 @@
 // time_point >
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -799,7 +850,7 @@
 // time_point <=
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -809,7 +860,7 @@
 // time_point >=
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -819,20 +870,18 @@
 // time_point operator+(time_point x, duration y);
 
 template <class _Clock, class _Duration1, class _Rep2, class _Period2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
 operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
 {
     typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
-    _Tr __r(__lhs.time_since_epoch());
-    __r += __rhs;
-    return __r;
+    return _Tr (__lhs.time_since_epoch() + __rhs);
 }
 
 // time_point operator+(duration x, time_point y);
 
 template <class _Rep1, class _Period1, class _Clock, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
 operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -842,7 +891,7 @@
 // time_point operator-(time_point x, duration y);
 
 template <class _Clock, class _Duration1, class _Rep2, class _Period2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
 operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
 {
@@ -852,7 +901,7 @@
 // duration operator-(time_point x, time_point y);
 
 template <class _Clock, class _Duration1, class _Duration2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename common_type<_Duration1, _Duration2>::type
 operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
 {
@@ -870,7 +919,7 @@
     typedef duration::rep                    rep;
     typedef duration::period                 period;
     typedef chrono::time_point<system_clock> time_point;
-    static const bool is_steady =            false;
+    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
 
     static time_point now() _NOEXCEPT;
     static time_t     to_time_t  (const time_point& __t) _NOEXCEPT;
@@ -884,7 +933,7 @@
     typedef duration::rep                                 rep;
     typedef duration::period                              period;
     typedef chrono::time_point<steady_clock, duration>    time_point;
-    static const bool is_steady =                         true;
+    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true;
 
     static time_point now() _NOEXCEPT;
 };
@@ -893,6 +942,86 @@
 
 } // chrono
 
+#if _LIBCPP_STD_VER > 11
+// Suffixes for duration literals [time.duration.literals]
+inline namespace literals
+{ 
+  inline namespace chrono_literals
+  {
+
+    constexpr chrono::hours operator"" h(unsigned long long __h)
+    {
+        return chrono::hours(static_cast<chrono::hours::rep>(__h));
+    }
+
+    constexpr chrono::duration<long double, ratio<3600,1>> operator"" h(long double __h)
+    {
+        return chrono::duration<long double, ratio<3600,1>>(__h);
+    }
+
+
+    constexpr chrono::minutes operator"" min(unsigned long long __m)
+    {
+        return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
+    }
+
+    constexpr chrono::duration<long double, ratio<60,1>> operator"" min(long double __m)
+    {
+        return chrono::duration<long double, ratio<60,1>> (__m);
+    }
+
+
+    constexpr chrono::seconds operator"" s(unsigned long long __s)
+    {
+        return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
+    }
+
+    constexpr chrono::duration<long double> operator"" s(long double __s)
+    {
+        return chrono::duration<long double> (__s);
+    }
+
+
+    constexpr chrono::milliseconds operator"" ms(unsigned long long __ms)
+    {
+        return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
+    }
+
+    constexpr chrono::duration<long double, milli> operator"" ms(long double __ms)
+    {
+        return chrono::duration<long double, milli>(__ms);
+    }
+
+
+    constexpr chrono::microseconds operator"" us(unsigned long long __us)
+    {
+        return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
+    }
+
+    constexpr chrono::duration<long double, micro> operator"" us(long double __us)
+    {
+        return chrono::duration<long double, micro> (__us);
+    }
+    
+
+    constexpr chrono::nanoseconds operator"" ns(unsigned long long __ns)
+    {
+        return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
+    }
+
+    constexpr chrono::duration<long double, nano> operator"" ns(long double __ns)
+    {
+        return chrono::duration<long double, nano> (__ns);
+    }
+
+}}
+
+namespace chrono { // hoist the literals into namespace std::chrono
+   using namespace literals::chrono_literals;
+}
+
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_CHRONO
diff --git a/include/cmath b/include/cmath
index 7eb2aa1..25a9b6b 100644
--- a/include/cmath
+++ b/include/cmath
@@ -301,7 +301,7 @@
 #include <math.h>
 #include <type_traits>
 
-#ifdef _MSC_VER
+#ifdef _LIBCPP_MSVCRT
 #include "support/win32/math_win32.h"
 #endif
 
@@ -654,6 +654,7 @@
 
 // abs
 
+#if !defined(_AIX)
 inline _LIBCPP_INLINE_VISIBILITY
 float
 abs(float __x) _NOEXCEPT {return fabsf(__x);}
@@ -665,6 +666,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 long double
 abs(long double __x) _NOEXCEPT {return fabsl(__x);}
+#endif // !defined(_AIX)
 
 #ifndef __sun__
 
@@ -673,7 +675,7 @@
 using ::acos;
 using ::acosf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -688,7 +690,7 @@
 using ::asin;
 using ::asinf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -703,7 +705,7 @@
 using ::atan;
 using ::atanf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -718,7 +720,7 @@
 using ::atan2;
 using ::atan2f;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -744,7 +746,7 @@
 using ::ceil;
 using ::ceilf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -759,13 +761,13 @@
 using ::cos;
 using ::cosf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
 
 template <class _A1>
-inline _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if<is_integral<_A1>::value, double>::type
 cos(_A1 __x) _NOEXCEPT {return cos((double)__x);}
 
@@ -774,7 +776,7 @@
 using ::cosh;
 using ::coshf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -792,7 +794,7 @@
 
 #ifndef __sun__
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -808,7 +810,7 @@
 using ::fabs;
 using ::fabsf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -823,7 +825,7 @@
 using ::floor;
 using ::floorf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -840,7 +842,7 @@
 using ::fmodf;
 #ifndef __sun__
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -867,7 +869,7 @@
 using ::frexp;
 using ::frexpf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -882,7 +884,7 @@
 using ::ldexp;
 using ::ldexpf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -899,7 +901,7 @@
 using ::logf;
 #ifndef __sun__
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -915,7 +917,7 @@
 using ::log10;
 using ::log10f;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -930,7 +932,7 @@
 using ::modf;
 using ::modff;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -943,7 +945,7 @@
 
 #ifndef __sun__
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -970,7 +972,7 @@
 using ::sin;
 using ::sinf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -985,7 +987,7 @@
 using ::sinh;
 using ::sinhf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -1002,7 +1004,7 @@
 using ::sqrtf;
 
 
-#if !(defined(_MSC_VER) || defined(__sun__))
+#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);}
 #endif
@@ -1018,7 +1020,7 @@
 using ::tanf;
 #ifndef __sun__
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -1033,7 +1035,7 @@
 using ::tanh;
 using ::tanhf;
 
-#ifndef _MSC_VER
+#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);}
 #endif
@@ -1045,7 +1047,7 @@
 
 // acosh
 
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::acosh;
 using ::acoshf;
 
@@ -1060,7 +1062,7 @@
 
 // asinh
 
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::asinh;
 using ::asinhf;
 
@@ -1075,7 +1077,7 @@
 
 // atanh
 
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::atanh;
 using ::atanhf;
 
@@ -1090,7 +1092,7 @@
 
 // cbrt
 
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::cbrt;
 using ::cbrtf;
 
@@ -1127,7 +1129,7 @@
     return copysign((__result_type)__x, (__result_type)__y);
 }
 
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 
 // erf
 
@@ -1434,13 +1436,18 @@
 typename enable_if<is_integral<_A1>::value, long>::type
 lround(_A1 __x) _NOEXCEPT {return lround((double)__x);}
 
-// nan
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 #endif // __sun__
+
+// nan
+
+#ifndef _LIBCPP_MSVCRT
 using ::nan;
 using ::nanf;
+#endif // _LIBCPP_MSVCRT
+
 #ifndef __sun__
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 
 // nearbyint
 
@@ -1627,7 +1634,7 @@
 typename enable_if<is_integral<_A1>::value, double>::type
 trunc(_A1 __x) _NOEXCEPT {return trunc((double)__x);}
 
-#endif // !_MSC_VER
+#endif // !_LIBCPP_MSVCRT
 
 using ::acosl;
 using ::asinl;
@@ -1650,15 +1657,15 @@
 using ::sinhl;
 using ::sqrtl;
 using ::tanl;
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::tanhl;
 using ::acoshl;
 using ::asinhl;
 using ::atanhl;
 using ::cbrtl;
-#endif  // !_MSC_VER
+#endif  // !_LIBCPP_MSVCRT
 using ::copysignl;
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::erfl;
 using ::erfcl;
 using ::exp2l;
@@ -1693,7 +1700,7 @@
 using ::scalbnl;
 using ::tgammal;
 using ::truncl;
-#endif // !_MSC_VER
+#endif // !_LIBCPP_MSVCRT
 
 #else 
 using ::lgamma;
diff --git a/include/codecvt b/include/codecvt
index a6e4308..6eff107 100644
--- a/include/codecvt
+++ b/include/codecvt
@@ -29,7 +29,8 @@
 class codecvt_utf8
     : public codecvt<Elem, char, mbstate_t>
 {
-    // unspecified
+    explicit codecvt_utf8(size_t refs = 0);
+    ~codecvt_utf8();
 };
 
 template <class Elem, unsigned long Maxcode = 0x10ffff,
@@ -37,7 +38,8 @@
 class codecvt_utf16
     : public codecvt<Elem, char, mbstate_t>
 {
-    // unspecified
+    explicit codecvt_utf16(size_t refs = 0);
+    ~codecvt_utf16();
 };
 
 template <class Elem, unsigned long Maxcode = 0x10ffff,
@@ -45,7 +47,8 @@
 class codecvt_utf8_utf16
     : public codecvt<Elem, char, mbstate_t>
 {
-    // unspecified
+    explicit codecvt_utf8_utf16(size_t refs = 0);
+    ~codecvt_utf8_utf16();
 };
 
 }  // std
@@ -73,7 +76,7 @@
 template <class _Elem> class __codecvt_utf8;
 
 template <>
-class __codecvt_utf8<wchar_t>
+class _LIBCPP_TYPE_VIS __codecvt_utf8<wchar_t>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -108,7 +111,7 @@
 };
 
 template <>
-class __codecvt_utf8<char16_t>
+class _LIBCPP_TYPE_VIS __codecvt_utf8<char16_t>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -143,7 +146,7 @@
 };
 
 template <>
-class __codecvt_utf8<char32_t>
+class _LIBCPP_TYPE_VIS __codecvt_utf8<char32_t>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -179,7 +182,7 @@
 
 template <class _Elem, unsigned long _Maxcode = 0x10ffff,
           codecvt_mode _Mode = (codecvt_mode)0>
-class _LIBCPP_TYPE_VIS codecvt_utf8
+class _LIBCPP_TYPE_VIS_ONLY codecvt_utf8
     : public __codecvt_utf8<_Elem>
 {
 public:
@@ -196,7 +199,7 @@
 template <class _Elem, bool _LittleEndian> class __codecvt_utf16;
 
 template <>
-class __codecvt_utf16<wchar_t, false>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, false>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -231,7 +234,7 @@
 };
 
 template <>
-class __codecvt_utf16<wchar_t, true>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, true>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -266,7 +269,7 @@
 };
 
 template <>
-class __codecvt_utf16<char16_t, false>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, false>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -301,7 +304,7 @@
 };
 
 template <>
-class __codecvt_utf16<char16_t, true>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, true>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -336,7 +339,7 @@
 };
 
 template <>
-class __codecvt_utf16<char32_t, false>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, false>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -371,7 +374,7 @@
 };
 
 template <>
-class __codecvt_utf16<char32_t, true>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, true>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -407,7 +410,7 @@
 
 template <class _Elem, unsigned long _Maxcode = 0x10ffff,
           codecvt_mode _Mode = (codecvt_mode)0>
-class _LIBCPP_TYPE_VIS codecvt_utf16
+class _LIBCPP_TYPE_VIS_ONLY codecvt_utf16
     : public __codecvt_utf16<_Elem, _Mode & little_endian>
 {
 public:
@@ -424,7 +427,7 @@
 template <class _Elem> class __codecvt_utf8_utf16;
 
 template <>
-class __codecvt_utf8_utf16<wchar_t>
+class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<wchar_t>
     : public codecvt<wchar_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -459,7 +462,7 @@
 };
 
 template <>
-class __codecvt_utf8_utf16<char32_t>
+class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char32_t>
     : public codecvt<char32_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -494,7 +497,7 @@
 };
 
 template <>
-class __codecvt_utf8_utf16<char16_t>
+class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char16_t>
     : public codecvt<char16_t, char, mbstate_t>
 {
     unsigned long _Maxcode_;
@@ -530,7 +533,7 @@
 
 template <class _Elem, unsigned long _Maxcode = 0x10ffff,
           codecvt_mode _Mode = (codecvt_mode)0>
-class _LIBCPP_TYPE_VIS codecvt_utf8_utf16
+class _LIBCPP_TYPE_VIS_ONLY codecvt_utf8_utf16
     : public __codecvt_utf8_utf16<_Elem>
 {
 public:
diff --git a/include/complex b/include/complex
index a09bf70..2943da1 100644
--- a/include/complex
+++ b/include/complex
@@ -23,12 +23,12 @@
 public:
     typedef T value_type;
 
-    complex(const T& re = T(), const T& im = T());
-    complex(const complex&);
-    template<class X> complex(const complex<X>&);
+    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
+    complex(const complex&);  // constexpr in C++14
+    template<class X> complex(const complex<X>&);  // constexpr in C++14
 
-    T real() const;
-    T imag() const;
+    T real() const; // constexpr in C++14
+    T imag() const; // constexpr in C++14
 
     void real(T);
     void imag(T);
@@ -149,12 +149,12 @@
 template<class T> complex<T> operator/(const T&, const complex<T>&);
 template<class T> complex<T> operator+(const complex<T>&);
 template<class T> complex<T> operator-(const complex<T>&);
-template<class T> bool operator==(const complex<T>&, const complex<T>&);
-template<class T> bool operator==(const complex<T>&, const T&);
-template<class T> bool operator==(const T&, const complex<T>&);
-template<class T> bool operator!=(const complex<T>&, const complex<T>&);
-template<class T> bool operator!=(const complex<T>&, const T&);
-template<class T> bool operator!=(const T&, const complex<T>&);
+template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
+template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
+template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
 
 template<class T, class charT, class traits>
   basic_istream<charT, traits>&
@@ -165,17 +165,17 @@
 
 // 26.3.7 values:
 
-template<class T>              T real(const complex<T>&);
-                     long double real(long double);
-                          double real(double);
-template<Integral T>      double real(T);
-                          float  real(float);
+template<class T>              T real(const complex<T>&); // constexpr in C++14
+                     long double real(long double);       // constexpr in C++14
+                          double real(double);            // constexpr in C++14
+template<Integral T>      double real(T);                 // constexpr in C++14
+                          float  real(float);             // constexpr in C++14
 
-template<class T>              T imag(const complex<T>&);
-                     long double imag(long double);
-                          double imag(double);
-template<Integral T>      double imag(T);
-                          float  imag(float);
+template<class T>              T imag(const complex<T>&); // constexpr in C++14
+                     long double imag(long double);       // constexpr in C++14
+                          double imag(double);            // constexpr in C++14
+template<Integral T>      double imag(T);                 // constexpr in C++14
+                          float  imag(float);             // constexpr in C++14
 
 template<class T> T abs(const complex<T>&);
 
@@ -255,13 +255,13 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<class _Tp> class _LIBCPP_TYPE_VIS complex;
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY complex;
 
 template<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
 template<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
 
 template<class _Tp>
-class _LIBCPP_TYPE_VIS complex
+class _LIBCPP_TYPE_VIS_ONLY complex
 {
 public:
     typedef _Tp value_type;
@@ -269,15 +269,15 @@
     value_type __re_;
     value_type __im_;
 public:
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     complex(const value_type& __re = value_type(), const value_type& __im = value_type())
         : __re_(__re), __im_(__im) {}
-    template<class _Xp> _LIBCPP_INLINE_VISIBILITY
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     complex(const complex<_Xp>& __c)
         : __re_(__c.real()), __im_(__c.imag()) {}
 
-    _LIBCPP_INLINE_VISIBILITY value_type real() const {return __re_;}
-    _LIBCPP_INLINE_VISIBILITY value_type imag() const {return __im_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}
 
     _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
     _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
@@ -309,21 +309,21 @@
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
         {
-            *this = *this * __c;
+            *this = *this * complex(__c.real(), __c.imag());
             return *this;
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
         {
-            *this = *this / __c;
+            *this = *this / complex(__c.real(), __c.imag());
             return *this;
         }
 };
 
-template<> class _LIBCPP_TYPE_VIS complex<double>;
-template<> class _LIBCPP_TYPE_VIS complex<long double>;
+template<> class _LIBCPP_TYPE_VIS_ONLY complex<double>;
+template<> class _LIBCPP_TYPE_VIS_ONLY complex<long double>;
 
 template<>
-class _LIBCPP_TYPE_VIS complex<float>
+class _LIBCPP_TYPE_VIS_ONLY complex<float>
 {
     float __re_;
     float __im_;
@@ -368,18 +368,18 @@
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
         {
-            *this = *this * __c;
+            *this = *this * complex(__c.real(), __c.imag());
             return *this;
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
         {
-            *this = *this / __c;
+            *this = *this / complex(__c.real(), __c.imag());
             return *this;
         }
 };
 
 template<>
-class _LIBCPP_TYPE_VIS complex<double>
+class _LIBCPP_TYPE_VIS_ONLY complex<double>
 {
     double __re_;
     double __im_;
@@ -424,18 +424,18 @@
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
         {
-            *this = *this * __c;
+            *this = *this * complex(__c.real(), __c.imag());
             return *this;
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
         {
-            *this = *this / __c;
+            *this = *this / complex(__c.real(), __c.imag());
             return *this;
         }
 };
 
 template<>
-class _LIBCPP_TYPE_VIS complex<long double>
+class _LIBCPP_TYPE_VIS_ONLY complex<long double>
 {
     long double __re_;
     long double __im_;
@@ -480,12 +480,12 @@
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
         {
-            *this = *this * __c;
+            *this = *this * complex(__c.real(), __c.imag());
             return *this;
         }
     template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
         {
-            *this = *this / __c;
+            *this = *this / complex(__c.real(), __c.imag());
             return *this;
         }
 };
@@ -740,7 +740,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
 {
@@ -748,7 +748,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator==(const complex<_Tp>& __x, const _Tp& __y)
 {
@@ -756,7 +756,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator==(const _Tp& __x, const complex<_Tp>& __y)
 {
@@ -764,7 +764,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
 {
@@ -772,7 +772,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator!=(const complex<_Tp>& __x, const _Tp& __y)
 {
@@ -780,7 +780,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator!=(const _Tp& __x, const complex<_Tp>& __y)
 {
@@ -792,21 +792,21 @@
 // real
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp
 real(const complex<_Tp>& __c)
 {
     return __c.real();
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 long double
 real(long double __re)
 {
     return __re;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 double
 real(double __re)
 {
@@ -814,7 +814,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename enable_if
 <
     is_integral<_Tp>::value,
@@ -825,7 +825,7 @@
     return __re;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 float
 real(float  __re)
 {
@@ -835,21 +835,21 @@
 // imag
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp
 imag(const complex<_Tp>& __c)
 {
     return __c.imag();
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 long double
 imag(long double __re)
 {
     return 0;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 double
 imag(double __re)
 {
@@ -857,7 +857,7 @@
 }
 
 template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename enable_if
 <
     is_integral<_Tp>::value,
@@ -868,7 +868,7 @@
     return 0;
 }
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 float
 imag(float  __re)
 {
@@ -1521,6 +1521,47 @@
     return __os << __s.str();
 }
 
+#if _LIBCPP_STD_VER > 11 
+// Literal suffix for complex number literals [complex.literals]
+inline namespace literals
+{ 
+  inline namespace complex_literals
+  {
+    constexpr complex<long double> operator""il(long double __im)
+    {
+        return { 0.0l, __im };
+    }
+
+    constexpr complex<long double> operator""il(unsigned long long __im)
+    {
+        return { 0.0l, static_cast<long double>(__im) };
+    }
+
+
+    constexpr complex<double> operator""i(long double __im)
+    {
+        return { 0.0, static_cast<double>(__im) };
+    }
+
+    constexpr complex<double> operator""i(unsigned long long __im)
+    {
+        return { 0.0, static_cast<double>(__im) };
+    }
+
+
+    constexpr complex<float> operator""if(long double __im)
+    {
+        return { 0.0f, static_cast<float>(__im) };
+    }
+
+    constexpr complex<float> operator""if(unsigned long long __im)
+    {
+        return { 0.0f, static_cast<float>(__im) };
+    }
+  }
+}
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_COMPLEX
diff --git a/include/cstddef b/include/cstddef
index c263772..7ef16ff 100644
--- a/include/cstddef
+++ b/include/cstddef
@@ -56,7 +56,7 @@
 
 #ifdef _LIBCPP_HAS_NO_NULLPTR
 
-struct _LIBCPP_TYPE_VIS nullptr_t
+struct _LIBCPP_TYPE_VIS_ONLY nullptr_t
 {
     void* __lx;
 
diff --git a/include/cstdio b/include/cstdio
index a7b106f..e7d8fab 100644
--- a/include/cstdio
+++ b/include/cstdio
@@ -74,7 +74,7 @@
 int fputs(const char* restrict s, FILE* restrict stream);
 int getc(FILE* stream);
 int getchar(void);
-char* gets(char* s);
+char* gets(char* s);  // removed in C++14
 int putc(int c, FILE* stream);
 int putchar(int c);
 int puts(const char* s);
@@ -103,6 +103,11 @@
 #pragma GCC system_header
 #endif
 
+// snprintf
+#if defined(_LIBCPP_MSVCRT)
+#include "support/win32/support.h"
+#endif
+
 #ifdef getc
 inline _LIBCPP_INLINE_VISIBILITY int __libcpp_getc(FILE* __stream) {return getc(__stream);}
 #undef getc
@@ -138,12 +143,12 @@
 using ::snprintf;
 using ::sprintf;
 using ::sscanf;
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::vfprintf;
 using ::vfscanf;
 using ::vscanf;
 using ::vsscanf;
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 using ::vprintf;
 using ::vsnprintf;
 using ::vsprintf;
@@ -153,7 +158,9 @@
 using ::fputs;
 using ::getc;
 using ::getchar;
+#if _LIBCPP_STD_VER <= 11
 using ::gets;
+#endif
 using ::putc;
 using ::putchar;
 using ::puts;
diff --git a/include/cstdlib b/include/cstdlib
index 95e3842..152b891 100644
--- a/include/cstdlib
+++ b/include/cstdlib
@@ -84,9 +84,9 @@
 
 #include <__config>
 #include <stdlib.h>
-#ifdef _MSC_VER
+#ifdef _LIBCPP_MSVCRT
 #include "support/win32/locale_win32.h"
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -154,8 +154,8 @@
 using ::aligned_alloc;
 #endif
 
-// MSVC already has the correct prototype in <stdlib.h.h> #ifdef __cplusplus
-#if !defined(_MSC_VER) && !defined(__sun__)
+// MSVCRT already has the correct prototype in <stdlib.h> #ifdef __cplusplus
+#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
 inline _LIBCPP_INLINE_VISIBILITY long      abs(     long __x) _NOEXCEPT {return  labs(__x);}
 #ifndef _LIBCPP_HAS_NO_LONG_LONG
 inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}
@@ -165,7 +165,7 @@
 #ifndef _LIBCPP_HAS_NO_LONG_LONG
 inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}
 #endif // _LIBCPP_HAS_NO_LONG_LONG
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/cstring b/include/cstring
index 45075b3..21c9155 100644
--- a/include/cstring
+++ b/include/cstring
@@ -93,8 +93,8 @@
 
 using ::strstr;
 
-// MSVC, GNU libc and its derivates already have the correct prototype in <string.h> #ifdef __cplusplus
-#if !defined(__GLIBC__) && !defined(_MSC_VER) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
+// MSVCRT, GNU libc and its derivates already have the correct prototype in <string.h> #ifdef __cplusplus
+#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
 inline _LIBCPP_INLINE_VISIBILITY       char* strchr(      char* __s, int __c) {return ::strchr(__s, __c);}
 inline _LIBCPP_INLINE_VISIBILITY       char* strpbrk(      char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);}
 inline _LIBCPP_INLINE_VISIBILITY       char* strrchr(      char* __s, int __c) {return ::strrchr(__s, __c);}
diff --git a/include/cwchar b/include/cwchar
index 845ccec..9f51587 100644
--- a/include/cwchar
+++ b/include/cwchar
@@ -106,9 +106,9 @@
 #include <__config>
 #include <cwctype>
 #include <wchar.h>
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
 #include <support/win32/support.h> // pull in *swprintf defines
-#endif // _WIN32
+#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -127,12 +127,12 @@
 using ::vfwprintf;
 using ::vswprintf;
 using ::vwprintf;
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::swscanf;
 using ::vfwscanf;
 using ::vswscanf;
 using ::vwscanf;
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 using ::wprintf;
 using ::wscanf;
 using ::fgetwc;
@@ -146,10 +146,10 @@
 using ::putwchar;
 using ::ungetwc;
 using ::wcstod;
-#ifndef _MSC_VER
+#ifndef _LIBCPP_MSVCRT
 using ::wcstof;
 using ::wcstold;
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 using ::wcstol;
 #ifndef _LIBCPP_HAS_NO_LONG_LONG
 using ::wcstoll;
diff --git a/include/deque b/include/deque
index 8e09822..f099000 100644
--- a/include/deque
+++ b/include/deque
@@ -41,6 +41,7 @@
     deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
     explicit deque(const allocator_type& a);
     explicit deque(size_type n);
+    explicit deque(size_type n, const allocator_type& a); // C++14
     deque(size_type n, const value_type& v);
     deque(size_type n, const value_type& v, const allocator_type& a);
     template <class InputIterator>
@@ -170,7 +171,7 @@
 
 template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
           class _DiffType, _DiffType _BlockSize>
-class _LIBCPP_TYPE_VIS __deque_iterator;
+class _LIBCPP_TYPE_VIS_ONLY __deque_iterator;
 
 template <class _RAIter,
           class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
@@ -262,7 +263,7 @@
 
 template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
           class _DiffType, _DiffType _BlockSize>
-class _LIBCPP_TYPE_VIS __deque_iterator
+class _LIBCPP_TYPE_VIS_ONLY __deque_iterator
 {
     typedef _MapPointer __map_iterator;
 public:
@@ -278,7 +279,11 @@
     typedef random_access_iterator_tag  iterator_category;
     typedef _Reference                  reference;
 
-    _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+     : __m_iter_(nullptr), __ptr_(nullptr)
+#endif
+     {}
 
     template <class _Pp, class _Rp, class _MP>
     _LIBCPP_INLINE_VISIBILITY
@@ -410,9 +415,9 @@
         : __m_iter_(__m), __ptr_(__p) {}
 
     template <class _Tp, class _Ap> friend class __deque_base;
-    template <class _Tp, class _Ap> friend class _LIBCPP_TYPE_VIS deque;
+    template <class _Tp, class _Ap> friend class _LIBCPP_TYPE_VIS_ONLY deque;
     template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
-        friend class _LIBCPP_TYPE_VIS __deque_iterator;
+        friend class _LIBCPP_TYPE_VIS_ONLY __deque_iterator;
 
     template <class _RAIter,
               class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
@@ -915,7 +920,14 @@
                                                          __pointer_allocator;
     typedef allocator_traits<__pointer_allocator>        __map_traits;
     typedef typename __map_traits::pointer               __map_pointer;
-    typedef typename __map_traits::const_pointer         __map_const_pointer;
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<const_pointer>
+#else
+                rebind_alloc<const_pointer>::other
+#endif
+                                                         __const_pointer_allocator;
+    typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
     typedef __split_buffer<pointer, __pointer_allocator> __map;
 
     typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
@@ -1053,7 +1065,7 @@
 typename __deque_base<_Tp, _Allocator>::const_iterator
 __deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
 {
-    __map_const_pointer __mp = __map_.begin() + __start_ / __block_size;
+    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
     return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
 }
 
@@ -1071,7 +1083,7 @@
 __deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
 {
     size_type __p = size() + __start_;
-    __map_const_pointer __mp = __map_.begin() + __p / __block_size;
+    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
     return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
 }
 
@@ -1167,7 +1179,7 @@
 }
 
 template <class _Tp, class _Allocator = allocator<_Tp> >
-class _LIBCPP_TYPE_VIS deque
+class _LIBCPP_TYPE_VIS_ONLY deque
     : private __deque_base<_Tp, _Allocator>
 {
 public:
@@ -1198,6 +1210,9 @@
         {}
     _LIBCPP_INLINE_VISIBILITY deque(const allocator_type& __a) : __base(__a) {}
     explicit deque(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit deque(size_type __n, const _Allocator& __a);
+#endif
     deque(size_type __n, const value_type& __v);
     deque(size_type __n, const value_type& __v, const allocator_type& __a);
     template <class _InputIter>
@@ -1341,6 +1356,8 @@
     _LIBCPP_INLINE_VISIBILITY
     bool __invariants() const {return __base::__invariants();}
 private:
+    typedef typename __base::__map_const_pointer __map_const_pointer;
+
     _LIBCPP_INLINE_VISIBILITY
     static size_type __recommend_blocks(size_type __n)
     {
@@ -1418,6 +1435,16 @@
         __append(__n);
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
+    : __base(__a)
+{
+    if (__n > 0)
+        __append(__n);
+}
+#endif
+
 template <class _Tp, class _Allocator>
 deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
 {
@@ -2505,9 +2532,9 @@
 deque<_Tp, _Allocator>::pop_front()
 {
     allocator_type& __a = __base::__alloc();
-    __alloc_traits::destroy(__a, *(__base::__map_.begin() +
-                                   __base::__start_ / __base::__block_size) +
-                                   __base::__start_ % __base::__block_size);
+    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
+                                                    __base::__start_ / __base::__block_size) +
+                                                    __base::__start_ % __base::__block_size));
     --__base::size();
     if (++__base::__start_ >= 2 * __base::__block_size)
     {
@@ -2523,9 +2550,9 @@
 {
     allocator_type& __a = __base::__alloc();
     size_type __p = __base::size() + __base::__start_ - 1;
-    __alloc_traits::destroy(__a, *(__base::__map_.begin() +
-                                   __p / __base::__block_size) +
-                                   __p % __base::__block_size);
+    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
+                                                    __p / __base::__block_size) +
+                                                    __p % __base::__block_size));
     --__base::size();
     if (__back_spare() >= 2 * __base::__block_size)
     {
@@ -2556,7 +2583,7 @@
             __fe = __fb + __bs;
         }
         if (__fb <= __vt && __vt < __fe)
-            __vt = (const_iterator(__f.__m_iter_, __vt) -= __f - __r).__ptr_;
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
         __r = _VSTD::move(__fb, __fe, __r);
         __n -= __bs;
         __f += __bs;
@@ -2587,7 +2614,7 @@
             __lb = __le - __bs;
         }
         if (__lb <= __vt && __vt < __le)
-            __vt = (const_iterator(__l.__m_iter_, __vt) += __r - __l - 1).__ptr_;
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
         __r = _VSTD::move_backward(__lb, __le, __r);
         __n -= __bs;
         __l -= __bs - 1;
@@ -2618,7 +2645,7 @@
             __fe = __fb + __bs;
         }
         if (__fb <= __vt && __vt < __fe)
-            __vt = (const_iterator(__f.__m_iter_, __vt) += __r - __f).__ptr_;
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
         for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
             __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
         __n -= __bs;
@@ -2654,7 +2681,7 @@
             __lb = __le - __bs;
         }
         if (__lb <= __vt && __vt < __le)
-            __vt = (const_iterator(__l.__m_iter_, __vt) -= __l - __r + 1).__ptr_;
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
         while (__le != __lb)
         {
             __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
@@ -2784,7 +2811,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
 {
@@ -2793,7 +2820,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
 {
@@ -2801,7 +2828,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
 {
@@ -2809,7 +2836,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
 {
@@ -2817,7 +2844,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
 {
@@ -2825,7 +2852,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
 {
@@ -2833,7 +2860,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
diff --git a/include/exception b/include/exception
index 37bfc57..cad802e 100644
--- a/include/exception
+++ b/include/exception
@@ -118,8 +118,8 @@
 
 class _LIBCPP_TYPE_VIS exception_ptr;
 
-exception_ptr current_exception() _NOEXCEPT;
-_LIBCPP_NORETURN void rethrow_exception(exception_ptr);
+_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
 
 class _LIBCPP_TYPE_VIS exception_ptr
 {
@@ -142,8 +142,8 @@
     bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
         {return !(__x == __y);}
 
-    friend exception_ptr current_exception() _NOEXCEPT;
-    friend void rethrow_exception(exception_ptr);
+    friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
 };
 
 template<class _Ep>
diff --git a/include/experimental/dynarray b/include/experimental/dynarray
new file mode 100644
index 0000000..7c5c9b3
--- /dev/null
+++ b/include/experimental/dynarray
@@ -0,0 +1,314 @@
+// -*- C++ -*-
+//===-------------------------- dynarray ----------------------------------===//
+//
+//                     The 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_DYNARRAY
+#define _LIBCPP_DYNARRAY
+
+#include <__config>
+#if _LIBCPP_STD_VER > 11
+
+/*
+    dynarray synopsis
+
+namespace std { namespace experimental {
+
+template< typename T >
+class dynarray
+{
+    // types:
+    typedef       T                               value_type;
+    typedef       T&                              reference;
+    typedef const T&                              const_reference;
+    typedef       T*                              pointer;
+    typedef const T*                              const_pointer;
+    typedef       implementation-defined          iterator;
+    typedef       implementation-defined          const_iterator;
+    typedef reverse_iterator<iterator>            reverse_iterator;
+    typedef reverse_iterator<const_iterator>      const_reverse_iterator;
+    typedef size_t                                size_type;
+    typedef ptrdiff_t                             difference_type;
+
+public:
+    // construct/copy/destroy:
+    explicit dynarray(size_type c);
+    template <typename Alloc>
+      dynarray(size_type c, const Alloc& alloc);
+    dynarray(size_type c, const T& v);
+    template <typename Alloc>
+      dynarray(size_type c, const T& v, const Alloc& alloc);
+    dynarray(const dynarray& d);
+    template <typename Alloc>
+      dynarray(const dynarray& d, const Alloc& alloc);
+    dynarray(initializer_list<T>);
+    template <typename Alloc>
+      dynarray(initializer_list<T>, const Alloc& alloc);
+
+    dynarray& operator=(const dynarray&) = delete;
+    ~dynarray();
+
+    // iterators:
+    iterator       begin()        noexcept;
+    const_iterator begin()  const noexcept;
+    const_iterator cbegin() const noexcept;
+    iterator       end()          noexcept;
+    const_iterator end()    const noexcept;
+    const_iterator cend()   const noexcept;
+
+    reverse_iterator       rbegin()        noexcept;
+    const_reverse_iterator rbegin()  const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    reverse_iterator       rend()          noexcept;
+    const_reverse_iterator rend()    const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    // capacity:
+    size_type size()     const noexcept;
+    size_type max_size() const noexcept;
+    bool      empty()    const noexcept;
+
+    // element access:
+    reference       operator[](size_type n);
+    const_reference operator[](size_type n) const;
+
+    reference       front();
+    const_reference front() const;
+    reference       back();
+    const_reference back()  const;
+
+    const_reference at(size_type n) const;
+    reference       at(size_type n);
+
+    // data access:
+    T*       data()       noexcept;
+    const T* data() const noexcept;
+
+    // mutating member functions:
+    void fill(const T& v);
+};
+
+}}  // std::experimental
+
+*/
+
+#include <__functional_base>
+#include <iterator>
+#include <stdexcept>
+#include <initializer_list>
+#include <new>
+#include <algorithm>
+
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+    #include <cassert>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std { namespace experimental { inline namespace __array_extensions_v1 {
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY dynarray
+{
+public:
+    // types:
+    typedef dynarray __self;
+    typedef _Tp                                   value_type;
+    typedef value_type&                           reference;
+    typedef const value_type&                     const_reference;
+    typedef value_type*                           iterator;
+    typedef const value_type*                     const_iterator;
+    typedef value_type*                           pointer;
+    typedef const value_type*                     const_pointer;
+    typedef size_t                                size_type;
+    typedef ptrdiff_t                             difference_type;
+    typedef std::reverse_iterator<iterator>       reverse_iterator;
+    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+private:
+    size_t                  __size_;
+    value_type *            __base_;
+    _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {}
+    
+    static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count )
+    {
+        if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count )
+        {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            throw bad_array_length();
+#else
+            assert(!"dynarray::allocation");
+#endif
+        }
+        return static_cast<value_type *> (::operator new (sizeof(value_type) * count));
+    }
+
+    static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept
+    {
+        ::operator delete (static_cast<void *> (__ptr));
+    }
+
+public:
+
+    explicit dynarray(size_type __c);
+    dynarray(size_type __c, const value_type& __v);
+    dynarray(const dynarray& __d);
+    dynarray(initializer_list<value_type>);
+
+//  We're not implementing these right now.
+//  Waiting for the resolution of LWG issue #2235
+//     template <typename _Alloc>
+//       dynarray(size_type __c, const _Alloc& __alloc);
+//     template <typename _Alloc>
+//       dynarray(size_type __c, const value_type& __v, const _Alloc& __alloc);
+//     template <typename _Alloc>
+//       dynarray(const dynarray& __d, const _Alloc& __alloc);
+//     template <typename _Alloc>
+//       dynarray(initializer_list<value_type>, const _Alloc& __alloc);
+
+    dynarray& operator=(const dynarray&) = delete;
+    ~dynarray();
+
+    // iterators:
+    inline _LIBCPP_INLINE_VISIBILITY iterator       begin()        noexcept { return iterator(data()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator begin()  const noexcept { return const_iterator(data()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); }
+    inline _LIBCPP_INLINE_VISIBILITY iterator       end()          noexcept { return iterator(data() + __size_); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator end()    const noexcept { return const_iterator(data() + __size_); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator cend()   const noexcept { return const_iterator(data() + __size_); }
+
+    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rbegin()        noexcept { return reverse_iterator(end()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin()  const noexcept { return const_reverse_iterator(end()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
+    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rend()          noexcept { return reverse_iterator(begin()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend()    const noexcept { return const_reverse_iterator(begin()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend()   const noexcept { return const_reverse_iterator(begin()); }
+
+    // capacity:
+    inline _LIBCPP_INLINE_VISIBILITY size_type size()     const noexcept { return __size_; }
+    inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; }
+    inline _LIBCPP_INLINE_VISIBILITY bool      empty()    const noexcept { return __size_ == 0; }
+
+    // element access:
+    inline _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n)       { return data()[__n]; }
+    inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; }
+
+    inline _LIBCPP_INLINE_VISIBILITY reference       front()       { return data()[0]; }
+    inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; }
+    inline _LIBCPP_INLINE_VISIBILITY reference       back()        { return data()[__size_-1]; }
+    inline _LIBCPP_INLINE_VISIBILITY const_reference back()  const { return data()[__size_-1]; }
+
+    inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const;
+    inline _LIBCPP_INLINE_VISIBILITY reference       at(size_type __n);
+
+    // data access:
+    inline _LIBCPP_INLINE_VISIBILITY _Tp*       data()       noexcept { return __base_; }
+    inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; }
+
+    // mutating member functions:
+    inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); }
+};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(size_type __c) : dynarray ()
+{
+    __base_ = __allocate (__c);
+    value_type *__data = data ();
+    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
+        ::new (__data) value_type;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray ()
+{
+    __base_ = __allocate (__c);
+    value_type *__data = data ();
+    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
+        ::new (__data) value_type (__v);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray ()
+{
+    size_t sz = __il.size();
+    __base_ = __allocate (sz);
+    value_type *__data = data ();
+    auto src = __il.begin();
+    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
+        ::new (__data) value_type (*src);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()
+{
+    size_t sz = __d.size();
+    __base_ = __allocate (sz);
+    value_type *__data = data ();
+    auto src = __d.begin();
+    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
+        ::new (__data) value_type (*src);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::~dynarray()
+{ 
+    value_type *__data = data () + __size_;
+    for ( size_t i = 0; i < __size_; ++i )
+        (--__data)->value_type::~value_type();
+    __deallocate ( __base_ );
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename dynarray<_Tp>::reference
+dynarray<_Tp>::at(size_type __n)
+{
+    if (__n >= __size_)
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("dynarray::at");
+#else
+        assert(!"dynarray::at out_of_range");
+#endif
+    }
+    return data()[__n];
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename dynarray<_Tp>::const_reference
+dynarray<_Tp>::at(size_type __n) const
+{
+    if (__n >= __size_)
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("dynarray::at");
+#else
+        assert(!"dynarray::at out_of_range");
+#endif
+    }
+    return data()[__n];
+}
+
+}}}
+
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Tp, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // if _LIBCPP_STD_VER > 11 
+#endif  // _LIBCPP_DYNARRAY
diff --git a/include/experimental/optional b/include/experimental/optional
new file mode 100644
index 0000000..3848da8
--- /dev/null
+++ b/include/experimental/optional
@@ -0,0 +1,699 @@
+// -*- C++ -*-
+//===-------------------------- optional ----------------------------------===//
+//
+//                     The 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_OPTIONAL
+#define _LIBCPP_OPTIONAL
+
+/*
+    optional synopsis
+
+// C++1y
+
+#include <initializer_list>
+
+namespace std { namespace experimental {
+
+// optional for object types
+template <class T>
+class optional
+{
+public:
+    typedef T value_type;
+
+    // constructors
+    constexpr optional() noexcept;
+    constexpr optional(nullopt_t) noexcept;
+    optional(const optional&);
+    optional(optional&&) noexcept(is_nothrow_move_constructible<T>::value);
+    constexpr optional(const T&);
+    constexpr optional(T&&);
+    template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
+    template <class U, class... Args>
+        constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
+
+    // destructor
+    ~optional();
+
+    // assignment
+    optional& operator=(nullopt_t) noexcept;
+    optional& operator=(const optional&);
+    optional& operator=(optional&&)
+        noexcept(is_nothrow_move_assignable<T>::value &&
+                 is_nothrow_move_constructible<T>::value);
+    template <class U> optional& operator=(U&&);
+    template <class... Args> void emplace(Args&&...);
+    template <class U, class... Args> void emplace(initializer_list<U>, Args&&...);
+
+    // swap
+    void swap(optional&)
+        noexcept(is_nothrow_move_constructible<T>::value &&
+                 noexcept(swap(declval<T&>(), declval<T&>())));
+
+    // observers
+    constexpr T const* operator->() const;
+    T* operator->();
+    constexpr T const& operator*() const;
+    T& operator*();
+    constexpr explicit operator bool() const noexcept;
+    constexpr T const& value() const;
+    T& value();
+    template <class U> constexpr T value_or(U&&) const&;
+    template <class U> T value_or(U&&) &&;
+};
+
+// In-place construction
+struct in_place_t{};
+constexpr in_place_t in_place{};
+
+// Disengaged state indicator
+struct nullopt_t{see below};
+constexpr nullopt_t nullopt(unspecified);
+
+// class bad_optional_access
+class bad_optional_access
+    : public logic_error
+{
+public:
+    explicit bad_optional_access(const string& what_arg);
+    explicit bad_optional_access(const char* what_arg);
+};
+
+// Relational operators
+template <class T> constexpr bool operator==(const optional<T>&, const optional<T>&);
+template <class T> constexpr bool operator< (const optional<T>&, const optional<T>&);
+
+// Comparison with nullopt
+template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
+template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
+template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
+template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
+
+// Comparison with T
+template <class T> constexpr bool operator==(const optional<T>&, const T&);
+template <class T> constexpr bool operator==(const T&, const optional<T>&);
+template <class T> constexpr bool operator<(const optional<T>&, const T&);
+template <class T> constexpr bool operator<(const T&, const optional<T>&);
+
+// Specialized algorithms
+template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
+template <class T> constexpr optional<typename decay<T>::type> make_optional(T&&);
+
+// hash support
+template <class T> struct hash;
+template <class T> struct hash<optional<T>>;
+
+}}  // std::experimental
+
+*/
+
+#include <__config>
+#include <functional>
+#include <stdexcept>
+
+namespace std { namespace experimental {
+
+class _LIBCPP_EXCEPTION_ABI bad_optional_access
+    : public logic_error
+{
+public:
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const string& __arg)
+        : logic_error(__arg) {}
+    _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const char* __arg)
+        : logic_error(__arg) {}
+    _LIBCPP_INLINE_VISIBILITY bad_optional_access(const bad_optional_access&) noexcept = default;
+    _LIBCPP_INLINE_VISIBILITY bad_optional_access& operator=(const bad_optional_access&) noexcept = default;
+#else
+private:
+    bad_optional_access(const bad_optional_access&);
+    bad_optional_access& operator=(const bad_optional_access&);
+public:
+#endif  // _LIBCPP_STD_VER > 11
+    // Get the key function ~bad_optional_access() into the dylib even if not compiling for C++1y
+    virtual ~bad_optional_access() _NOEXCEPT;
+};
+
+}}  // std::experimental
+
+#if _LIBCPP_STD_VER > 11
+
+#include <initializer_list>
+#include <type_traits>
+#include <new>
+#include <__functional_base>
+
+#include <__undef_min_max>
+
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std { namespace experimental { inline namespace __library_fundamentals_v1 {
+
+struct in_place_t {};
+constexpr in_place_t in_place{};
+
+struct nullopt_t
+{
+    explicit constexpr nullopt_t(int) noexcept {}
+};
+
+constexpr nullopt_t nullopt{0};
+
+template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
+class __optional_storage
+{
+protected:
+    typedef _Tp value_type;
+    union
+    {
+        char __null_state_;
+        value_type __val_;
+    };
+    bool __engaged_ = false;
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__optional_storage()
+    {
+        if (__engaged_)
+            __val_.~value_type();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage() noexcept
+        :  __null_state_('\0') {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(const __optional_storage& __x)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(__optional_storage&& __x)
+                      noexcept(is_nothrow_move_constructible<value_type>::value)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(const value_type& __v)
+        :  __val_(__v),
+           __engaged_(true) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(value_type&& __v)
+        :  __val_(_VSTD::move(__v)),
+           __engaged_(true) {}
+
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit __optional_storage(in_place_t, _Args&&... __args)
+       :  __val_(_VSTD::forward<_Args>(__args)...),
+           __engaged_(true) {}
+};
+
+template <class _Tp>
+class __optional_storage<_Tp, true>
+{
+protected:
+    typedef _Tp value_type;
+    union
+    {
+        char __null_state_;
+        value_type __val_;
+    };
+    bool __engaged_ = false;
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage() noexcept
+        :  __null_state_('\0') {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(const __optional_storage& __x)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(__optional_storage&& __x)
+                      noexcept(is_nothrow_move_constructible<value_type>::value)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(const value_type& __v)
+        :  __val_(__v),
+           __engaged_(true) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(value_type&& __v)
+        :  __val_(_VSTD::move(__v)),
+           __engaged_(true) {}
+
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit __optional_storage(in_place_t, _Args&&... __args)
+       :  __val_(_VSTD::forward<_Args>(__args)...),
+           __engaged_(true) {}
+};
+
+template <class _Tp>
+class optional
+    : private __optional_storage<_Tp>
+{
+    typedef __optional_storage<_Tp> __base;
+public:
+    typedef _Tp value_type;
+
+    static_assert(!is_reference<value_type>::value,
+              "Instantiation of optional with a reference type is ill-formed.");
+    static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
+              "Instantiation of optional with a in_place_t type is ill-formed.");
+    static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
+              "Instantiation of optional with a nullopt_t type is ill-formed.");
+    static_assert(is_object<value_type>::value,
+        "Instantiation of optional with a non-object type is undefined behavior.");
+    static_assert(is_nothrow_destructible<value_type>::value,
+        "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
+
+    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
+    _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
+    _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
+    _LIBCPP_INLINE_VISIBILITY ~optional() = default;
+    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
+    _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
+        : __base(__v) {}
+    _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
+        : __base(_VSTD::move(__v)) {}
+
+    template <class... _Args,
+              class = typename enable_if
+                      <
+                           is_constructible<value_type, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit optional(in_place_t, _Args&&... __args)
+        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
+
+    template <class _Up, class... _Args,
+              class = typename enable_if
+                      <
+                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
+        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    optional& operator=(nullopt_t) noexcept
+    {
+        if (this->__engaged_)
+        {
+            this->__val_.~value_type();
+            this->__engaged_ = false;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    optional&
+    operator=(const optional& __opt)
+    {
+        if (this->__engaged_ == __opt.__engaged_)
+        {
+            if (this->__engaged_)
+                this->__val_ = __opt.__val_;
+        }
+        else
+        {
+            if (this->__engaged_)
+                this->__val_.~value_type();
+            else
+                ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
+            this->__engaged_ = __opt.__engaged_;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    optional&
+    operator=(optional&& __opt)
+        noexcept(is_nothrow_move_assignable<value_type>::value &&
+                 is_nothrow_move_constructible<value_type>::value)
+    {
+        if (this->__engaged_ == __opt.__engaged_)
+        {
+            if (this->__engaged_)
+                this->__val_ = _VSTD::move(__opt.__val_);
+        }
+        else
+        {
+            if (this->__engaged_)
+                this->__val_.~value_type();
+            else
+                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
+            this->__engaged_ = __opt.__engaged_;
+        }
+        return *this;
+    }
+
+    template <class _Up,
+              class = typename enable_if
+                      <
+                          is_same<typename remove_reference<_Up>::type, value_type>::value &&
+                          is_constructible<value_type, _Up>::value &&
+                          is_assignable<value_type&, _Up>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    optional&
+    operator=(_Up&& __v)
+    {
+        if (this->__engaged_)
+            this->__val_ = _VSTD::forward<_Up>(__v);
+        else
+        {
+            ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
+            this->__engaged_ = true;
+        }
+        return *this;
+    }
+
+    template <class... _Args,
+              class = typename enable_if
+                      <
+                          is_constructible<value_type, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    emplace(_Args&&... __args)
+    {
+        *this = nullopt;
+        ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
+        this->__engaged_ = true;
+    }
+
+    template <class _Up, class... _Args,
+              class = typename enable_if
+                      <
+                          is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    emplace(initializer_list<_Up> __il, _Args&&... __args)
+    {
+        *this = nullopt;
+        ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
+        this->__engaged_ = true;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    swap(optional& __opt)
+        noexcept(is_nothrow_move_constructible<value_type>::value &&
+                 __is_nothrow_swappable<value_type>::value)
+    {
+        using _VSTD::swap;
+        if (this->__engaged_ == __opt.__engaged_)
+        {
+            if (this->__engaged_)
+                swap(this->__val_, __opt.__val_);
+        }
+        else
+        {
+            if (this->__engaged_)
+            {
+                ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
+                this->__val_.~value_type();
+            }
+            else
+            {
+                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
+                __opt.__val_.~value_type();
+            }
+            swap(this->__engaged_, __opt.__engaged_);
+        }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    value_type const*
+    operator->() const
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
+        return __operator_arrow(__has_operator_addressof<value_type>{});
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type*
+    operator->()
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
+        return _VSTD::addressof(this->__val_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    const value_type&
+    operator*() const
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
+        return this->__val_;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type&
+    operator*()
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
+        return this->__val_;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr explicit operator bool() const noexcept {return this->__engaged_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr value_type const& value() const
+    {
+        if (!this->__engaged_)
+            throw bad_optional_access("optional<T>::value: not engaged");
+        return this->__val_;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type& value()
+    {
+        if (!this->__engaged_)
+            throw bad_optional_access("optional<T>::value: not engaged");
+        return this->__val_;
+    }
+
+    template <class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr value_type value_or(_Up&& __v) const&
+    {
+        static_assert(is_copy_constructible<value_type>::value,
+                      "optional<T>::value_or: T must be copy constructible");
+        static_assert(is_convertible<_Up, value_type>::value,
+                      "optional<T>::value_or: U must be convertible to T");
+        return this->__engaged_ ? this->__val_ :
+                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
+    }
+
+    template <class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    value_type value_or(_Up&& __v) &&
+    {
+        static_assert(is_move_constructible<value_type>::value,
+                      "optional<T>::value_or: T must be move constructible");
+        static_assert(is_convertible<_Up, value_type>::value,
+                      "optional<T>::value_or: U must be convertible to T");
+        return this->__engaged_ ? _VSTD::move(this->__val_) :
+                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
+    }
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    value_type const*
+    __operator_arrow(true_type) const
+    {
+        return _VSTD::addressof(this->__val_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    value_type const*
+    __operator_arrow(false_type) const
+    {
+        return &this->__val_;
+    }
+};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
+{
+    if (static_cast<bool>(__x) != static_cast<bool>(__y))
+        return false;
+    if (!static_cast<bool>(__x))
+        return true;
+    return *__x == *__y;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
+{
+    if (!static_cast<bool>(__y))
+        return false;
+    if (!static_cast<bool>(__x))
+        return true;
+    return less<_Tp>{}(*__x, *__y);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const optional<_Tp>& __x, nullopt_t) noexcept
+{
+    return !static_cast<bool>(__x);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(nullopt_t, const optional<_Tp>& __x) noexcept
+{
+    return !static_cast<bool>(__x);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const optional<_Tp>&, nullopt_t) noexcept
+{
+    return false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(nullopt_t, const optional<_Tp>& __x) noexcept
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const optional<_Tp>& __x, const _Tp& __v)
+{
+    return static_cast<bool>(__x) ? *__x == __v : false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const _Tp& __v, const optional<_Tp>& __x)
+{
+    return static_cast<bool>(__x) ? *__x == __v : false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const optional<_Tp>& __x, const _Tp& __v)
+{
+    return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const _Tp& __v, const optional<_Tp>& __x)
+{
+    return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+optional<typename decay<_Tp>::type>
+make_optional(_Tp&& __v)
+{
+    return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
+}
+
+}}}  // namespace std::experimental::__library_fundamentals_v1
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
+{
+    typedef std::experimental::optional<_Tp> argument_type;
+    typedef size_t        result_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()(const argument_type& __opt) const _NOEXCEPT
+    {
+        return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
+    }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STD_VER > 11
+
+#endif  // _LIBCPP_ARRAY
diff --git a/include/ext/__hash b/include/ext/__hash
index f6ecfe3..04975bf 100644
--- a/include/ext/__hash
+++ b/include/ext/__hash
@@ -19,10 +19,10 @@
 namespace __gnu_cxx {
 using namespace std;
 
-template <typename T> struct _LIBCPP_TYPE_VIS hash : public std::hash<T>
+template <typename T> struct _LIBCPP_TYPE_VIS_ONLY hash : public std::hash<T>
     { };
 
-template <> struct _LIBCPP_TYPE_VIS hash<const char*>
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<const char*>
     : public unary_function<const char*, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -32,7 +32,7 @@
     }
 };
 
-template <> struct _LIBCPP_TYPE_VIS hash<char *>
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<char *>
     : public unary_function<char*, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
diff --git a/include/ext/hash_map b/include/ext/hash_map
index a6fe894..225b72b 100644
--- a/include/ext/hash_map
+++ b/include/ext/hash_map
@@ -206,7 +206,11 @@
 #include <ext/__hash>
 
 #if __DEPRECATED
-#warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
+#if defined(_MSC_VER) && ! defined(__clang__)
+    _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>")
+#else
+#   warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
+#endif
 #endif
 
 #pragma GCC system_header
@@ -361,7 +365,7 @@
 };
 
 template <class _HashIterator>
-class _LIBCPP_TYPE_VIS __hash_map_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator
 {
     _HashIterator __i_;
 
@@ -404,15 +408,15 @@
     bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
         {return __x.__i_ != __y.__i_;}
 
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS hash_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS hash_multimap;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_local_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_map_const_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
 };
 
 template <class _HashIterator>
-class _LIBCPP_TYPE_VIS __hash_map_const_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator
 {
     _HashIterator __i_;
 
@@ -463,15 +467,15 @@
     bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
         {return __x.__i_ != __y.__i_;}
 
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS hash_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS hash_multimap;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_local_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
 };
 
 template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
           class _Alloc = allocator<pair<const _Key, _Tp> > >
-class _LIBCPP_TYPE_VIS hash_map
+class _LIBCPP_TYPE_VIS_ONLY hash_map
 {
 public:
     // types
@@ -684,7 +688,7 @@
     __h.get_deleter().__first_constructed = true;
     __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
     __h.get_deleter().__second_constructed = true;
-    return _VSTD::move(__h);
+    return _VSTD::move(__h);  // explicitly moved for C++03
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -750,7 +754,7 @@
 
 template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
           class _Alloc = allocator<pair<const _Key, _Tp> > >
-class _LIBCPP_TYPE_VIS hash_multimap
+class _LIBCPP_TYPE_VIS_ONLY hash_multimap
 {
 public:
     // types
diff --git a/include/ext/hash_set b/include/ext/hash_set
index 52bbeee..c4bb898 100644
--- a/include/ext/hash_set
+++ b/include/ext/hash_set
@@ -199,7 +199,11 @@
 #include <ext/__hash>
 
 #if __DEPRECATED
-#warning Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>
+#if defined(_MSC_VER) && ! defined(__clang__)
+    _LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>")
+#else
+#   warning Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>
+#endif
 #endif
 
 namespace __gnu_cxx {
@@ -208,7 +212,7 @@
 
 template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
           class _Alloc = allocator<_Value> >
-class _LIBCPP_TYPE_VIS hash_set
+class _LIBCPP_TYPE_VIS_ONLY hash_set
 {
 public:
     // types
@@ -429,7 +433,7 @@
 
 template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
           class _Alloc = allocator<_Value> >
-class _LIBCPP_TYPE_VIS hash_multiset
+class _LIBCPP_TYPE_VIS_ONLY hash_multiset
 {
 public:
     // types
diff --git a/include/forward_list b/include/forward_list
index 0cbf2fd..398226b 100644
--- a/include/forward_list
+++ b/include/forward_list
@@ -38,6 +38,7 @@
         noexcept(is_nothrow_default_constructible<allocator_type>::value);
     explicit forward_list(const allocator_type& a);
     explicit forward_list(size_type n);
+    explicit forward_list(size_type n, const allocator_type& a); // C++14
     forward_list(size_type n, const value_type& v);
     forward_list(size_type n, const value_type& v, const allocator_type& a);
     template <class InputIterator>
@@ -212,11 +213,11 @@
     value_type __value_;
 };
 
-template<class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS forward_list;
-template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS __forward_list_const_iterator;
+template<class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS_ONLY forward_list;
+template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
 
 template <class _NodePtr>
-class _LIBCPP_TYPE_VIS __forward_list_iterator
+class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator
 {
     typedef _NodePtr __node_pointer;
 
@@ -225,14 +226,14 @@
     _LIBCPP_INLINE_VISIBILITY
     explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
 
-    template<class, class> friend class _LIBCPP_TYPE_VIS forward_list;
-    template<class> friend class _LIBCPP_TYPE_VIS __forward_list_const_iterator;
+    template<class, class> friend class _LIBCPP_TYPE_VIS_ONLY forward_list;
+    template<class> friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
 
 public:
     typedef forward_iterator_tag                              iterator_category;
     typedef typename pointer_traits<__node_pointer>::element_type::value_type
                                                               value_type;
-    typedef value_type& reference;
+    typedef value_type&                                       reference;
     typedef typename pointer_traits<__node_pointer>::difference_type
                                                               difference_type;
     typedef typename pointer_traits<__node_pointer>::template
@@ -249,7 +250,7 @@
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {return __ptr_->__value_;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return &__ptr_->__value_;}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
     __forward_list_iterator& operator++()
@@ -276,7 +277,7 @@
 };
 
 template <class _NodeConstPtr>
-class _LIBCPP_TYPE_VIS __forward_list_const_iterator
+class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator
 {
     typedef _NodeConstPtr __node_const_pointer;
 
@@ -303,7 +304,7 @@
 public:
     typedef forward_iterator_tag                              iterator_category;
     typedef typename __node::value_type                       value_type;
-    typedef const value_type& reference;
+    typedef const value_type&                                 reference;
     typedef typename pointer_traits<__node_const_pointer>::difference_type
                                                               difference_type;
     typedef typename pointer_traits<__node_const_pointer>::template
@@ -323,7 +324,7 @@
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {return __ptr_->__value_;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return &__ptr_->__value_;}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
     __forward_list_const_iterator& operator++()
@@ -368,18 +369,27 @@
                                                       __node_allocator;
     typedef allocator_traits<__node_allocator>        __node_traits;
     typedef typename __node_traits::pointer           __node_pointer;
-    typedef typename __node_traits::const_pointer     __node_const_pointer;
+    typedef typename __node_traits::pointer           __node_const_pointer;
+
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__begin_node>
+#else
+                rebind_alloc<__begin_node>::other
+#endif
+                                                      __begin_node_allocator;
+    typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;
 
     __compressed_pair<__begin_node, __node_allocator> __before_begin_;
 
     _LIBCPP_INLINE_VISIBILITY
     __node_pointer        __before_begin() _NOEXCEPT
-        {return pointer_traits<__node_pointer>::pointer_to(
-                                static_cast<__node&>(__before_begin_.first()));}
+        {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>::
+                                        pointer_to(__before_begin_.first()));}
     _LIBCPP_INLINE_VISIBILITY
     __node_const_pointer  __before_begin() const _NOEXCEPT
-        {return pointer_traits<__node_const_pointer>::pointer_to(
-                          static_cast<const __node&>(__before_begin_.first()));}
+        {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>::
+                                        pointer_to(const_cast<__begin_node&>(__before_begin_.first())));}
 
     _LIBCPP_INLINE_VISIBILITY
           __node_allocator& __alloc() _NOEXCEPT
@@ -389,7 +399,7 @@
         {return __before_begin_.second();}
 
     typedef __forward_list_iterator<__node_pointer>             iterator;
-    typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
+    typedef __forward_list_const_iterator<__node_pointer>       const_iterator;
 
     _LIBCPP_INLINE_VISIBILITY
     __forward_list_base()
@@ -533,7 +543,7 @@
 }
 
 template <class _Tp, class _Alloc = allocator<_Tp> >
-class _LIBCPP_TYPE_VIS forward_list
+class _LIBCPP_TYPE_VIS_ONLY forward_list
     : private __forward_list_base<_Tp, _Alloc>
 {
     typedef __forward_list_base<_Tp, _Alloc> base;
@@ -562,6 +572,9 @@
         {} // = default;
     explicit forward_list(const allocator_type& __a);
     explicit forward_list(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit forward_list(size_type __n, const allocator_type& __a);
+#endif
     forward_list(size_type __n, const value_type& __v);
     forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
     template <class _InputIterator>
@@ -785,6 +798,28 @@
     }
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a)
+    : base ( __a )
+{
+    if (__n > 0)
+    {
+        __node_allocator& __a = base::__alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
+        for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
+                                                             __p = __p->__next_)
+        {
+            __h.reset(__node_traits::allocate(__a, 1));
+            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
+            __h->__next_ = nullptr;
+            __p->__next_ = __h.release();
+        }
+    }
+}
+#endif
+
 template <class _Tp, class _Alloc>
 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
 {
@@ -1050,7 +1085,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
 {
-    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer const __r = __p.__ptr_;
     __node_allocator& __a = base::__alloc();
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
@@ -1067,7 +1102,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
 {
-    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer const __r = __p.__ptr_;
     __node_allocator& __a = base::__alloc();
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
@@ -1083,7 +1118,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
 {
-    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer const __r = __p.__ptr_;
     __node_allocator& __a = base::__alloc();
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
@@ -1098,7 +1133,7 @@
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
                                         const value_type& __v)
 {
-    __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer __r = __p.__ptr_;
     if (__n > 0)
     {
         __node_allocator& __a = base::__alloc();
@@ -1148,7 +1183,7 @@
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
                                         _InputIterator __f, _InputIterator __l)
 {
-    __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer __r = __p.__ptr_;
     if (__f != __l)
     {
         __node_allocator& __a = base::__alloc();
@@ -1192,7 +1227,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
 {
-    __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
+    __node_pointer __p = __f.__ptr_;
     __node_pointer __n = __p->__next_;
     __p->__next_ = __n->__next_;
     __node_allocator& __a = base::__alloc();
@@ -1205,10 +1240,10 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
 {
-    __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
+    __node_pointer __e = __l.__ptr_;
     if (__f != __l)
     {
-        __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
+        __node_pointer __p = __f.__ptr_;
         __node_pointer __n = __p->__next_;
         if (__n != __e)
         {
@@ -1302,12 +1337,10 @@
             const_iterator __lm1 = __x.before_begin();
             while (__lm1.__ptr_->__next_ != nullptr)
                 ++__lm1;
-            const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__p.__ptr_)->__next_;
+            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
         }
-        const_cast<__node_pointer>(__p.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__x.__before_begin())->__next_;
-        const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
+        __p.__ptr_->__next_ = __x.__before_begin()->__next_;
+        __x.__before_begin()->__next_ = nullptr;
     }
 }
 
@@ -1320,12 +1353,9 @@
     const_iterator __lm1 = _VSTD::next(__i);
     if (__p != __i && __p != __lm1)
     {
-        const_cast<__node_pointer>(__i.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
-        const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__p.__ptr_)->__next_;
-        const_cast<__node_pointer>(__p.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__lm1.__ptr_);
+        __i.__ptr_->__next_ = __lm1.__ptr_->__next_;
+        __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
+        __p.__ptr_->__next_ = __lm1.__ptr_;
     }
 }
 
@@ -1342,12 +1372,9 @@
             ++__lm1;
         if (__f != __lm1)
         {
-            const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__p.__ptr_)->__next_;
-            const_cast<__node_pointer>(__p.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__f.__ptr_)->__next_;
-            const_cast<__node_pointer>(__f.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__l.__ptr_);
+            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
+            __p.__ptr_->__next_ = __f.__ptr_->__next_;
+            __f.__ptr_->__next_ = __l.__ptr_;
         }
     }
 }
diff --git a/include/fstream b/include/fstream
index e3f8306..38778c6 100644
--- a/include/fstream
+++ b/include/fstream
@@ -180,7 +180,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_filebuf
+class _LIBCPP_TYPE_VIS_ONLY basic_filebuf
     : public basic_streambuf<_CharT, _Traits>
 {
 public:
@@ -994,7 +994,7 @@
 // basic_ifstream
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_ifstream
+class _LIBCPP_TYPE_VIS_ONLY basic_ifstream
     : public basic_istream<_CharT, _Traits>
 {
 public:
@@ -1139,7 +1139,7 @@
 // basic_ofstream
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_ofstream
+class _LIBCPP_TYPE_VIS_ONLY basic_ofstream
     : public basic_ostream<_CharT, _Traits>
 {
 public:
@@ -1284,7 +1284,7 @@
 // basic_fstream
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_fstream
+class _LIBCPP_TYPE_VIS_ONLY basic_fstream
     : public basic_iostream<_CharT, _Traits>
 {
 public:
diff --git a/include/functional b/include/functional
index 995db56..d40f70a 100644
--- a/include/functional
+++ b/include/functional
@@ -56,7 +56,7 @@
 
     // invoke
     template <class... ArgTypes>
-      typename result_of<T(ArgTypes...)>::type
+      typename result_of<T&(ArgTypes&&...)>::type
           operator() (ArgTypes&&...) const;
 };
 
@@ -68,96 +68,120 @@
 template <class T> void cref(const T&& t) = delete;
 template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct plus : binary_function<T, T, T>
 {
     T operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct minus : binary_function<T, T, T>
 {
     T operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct multiplies : binary_function<T, T, T>
 {
     T operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct divides : binary_function<T, T, T>
 {
     T operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct modulus : binary_function<T, T, T>
 {
     T operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct negate : unary_function<T, T>
 {
     T operator()(const T& x) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct equal_to : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct not_equal_to : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct greater : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct less : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct greater_equal : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct less_equal : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct logical_and : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct logical_or : binary_function<T, T, bool>
 {
     bool operator()(const T& x, const T& y) const;
 };
 
-template <class T>
+template <class T> // <class T=void> in C++14
 struct logical_not : unary_function<T, bool>
 {
     bool operator()(const T& x) const;
 };
 
+template <class T> // <class T=void> in C++14
+struct bit_and : unary_function<T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct bit_or : unary_function<T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct bit_xor : unary_function<T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T=void> // C++14
+struct bit_xor : unary_function<T, bool>
+{
+    bool operator()(const T& x) const;
+};
+
 template <class Predicate>
 class unary_negate
     : public unary_function<typename Predicate::argument_type, bool>
@@ -334,18 +358,6 @@
 template <class S, class T, class A> const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const);
 
 template<class R, class T> unspecified mem_fn(R T::*);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...));
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) const);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) volatile);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) const volatile);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) &);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) const &);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) volatile &);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) const volatile &);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) &&);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) const &&);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) volatile &&);
-template<class R, class T, class... Args> unspecified mem_fn(R (T::*)(Args...) const volatile &&);
 
 class bad_function_call
     : public exception
@@ -473,166 +485,496 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS plus : binary_function<_Tp, _Tp, _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY plus : binary_function<_Tp, _Tp, _Tp>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x + __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS minus : binary_function<_Tp, _Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY plus<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY minus : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x - __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS multiplies : binary_function<_Tp, _Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY minus<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY multiplies : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x * __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS divides : binary_function<_Tp, _Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY multiplies<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY divides : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x / __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS modulus : binary_function<_Tp, _Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY divides<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY modulus : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x % __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS negate : unary_function<_Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY modulus<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY negate : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
         {return -__x;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS equal_to : binary_function<_Tp, _Tp, bool>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY negate<void>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+        { return -_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY equal_to : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x == __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS not_equal_to : binary_function<_Tp, _Tp, bool>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY equal_to<void>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY not_equal_to : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x != __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS greater : binary_function<_Tp, _Tp, bool>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY not_equal_to<void>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY greater : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x > __y;}
 };
 
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY greater<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
 // less in <__functional_base>
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS greater_equal : binary_function<_Tp, _Tp, bool>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY greater_equal : binary_function<_Tp, _Tp, bool>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x >= __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS less_equal : binary_function<_Tp, _Tp, bool>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY greater_equal<void>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY less_equal : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x <= __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS logical_and : binary_function<_Tp, _Tp, bool>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY less_equal<void>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY logical_and : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x && __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS logical_or : binary_function<_Tp, _Tp, bool>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY logical_and<void>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY logical_or : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
         {return __x || __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS logical_not : unary_function<_Tp, bool>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY logical_or<void>
 {
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY logical_not : unary_function<_Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x) const
         {return !__x;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS bit_and : binary_function<_Tp, _Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY logical_not<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+        { return !_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY bit_and : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x & __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS bit_or : binary_function<_Tp, _Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_and<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY bit_or : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x | __y;}
 };
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS bit_xor : binary_function<_Tp, _Tp, _Tp>
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_or<void>
 {
-    _LIBCPP_INLINE_VISIBILITY _Tp operator()(const _Tp& __x, const _Tp& __y) const
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY bit_xor : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
         {return __x ^ __y;}
 };
 
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_xor<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+struct _LIBCPP_TYPE_VIS_ONLY bit_not : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return ~__x;}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_not<void>
+{
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+        { return ~_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
 template <class _Predicate>
-class _LIBCPP_TYPE_VIS unary_negate
+class _LIBCPP_TYPE_VIS_ONLY unary_negate
     : public unary_function<typename _Predicate::argument_type, bool>
 {
     _Predicate __pred_;
 public:
-    _LIBCPP_INLINE_VISIBILITY explicit unary_negate(const _Predicate& __pred)
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    explicit unary_negate(const _Predicate& __pred)
         : __pred_(__pred) {}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const typename _Predicate::argument_type& __x) const
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Predicate::argument_type& __x) const
         {return !__pred_(__x);}
 };
 
 template <class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
 unary_negate<_Predicate>
 not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
 
 template <class _Predicate>
-class _LIBCPP_TYPE_VIS binary_negate
+class _LIBCPP_TYPE_VIS_ONLY binary_negate
     : public binary_function<typename _Predicate::first_argument_type,
                              typename _Predicate::second_argument_type,
                              bool>
 {
     _Predicate __pred_;
 public:
-    _LIBCPP_INLINE_VISIBILITY explicit binary_negate(const _Predicate& __pred)
-        : __pred_(__pred) {}
-    _LIBCPP_INLINE_VISIBILITY bool operator()(const typename _Predicate::first_argument_type& __x,
+    _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 
+    binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
+
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Predicate::first_argument_type& __x,
                     const typename _Predicate::second_argument_type& __y) const
         {return !__pred_(__x, __y);}
 };
 
 template <class _Predicate>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
 binary_negate<_Predicate>
 not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
 
 template <class __Operation>
-class _LIBCPP_TYPE_VIS binder1st
+class _LIBCPP_TYPE_VIS_ONLY binder1st
     : public unary_function<typename __Operation::second_argument_type,
                             typename __Operation::result_type>
 {
@@ -658,7 +1000,7 @@
     {return binder1st<__Operation>(__op, __x);}
 
 template <class __Operation>
-class _LIBCPP_TYPE_VIS binder2nd
+class _LIBCPP_TYPE_VIS_ONLY binder2nd
     : public unary_function<typename __Operation::first_argument_type,
                             typename __Operation::result_type>
 {
@@ -684,7 +1026,7 @@
     {return binder2nd<__Operation>(__op, __x);}
 
 template <class _Arg, class _Result>
-class _LIBCPP_TYPE_VIS pointer_to_unary_function
+class _LIBCPP_TYPE_VIS_ONLY pointer_to_unary_function
     : public unary_function<_Arg, _Result>
 {
     _Result (*__f_)(_Arg);
@@ -702,7 +1044,7 @@
     {return pointer_to_unary_function<_Arg,_Result>(__f);}
 
 template <class _Arg1, class _Arg2, class _Result>
-class _LIBCPP_TYPE_VIS pointer_to_binary_function
+class _LIBCPP_TYPE_VIS_ONLY pointer_to_binary_function
     : public binary_function<_Arg1, _Arg2, _Result>
 {
     _Result (*__f_)(_Arg1, _Arg2);
@@ -720,7 +1062,7 @@
     {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}
 
 template<class _Sp, class _Tp>
-class _LIBCPP_TYPE_VIS mem_fun_t : public unary_function<_Tp*, _Sp>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun_t : public unary_function<_Tp*, _Sp>
 {
     _Sp (_Tp::*__p_)();
 public:
@@ -731,7 +1073,7 @@
 };
 
 template<class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TYPE_VIS mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp>
 {
     _Sp (_Tp::*__p_)(_Ap);
 public:
@@ -754,7 +1096,7 @@
     {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
 
 template<class _Sp, class _Tp>
-class _LIBCPP_TYPE_VIS mem_fun_ref_t : public unary_function<_Tp, _Sp>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun_ref_t : public unary_function<_Tp, _Sp>
 {
     _Sp (_Tp::*__p_)();
 public:
@@ -765,7 +1107,7 @@
 };
 
 template<class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TYPE_VIS mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp>
 {
     _Sp (_Tp::*__p_)(_Ap);
 public:
@@ -788,7 +1130,7 @@
     {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
 
 template <class _Sp, class _Tp>
-class _LIBCPP_TYPE_VIS const_mem_fun_t : public unary_function<const _Tp*, _Sp>
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun_t : public unary_function<const _Tp*, _Sp>
 {
     _Sp (_Tp::*__p_)() const;
 public:
@@ -799,7 +1141,7 @@
 };
 
 template <class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TYPE_VIS const_mem_fun1_t : public binary_function<const _Tp*, _Ap, _Sp>
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_t : public binary_function<const _Tp*, _Ap, _Sp>
 {
     _Sp (_Tp::*__p_)(_Ap) const;
 public:
@@ -822,7 +1164,7 @@
     {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
 
 template <class _Sp, class _Tp>
-class _LIBCPP_TYPE_VIS const_mem_fun_ref_t : public unary_function<_Tp, _Sp>
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun_ref_t : public unary_function<_Tp, _Sp>
 {
     _Sp (_Tp::*__p_)() const;
 public:
@@ -833,7 +1175,7 @@
 };
 
 template <class _Sp, class _Tp, class _Ap>
-class _LIBCPP_TYPE_VIS const_mem_fun1_ref_t
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_ref_t
     : public binary_function<_Tp, _Ap, _Sp>
 {
     _Sp (_Tp::*__p_)(_Ap) const;
@@ -893,38 +1235,6 @@
     return __mem_fn<_Rp _Tp::*>(__pm);
 }
 
-template<class _Rp, class _Tp, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_Args...)>
-mem_fn(_Rp (_Tp::* __pm)(_Args...))
-{
-    return __mem_fn<_Rp (_Tp::*)(_Args...)>(__pm);
-}
-
-template<class _Rp, class _Tp, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_Args...) const>
-mem_fn(_Rp (_Tp::* __pm)(_Args...) const)
-{
-    return __mem_fn<_Rp (_Tp::*)(_Args...) const>(__pm);
-}
-
-template<class _Rp, class _Tp, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_Args...) volatile>
-mem_fn(_Rp (_Tp::* __pm)(_Args...) volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_Args...) volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_Args...) const volatile>
-mem_fn(_Rp (_Tp::* __pm)(_Args...) const volatile)
-{
-    return __mem_fn<_Rp (_Tp::*)(_Args...) const volatile>(__pm);
-}
-
 // bad_function_call
 
 class _LIBCPP_EXCEPTION_ABI bad_function_call
@@ -932,7 +1242,7 @@
 {
 };
 
-template<class _Fp> class _LIBCPP_TYPE_VIS function; // undefined
+template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined
 
 namespace __function
 {
@@ -1083,7 +1393,7 @@
 }  // __function
 
 template<class _Rp, class ..._ArgTypes>
-class _LIBCPP_TYPE_VIS function<_Rp(_ArgTypes...)>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_ArgTypes...)>
     : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
       public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
 {
@@ -1139,8 +1449,11 @@
     function(const function&);
     function(function&&) _NOEXCEPT;
     template<class _Fp>
-      function(_Fp,
-               typename enable_if<__callable<_Fp>::value>::type* = 0);
+      function(_Fp, typename enable_if
+                                     <
+                                        __callable<_Fp>::value &&
+                                        !is_same<_Fp, function>::value
+                                      >::type* = 0);
 
     template<class _Alloc>
       _LIBCPP_INLINE_VISIBILITY
@@ -1162,7 +1475,8 @@
     template<class _Fp>
       typename enable_if
       <
-        __callable<typename decay<_Fp>::type>::value,
+        __callable<typename decay<_Fp>::type>::value &&
+        !is_same<typename remove_reference<_Fp>::type, function>::value,
         function&
       >::type
       operator=(_Fp&&);
@@ -1266,7 +1580,11 @@
 template<class _Rp, class ..._ArgTypes>
 template <class _Fp>
 function<_Rp(_ArgTypes...)>::function(_Fp __f,
-                                     typename enable_if<__callable<_Fp>::value>::type*)
+                                     typename enable_if
+                                     <
+                                        __callable<_Fp>::value &&
+                                        !is_same<_Fp, function>::value
+                                     >::type*)
     : __f_(0)
 {
     if (__not_null(__f))
@@ -1370,7 +1688,8 @@
 template <class _Fp>
 typename enable_if
 <
-    function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value,
+    function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value &&
+    !is_same<typename remove_reference<_Fp>::type, function<_Rp(_ArgTypes...)>>::value,
     function<_Rp(_ArgTypes...)>&
 >::type
 function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
@@ -1496,11 +1815,11 @@
 {return __x.swap(__y);}
 
 template<class _Tp> struct __is_bind_expression : public false_type {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS is_bind_expression
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
     : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
 
 template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS is_placeholder
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder
     : public __is_placeholder<typename remove_cv<_Tp>::type> {};
 
 namespace placeholders
@@ -1508,16 +1827,16 @@
 
 template <int _Np> struct __ph {};
 
-extern __ph<1>   _1;
-extern __ph<2>   _2;
-extern __ph<3>   _3;
-extern __ph<4>   _4;
-extern __ph<5>   _5;
-extern __ph<6>   _6;
-extern __ph<7>   _7;
-extern __ph<8>   _8;
-extern __ph<9>   _9;
-extern __ph<10> _10;
+_LIBCPP_FUNC_VIS extern __ph<1>   _1;
+_LIBCPP_FUNC_VIS extern __ph<2>   _2;
+_LIBCPP_FUNC_VIS extern __ph<3>   _3;
+_LIBCPP_FUNC_VIS extern __ph<4>   _4;
+_LIBCPP_FUNC_VIS extern __ph<5>   _5;
+_LIBCPP_FUNC_VIS extern __ph<6>   _6;
+_LIBCPP_FUNC_VIS extern __ph<7>   _7;
+_LIBCPP_FUNC_VIS extern __ph<8>   _8;
+_LIBCPP_FUNC_VIS extern __ph<9>   _9;
+_LIBCPP_FUNC_VIS extern __ph<10> _10;
 
 }  // placeholders
 
@@ -1594,12 +1913,24 @@
           class _TupleUj>
 struct ____mu_return;
 
+template <bool _Invokable, class _Ti, class ..._Uj>
+struct ____mu_return_invokable  // false
+{
+    typedef __nat type;
+};
+
 template <class _Ti, class ..._Uj>
-struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> >
+struct ____mu_return_invokable<true, _Ti, _Uj...>
 {
     typedef typename __invoke_of<_Ti&, _Uj...>::type type;
 };
 
+template <class _Ti, class ..._Uj>
+struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> >
+    : public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
+{
+};
+
 template <class _Ti, class _TupleUj>
 struct ____mu_return<_Ti, false, false, true, _TupleUj>
 {
@@ -1737,7 +2068,9 @@
     template <class _Gp, class ..._BA,
               class = typename enable_if
                                <
-                                  is_constructible<_Fd, _Gp>::value
+                                  is_constructible<_Fd, _Gp>::value &&
+                                  !is_same<typename remove_reference<_Gp>::type,
+                                           __bind>::value
                                >::type>
       _LIBCPP_INLINE_VISIBILITY
       explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
@@ -1802,7 +2135,13 @@
 
 #endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
 
-    template <class _Gp, class ..._BA>
+    template <class _Gp, class ..._BA,
+              class = typename enable_if
+                               <
+                                  is_constructible<_Fd, _Gp>::value &&
+                                  !is_same<typename remove_reference<_Gp>::type,
+                                           __bind_r>::value
+                               >::type>
       _LIBCPP_INLINE_VISIBILITY
       explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
         : base(_VSTD::forward<_Gp>(__f),
@@ -1859,7 +2198,7 @@
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<bool>
+struct _LIBCPP_TYPE_VIS_ONLY hash<bool>
     : public unary_function<bool, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1867,7 +2206,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<char>
+struct _LIBCPP_TYPE_VIS_ONLY hash<char>
     : public unary_function<char, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1875,7 +2214,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<signed char>
+struct _LIBCPP_TYPE_VIS_ONLY hash<signed char>
     : public unary_function<signed char, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1883,7 +2222,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<unsigned char>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned char>
     : public unary_function<unsigned char, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1893,7 +2232,7 @@
 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<char16_t>
+struct _LIBCPP_TYPE_VIS_ONLY hash<char16_t>
     : public unary_function<char16_t, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1901,7 +2240,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<char32_t>
+struct _LIBCPP_TYPE_VIS_ONLY hash<char32_t>
     : public unary_function<char32_t, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1911,7 +2250,7 @@
 #endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<wchar_t>
+struct _LIBCPP_TYPE_VIS_ONLY hash<wchar_t>
     : public unary_function<wchar_t, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1919,7 +2258,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<short>
+struct _LIBCPP_TYPE_VIS_ONLY hash<short>
     : public unary_function<short, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1927,7 +2266,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<unsigned short>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned short>
     : public unary_function<unsigned short, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1935,7 +2274,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<int>
+struct _LIBCPP_TYPE_VIS_ONLY hash<int>
     : public unary_function<int, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1943,7 +2282,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<unsigned int>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned int>
     : public unary_function<unsigned int, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1951,7 +2290,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<long>
+struct _LIBCPP_TYPE_VIS_ONLY hash<long>
     : public unary_function<long, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1959,7 +2298,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<unsigned long>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long>
     : public unary_function<unsigned long, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1967,19 +2306,19 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<long long>
+struct _LIBCPP_TYPE_VIS_ONLY hash<long long>
     : public __scalar_hash<long long>
 {
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<unsigned long long>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long long>
     : public __scalar_hash<unsigned long long>
 {
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<float>
+struct _LIBCPP_TYPE_VIS_ONLY hash<float>
     : public __scalar_hash<float>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -1993,7 +2332,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<double>
+struct _LIBCPP_TYPE_VIS_ONLY hash<double>
     : public __scalar_hash<double>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -2007,7 +2346,7 @@
 };
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<long double>
+struct _LIBCPP_TYPE_VIS_ONLY hash<long double>
     : public __scalar_hash<long double>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -2056,6 +2395,22 @@
     }
 };
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY hash
+    : public unary_function<_Tp, size_t>
+{
+    static_assert(is_enum<_Tp>::value, "This hash only works for enumeration types");
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        typedef typename underlying_type<_Tp>::type type;
+        return hash<type>{}(static_cast<type>(__v));
+    }
+};
+#endif
+
 // struct hash<T*> in <memory>
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/include/future b/include/future
index 3d7bb6c..73d5456 100644
--- a/include/future
+++ b/include/future
@@ -19,10 +19,10 @@
 
 enum class future_errc
 {
-    broken_promise,
-    future_already_retrieved,
+    future_already_retrieved = 1,
     promise_already_satisfied,
-    no_state
+    no_state,
+    broken_promise
 };
 
 enum class launch
@@ -309,11 +309,11 @@
 };
 
 template <class F, class... Args>
-  future<typename result_of<F(Args...)>::type>
+  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
   async(F&& f, Args&&... args);
 
 template <class F, class... Args>
-  future<typename result_of<F(Args...)>::type>
+  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
   async(launch policy, F&& f, Args&&... args);
 
 template <class> class packaged_task; // undefined
@@ -379,19 +379,19 @@
 //enum class future_errc
 _LIBCPP_DECLARE_STRONG_ENUM(future_errc)
 {
-    broken_promise,
-    future_already_retrieved,
+    future_already_retrieved = 1,
     promise_already_satisfied,
-    no_state
+    no_state,
+    broken_promise
 };
 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
 
 template <>
-struct _LIBCPP_TYPE_VIS is_error_code_enum<future_errc> : public true_type {};
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
 
 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
 template <>
-struct _LIBCPP_TYPE_VIS is_error_code_enum<future_errc::__lx> : public true_type { };
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
 #endif
 
 //enum class launch
@@ -403,6 +403,72 @@
 };
 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
 
+#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
+
+#ifdef _LIBCXX_UNDERLYING_TYPE
+typedef underlying_type<launch>::type __launch_underlying_type;
+#else
+typedef int __launch_underlying_type;
+#endif
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator&(launch __x, launch __y)
+{
+    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
+                               static_cast<__launch_underlying_type>(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator|(launch __x, launch __y)
+{
+    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
+                               static_cast<__launch_underlying_type>(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator^(launch __x, launch __y)
+{
+    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
+                               static_cast<__launch_underlying_type>(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator~(launch __x)
+{
+    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+launch&
+operator&=(launch& __x, launch __y)
+{
+    __x = __x & __y; return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+launch&
+operator|=(launch& __x, launch __y)
+{
+    __x = __x | __y; return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+launch&
+operator^=(launch& __x, launch __y)
+{
+    __x = __x ^ __y; return __x;
+}
+
+#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
+
 //enum class future_status
 _LIBCPP_DECLARE_STRONG_ENUM(future_status)
 {
@@ -442,7 +508,7 @@
     virtual ~future_error() _NOEXCEPT;
 };
 
-class __assoc_sub_state
+class _LIBCPP_TYPE_VIS __assoc_sub_state
     : public __shared_count
 {
 protected:
@@ -476,14 +542,14 @@
         __state_ |= __future_attached;
     }
     _LIBCPP_INLINE_VISIBILITY
-    bool __has_future_attached() const {return __state_ & __future_attached;}
+    bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
 
     _LIBCPP_INLINE_VISIBILITY
     void __set_deferred() {__state_ |= deferred;}
 
     void __make_ready();
     _LIBCPP_INLINE_VISIBILITY
-    bool __is_ready() const {return __state_ & ready;}
+    bool __is_ready() const {return (__state_ & ready) != 0;}
 
     void set_value();
     void set_value_at_thread_exit();
@@ -661,7 +727,7 @@
     if (this->__has_value())
         throw future_error(make_error_code(future_errc::promise_already_satisfied));
 #endif
-    __value_ = &__arg;
+    __value_ = _VSTD::addressof(__arg);
     this->__state_ |= base::__constructed | base::ready;
     __lk.unlock();
     __cv_.notify_all();
@@ -676,7 +742,7 @@
     if (this->__has_value())
         throw future_error(make_error_code(future_errc::promise_already_satisfied));
 #endif
-    __value_ = &__arg;
+    __value_ = _VSTD::addressof(__arg);
     this->__state_ |= base::__constructed;
     __thread_local_data()->__make_ready_at_thread_exit(this);
     __lk.unlock();
@@ -712,7 +778,7 @@
 __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
 {
     if (this->__state_ & base::__constructed)
-        reinterpret_cast<_Rp*>(&this->__value_)->~_Rp();
+        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
     typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
     this->~__assoc_state_alloc();
     __a.deallocate(this, 1);
@@ -966,12 +1032,12 @@
     base::__on_zero_shared();
 }
 
-template <class _Rp> class _LIBCPP_TYPE_VIS promise;
-template <class _Rp> class _LIBCPP_TYPE_VIS shared_future;
+template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
+template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
 
 // future
 
-template <class _Rp> class _LIBCPP_TYPE_VIS future;
+template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
 
 template <class _Rp, class _Fp>
 future<_Rp>
@@ -990,7 +1056,7 @@
 #endif
 
 template <class _Rp>
-class _LIBCPP_TYPE_VIS future
+class _LIBCPP_TYPE_VIS_ONLY future
 {
     __assoc_state<_Rp>* __state_;
 
@@ -1094,7 +1160,7 @@
 }
 
 template <class _Rp>
-class _LIBCPP_TYPE_VIS future<_Rp&>
+class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
 {
     __assoc_state<_Rp&>* __state_;
 
@@ -1275,7 +1341,7 @@
 template <class _Callable> class packaged_task;
 
 template <class _Rp>
-class _LIBCPP_TYPE_VIS promise
+class _LIBCPP_TYPE_VIS_ONLY promise
 {
     __assoc_state<_Rp>* __state_;
 
@@ -1453,7 +1519,7 @@
 // promise<R&>
 
 template <class _Rp>
-class _LIBCPP_TYPE_VIS promise<_Rp&>
+class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
 {
     __assoc_state<_Rp&>* __state_;
 
@@ -1670,7 +1736,7 @@
 }
 
 template <class _Rp, class _Alloc>
-    struct _LIBCPP_TYPE_VIS uses_allocator<promise<_Rp>, _Alloc>
+    struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
         : public true_type {};
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -1934,7 +2000,7 @@
 }
 
 template<class _Rp, class ..._ArgTypes>
-class _LIBCPP_TYPE_VIS packaged_task<_Rp(_ArgTypes...)>
+class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
 {
 public:
     typedef _Rp result_type;
@@ -1947,10 +2013,26 @@
     // construction and destruction
     _LIBCPP_INLINE_VISIBILITY
     packaged_task() _NOEXCEPT : __p_(nullptr) {}
-    template <class _Fp>
+    template <class _Fp,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+             >
         _LIBCPP_INLINE_VISIBILITY
         explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
-    template <class _Fp, class _Allocator>
+    template <class _Fp, class _Allocator,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+              >
         _LIBCPP_INLINE_VISIBILITY
         explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
              : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
@@ -2049,7 +2131,7 @@
 }
 
 template<class ..._ArgTypes>
-class _LIBCPP_TYPE_VIS packaged_task<void(_ArgTypes...)>
+class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
 {
 public:
     typedef void result_type;
@@ -2062,10 +2144,26 @@
     // construction and destruction
     _LIBCPP_INLINE_VISIBILITY
     packaged_task() _NOEXCEPT : __p_(nullptr) {}
-    template <class _Fp>
+    template <class _Fp,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+              >
         _LIBCPP_INLINE_VISIBILITY
         explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
-    template <class _Fp, class _Allocator>
+    template <class _Fp, class _Allocator,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+              >    
         _LIBCPP_INLINE_VISIBILITY
         explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
              : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
@@ -2174,7 +2272,7 @@
 }
 
 template <class _Callable, class _Alloc>
-struct _LIBCPP_TYPE_VIS uses_allocator<packaged_task<_Callable>, _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
     : public true_type {};
 
 template <class _Rp, class _Fp>
@@ -2233,20 +2331,32 @@
     }
 };
 
+inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
+{ return (int(__policy) & int(__value)) != 0; }
+
 template <class _Fp, class... _Args>
 future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
 async(launch __policy, _Fp&& __f, _Args&&... __args)
 {
     typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
     typedef typename _BF::_Rp _Rp;
-    future<_Rp> __r;
-    if (int(__policy) & int(launch::async))
-        __r = _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
+
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif
+        if (__does_policy_contain(__policy, launch::async))
+        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
                                                      __decay_copy(_VSTD::forward<_Args>(__args))...));
-    else if (int(__policy) & int(launch::deferred))
-        __r = _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch ( ... ) { if (__policy == launch::async) throw ; }
+#endif
+
+    if (__does_policy_contain(__policy, launch::deferred))
+        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
                                                         __decay_copy(_VSTD::forward<_Args>(__args))...));
-    return __r;
+    return future<_Rp>{};
 }
 
 template <class _Fp, class... _Args>
@@ -2263,7 +2373,7 @@
 // shared_future
 
 template <class _Rp>
-class _LIBCPP_TYPE_VIS shared_future
+class _LIBCPP_TYPE_VIS_ONLY shared_future
 {
     __assoc_state<_Rp>* __state_;
 
@@ -2337,7 +2447,7 @@
 }
 
 template <class _Rp>
-class _LIBCPP_TYPE_VIS shared_future<_Rp&>
+class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
 {
     __assoc_state<_Rp&>* __state_;
 
diff --git a/include/initializer_list b/include/initializer_list
index 181313d..663e49b 100644
--- a/include/initializer_list
+++ b/include/initializer_list
@@ -29,15 +29,15 @@
     typedef const E* iterator;
     typedef const E* const_iterator;
 
-    initializer_list() noexcept;
+    initializer_list() noexcept; // constexpr in C++14
 
-    size_t   size()  const noexcept;
-    const E* begin() const noexcept;
-    const E* end()   const noexcept;
+    size_t   size()  const noexcept; // constexpr in C++14
+    const E* begin() const noexcept; // constexpr in C++14
+    const E* end()   const noexcept; // constexpr in C++14
 };
 
-template<class E> const E* begin(initializer_list<E> il) noexcept;
-template<class E> const E* end(initializer_list<E> il) noexcept;
+template<class E> const E* begin(initializer_list<E> il) noexcept; // constexpr in C++14
+template<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in C++14
 
 }  // std
 
@@ -56,12 +56,13 @@
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template<class _Ep>
-class _LIBCPP_TYPE_VIS initializer_list
+class _LIBCPP_TYPE_VIS_ONLY initializer_list
 {
     const _Ep* __begin_;
     size_t    __size_;
 
     _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
     initializer_list(const _Ep* __b, size_t __s) _NOEXCEPT
         : __begin_(__b),
           __size_(__s)
@@ -75,15 +76,26 @@
     typedef const _Ep* iterator;
     typedef const _Ep* const_iterator;
 
-    _LIBCPP_ALWAYS_INLINE initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}
 
-    _LIBCPP_ALWAYS_INLINE size_t    size()  const _NOEXCEPT {return __size_;}
-    _LIBCPP_ALWAYS_INLINE const _Ep* begin() const _NOEXCEPT {return __begin_;}
-    _LIBCPP_ALWAYS_INLINE const _Ep* end()   const _NOEXCEPT {return __begin_ + __size_;}
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    size_t    size()  const _NOEXCEPT {return __size_;}
+    
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _Ep* begin() const _NOEXCEPT {return __begin_;}
+
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _Ep* end()   const _NOEXCEPT {return __begin_ + __size_;}
 };
 
 template<class _Ep>
 inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Ep*
 begin(initializer_list<_Ep> __il) _NOEXCEPT
 {
@@ -92,6 +104,7 @@
 
 template<class _Ep>
 inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX11
 const _Ep*
 end(initializer_list<_Ep> __il) _NOEXCEPT
 {
diff --git a/include/iomanip b/include/iomanip
index 0c58e19..e334c7d 100644
--- a/include/iomanip
+++ b/include/iomanip
@@ -14,6 +14,8 @@
 /*
     iomanip synopsis
 
+namespace std {
+
 // types T1, T2, ... are unspecified implementation types
 T1 resetiosflags(ios_base::fmtflags mask);
 T2 setiosflags (ios_base::fmtflags mask);
@@ -26,6 +28,17 @@
 template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
 template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);
 
+template <class charT>
+  T11 quoted(const charT* s, charT delim=charT('"'), charT escape=charT('\\')); // C++14
+
+template <class charT, class traits, class Allocator>
+  T12 quoted(const basic_string<charT, traits, Allocator>& s,
+             charT delim=charT('"'), charT escape=charT('\\')); // C++14
+
+template <class charT, class traits, class Allocator>
+  T13 quoted(basic_string<charT, traits, Allocator>& s,
+             charT delim=charT('"'), charT escape=charT('\\')); // C++14
+
 }  // std
 
 */
@@ -499,6 +512,142 @@
     return __iom_t10<_CharT>(__tm, __fmt);
 }
 
+#if _LIBCPP_STD_VER > 11
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+std::basic_ostream<_CharT, _Traits> &
+__quoted_output ( basic_ostream<_CharT, _Traits> &__os, 
+        _ForwardIterator __first, _ForwardIterator __last, _CharT __delim, _CharT __escape )
+{
+    __os << __delim;
+    for ( ; __first != __last; ++ __first )
+    {
+        if (_Traits::eq (*__first, __escape) || _Traits::eq (*__first, __delim))
+            __os << __escape;
+        __os << *__first;
+    }
+    __os << __delim;
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _String>
+basic_istream<_CharT, _Traits> &
+__quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _CharT __delim, _CharT __escape )
+{
+    __string.clear ();
+    _CharT __c;
+    __is >> __c;
+    if ( __is.fail ())
+        return __is;
+
+    if (!_Traits::eq (__c, __delim))    // no delimiter, read the whole string
+    {
+        __is.unget ();
+        __is >> __string;
+        return __is;
+    }
+
+    __save_flags<_CharT, _Traits> sf(__is);
+    noskipws (__is);
+    while (true)
+        {
+        __is >> __c;
+        if ( __is.fail ())
+            break;
+        if (_Traits::eq (__c, __escape))
+        {
+            __is >> __c;
+            if ( __is.fail ())
+                break;
+        }
+        else if (_Traits::eq (__c, __delim))
+            break;
+        __string.push_back ( __c );
+        }
+    return __is;
+}
+
+
+template <class _CharT, class _Iter, class _Traits=char_traits<_CharT>>
+struct __quoted_output_proxy
+{
+    _Iter  __first;
+    _Iter  __last;
+    _CharT  __delim;
+    _CharT  __escape;
+
+    __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
+    : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
+    //  This would be a nice place for a string_ref 
+};
+
+template <class _CharT, class _Traits, class _Iter>
+basic_ostream<_CharT, _Traits>& operator<<(
+         basic_ostream<_CharT, _Traits>& __os, 
+         const __quoted_output_proxy<_CharT, _Iter, _Traits> & __proxy)
+{
+    return __quoted_output (__os, __proxy.__first, __proxy.__last, __proxy.__delim, __proxy.__escape);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+struct __quoted_proxy
+{
+    basic_string<_CharT, _Traits, _Allocator> &__string;
+    _CharT  __delim;
+    _CharT  __escape;
+
+    __quoted_proxy(basic_string<_CharT, _Traits, _Allocator> &__s, _CharT __d, _CharT __e)
+    : __string(__s), __delim(__d), __escape(__e) {}
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>& operator<<(
+        basic_ostream<_CharT, _Traits>& __os, 
+        const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)
+{
+    return __quoted_output (__os, __proxy.__string.cbegin (), __proxy.__string.cend (), __proxy.__delim, __proxy.__escape);
+}
+
+//  extractor for non-const basic_string& proxies
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>& operator>>(
+        basic_istream<_CharT, _Traits>& __is, 
+        const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)
+{
+    return __quoted_input ( __is, __proxy.__string, __proxy.__delim, __proxy.__escape );
+}
+
+
+template <class _CharT>
+_LIBCPP_INLINE_VISIBILITY
+__quoted_output_proxy<_CharT, const _CharT *>
+quoted ( const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape =_CharT('\\'))
+{
+    const _CharT *__end = __s;
+    while ( *__end ) ++__end;
+    return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape );
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
+quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+    return __quoted_output_proxy<_CharT, 
+            typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> 
+                    ( __s.cbegin(), __s.cend (), __delim, __escape );
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+__quoted_proxy<_CharT, _Traits, _Allocator>
+quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+    return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape );
+}
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_IOMANIP
diff --git a/include/ios b/include/ios
index 25bbfc0..d95f18a 100644
--- a/include/ios
+++ b/include/ios
@@ -203,9 +203,9 @@
 };
 
 concept_map ErrorCodeEnum<io_errc> { };
-error_code make_error_code(io_errc e);
-error_condition make_error_condition(io_errc e);
-storage-class-specifier const error_category& iostream_category;
+error_code make_error_code(io_errc e) noexcept; 
+error_condition make_error_condition(io_errc e) noexcept; 
+storage-class-specifier const error_category& iostream_category() noexcept;
 
 }  // std
 
@@ -216,6 +216,10 @@
 #include <__locale>
 #include <system_error>
 
+#if __has_feature(cxx_atomic)
+#include <atomic>     // for __xindex_
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -319,7 +323,7 @@
     _LIBCPP_INLINE_VISIBILITY bool bad() const;
 
     _LIBCPP_INLINE_VISIBILITY iostate exceptions() const;
-    _LIBCPP_INLINE_VISIBILITY void exceptions(iostate __except);
+    _LIBCPP_INLINE_VISIBILITY void exceptions(iostate __iostate);
 
     void __set_badbit_and_consider_rethrow();
     void __set_failbit_and_consider_rethrow();
@@ -363,7 +367,11 @@
     int*            __index_;
     size_t          __event_size_;
     size_t          __event_cap_;
+#if __has_feature(cxx_atomic)
+    static atomic<int> __xindex_;
+#else
     static int      __xindex_;
+#endif
     long*           __iarray_;
     size_t          __iarray_size_;
     size_t          __iarray_cap_;
@@ -380,26 +388,26 @@
 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(io_errc)
 
 template <>
-struct _LIBCPP_TYPE_VIS is_error_code_enum<io_errc> : public true_type { };
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<io_errc> : public true_type { };
 
 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
 template <>
-struct _LIBCPP_TYPE_VIS is_error_code_enum<io_errc::__lx> : public true_type { };
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<io_errc::__lx> : public true_type { };
 #endif
 
 _LIBCPP_FUNC_VIS
-const error_category& iostream_category();
+const error_category& iostream_category() _NOEXCEPT;
 
 inline _LIBCPP_INLINE_VISIBILITY
 error_code
-make_error_code(io_errc __e)
+make_error_code(io_errc __e) _NOEXCEPT
 {
     return error_code(static_cast<int>(__e), iostream_category());
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
 error_condition
-make_error_condition(io_errc __e)
+make_error_condition(io_errc __e) _NOEXCEPT
 {
     return error_condition(static_cast<int>(__e), iostream_category());
 }
@@ -527,21 +535,21 @@
 bool
 ios_base::eof() const
 {
-    return __rdstate_ & eofbit;
+    return (__rdstate_ & eofbit) != 0;
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
 bool
 ios_base::fail() const
 {
-    return __rdstate_ & (failbit | badbit);
+    return (__rdstate_ & (failbit | badbit)) != 0;
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
 bool
 ios_base::bad() const
 {
-    return __rdstate_ & badbit;
+    return (__rdstate_ & badbit) != 0;
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
@@ -553,14 +561,14 @@
 
 inline _LIBCPP_INLINE_VISIBILITY
 void
-ios_base::exceptions(iostate __except)
+ios_base::exceptions(iostate __iostate)
 {
-    __exceptions_ = __except;
+    __exceptions_ = __iostate;
     clear(__rdstate_);
 }
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_ios
+class _LIBCPP_TYPE_VIS_ONLY basic_ios
     : public ios_base
 {
 public:
@@ -585,7 +593,7 @@
     _LIBCPP_ALWAYS_INLINE bool bad() const  {return ios_base::bad();}
 
     _LIBCPP_ALWAYS_INLINE iostate exceptions() const {return ios_base::exceptions();}
-    _LIBCPP_ALWAYS_INLINE void exceptions(iostate __except) {ios_base::exceptions(__except);}
+    _LIBCPP_ALWAYS_INLINE void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);}
 
     // 27.5.4.1 Constructor/destructor:
     _LIBCPP_INLINE_VISIBILITY
@@ -983,6 +991,33 @@
     return __str;
 }
 
+template <class _CharT, class _Traits>
+class __save_flags
+{
+    typedef basic_ios<_CharT, _Traits> __stream_type;
+    typedef typename __stream_type::fmtflags fmtflags;
+
+    __stream_type& __stream_;
+    fmtflags       __fmtflags_;
+    _CharT         __fill_;
+
+    __save_flags(const __save_flags&);
+    __save_flags& operator=(const __save_flags&);
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __save_flags(__stream_type& __stream)
+        : __stream_(__stream),
+          __fmtflags_(__stream.flags()),
+          __fill_(__stream.fill())
+        {}
+    _LIBCPP_INLINE_VISIBILITY
+    ~__save_flags()
+    {
+        __stream_.flags(__fmtflags_);
+        __stream_.fill(__fill_);
+    }
+};
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_IOS
diff --git a/include/iosfwd b/include/iosfwd
index 849d7e5..d24c227 100644
--- a/include/iosfwd
+++ b/include/iosfwd
@@ -97,47 +97,47 @@
 
 class _LIBCPP_TYPE_VIS ios_base;
 
-template<class _CharT>  struct _LIBCPP_TYPE_VIS char_traits;
-template<class _Tp>     class _LIBCPP_TYPE_VIS allocator;
+template<class _CharT>  struct _LIBCPP_TYPE_VIS_ONLY char_traits;
+template<class _Tp>     class _LIBCPP_TYPE_VIS_ONLY allocator;
 
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_ios;
+    class _LIBCPP_TYPE_VIS_ONLY basic_ios;
 
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_streambuf;
+    class _LIBCPP_TYPE_VIS_ONLY basic_streambuf;
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_istream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_istream;
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_ostream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_ostream;
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_iostream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_iostream;
 
 template <class _CharT, class _Traits = char_traits<_CharT>,
           class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_stringbuf;
+    class _LIBCPP_TYPE_VIS_ONLY basic_stringbuf;
 template <class _CharT, class _Traits = char_traits<_CharT>,
           class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_istringstream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_istringstream;
 template <class _CharT, class _Traits = char_traits<_CharT>,
           class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_ostringstream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_ostringstream;
 template <class _CharT, class _Traits = char_traits<_CharT>,
           class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_stringstream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_stringstream;
 
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_filebuf;
+    class _LIBCPP_TYPE_VIS_ONLY basic_filebuf;
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_ifstream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_ifstream;
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_ofstream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_ofstream;
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_fstream;
+    class _LIBCPP_TYPE_VIS_ONLY basic_fstream;
 
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS istreambuf_iterator;
+    class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator;
 template <class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TYPE_VIS ostreambuf_iterator;
+    class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator;
 
 typedef basic_ios<char>              ios;
 typedef basic_ios<wchar_t>           wios;
@@ -172,7 +172,7 @@
 typedef basic_ofstream<wchar_t>      wofstream;
 typedef basic_fstream<wchar_t>       wfstream;
 
-template <class _State>             class _LIBCPP_TYPE_VIS fpos;
+template <class _State>             class _LIBCPP_TYPE_VIS_ONLY fpos;
 typedef fpos<mbstate_t>    streampos;
 typedef fpos<mbstate_t>    wstreampos;
 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
@@ -185,7 +185,7 @@
 template <class _CharT,             // for <stdexcept>
           class _Traits = char_traits<_CharT>,
           class _Allocator = allocator<_CharT> >
-    class _LIBCPP_TYPE_VIS basic_string;
+    class _LIBCPP_TYPE_VIS_ONLY basic_string;
 typedef basic_string<char, char_traits<char>, allocator<char> > string;
 typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
 
diff --git a/include/istream b/include/istream
index 3f629f6..14fa466 100644
--- a/include/istream
+++ b/include/istream
@@ -164,7 +164,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_istream
+class _LIBCPP_TYPE_VIS_ONLY basic_istream
     : virtual public basic_ios<_CharT, _Traits>
 {
     streamsize __gc_;
@@ -194,7 +194,7 @@
 public:
 
     // 27.7.1.1.3 Prefix/suffix:
-    class _LIBCPP_TYPE_VIS sentry;
+    class _LIBCPP_TYPE_VIS_ONLY sentry;
 
     // 27.7.1.2 Formatted input:
     basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&));
@@ -244,7 +244,7 @@
 };
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_istream<_CharT, _Traits>::sentry
+class _LIBCPP_TYPE_VIS_ONLY basic_istream<_CharT, _Traits>::sentry
 {
     bool __ok_;
 
@@ -1144,8 +1144,7 @@
                        break;
                     }
                     ++__gc_;
-                    char_type __ch = traits_type::to_char_type(__i);
-                    if (traits_type::eq(__ch, static_cast<char_type>(__dlm)))
+                    if (traits_type::eq_int_type(__i, __dlm))
                         break;
                 }
             }
@@ -1160,8 +1159,7 @@
                        break;
                     }
                     ++__gc_;
-                    char_type __ch = traits_type::to_char_type(__i);
-                    if (traits_type::eq(__ch, static_cast<char_type>(__dlm)))
+                    if (traits_type::eq_int_type(__i, __dlm))
                         break;
                 }
             }
@@ -1371,8 +1369,10 @@
         this->clear(this->rdstate() & ~ios_base::eofbit);
         sentry __sen(*this, true);
         if (__sen)
+        {
             if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))
                 this->setstate(ios_base::failbit);
+        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }
     catch (...)
@@ -1393,7 +1393,10 @@
 #endif  // _LIBCPP_NO_EXCEPTIONS
         sentry __sen(*this, true);
         if (__sen)
-            this->rdbuf()->pubseekoff(__off, __dir, ios_base::in);
+        {
+            if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))
+                this->setstate(ios_base::failbit);
+        }
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }
     catch (...)
@@ -1453,7 +1456,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_iostream
+class _LIBCPP_TYPE_VIS_ONLY basic_iostream
     : public basic_istream<_CharT, _Traits>,
       public basic_ostream<_CharT, _Traits>
 {
@@ -1704,9 +1707,9 @@
     return __is;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class basic_istream<char>)
-_LIBCPP_EXTERN_TEMPLATE(class basic_istream<wchar_t>)
-_LIBCPP_EXTERN_TEMPLATE(class basic_iostream<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_iostream<char>)
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/iterator b/include/iterator
index 3b078a2..d16aa2a 100644
--- a/include/iterator
+++ b/include/iterator
@@ -309,6 +309,19 @@
 template <class T, size_t N> T* begin(T (&array)[N]);
 template <class T, size_t N> T* end(T (&array)[N]);
 
+template <class C> auto cbegin(const C& c) -> decltype(std::begin(c));        // C++14
+template <class C> auto cend(const C& c) -> decltype(std::end(c));            // C++14
+template <class C> auto rbegin(C& c) -> decltype(c.rbegin());                 // C++14
+template <class C> auto rbegin(const C& c) -> decltype(c.rbegin());           // C++14
+template <class C> auto rend(C& c) -> decltype(c.rend());                     // C++14
+template <class C> auto rend(const C& c) -> decltype(c.rend());               // C++14
+template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14
+template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);   // C++14
+template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);      // C++14
+template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);        // C++14
+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
+
 }  // std
 
 */
@@ -317,12 +330,15 @@
 #include <type_traits>
 #include <cstddef>
 #include <iosfwd>
+#include <initializer_list>
 #ifdef __APPLE__
 #include <Availability.h>
 #endif
 
 #ifdef _LIBCPP_DEBUG
-#include <cassert>
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
 #endif
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -331,11 +347,11 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-struct _LIBCPP_TYPE_VIS input_iterator_tag {};
-struct _LIBCPP_TYPE_VIS output_iterator_tag {};
-struct _LIBCPP_TYPE_VIS forward_iterator_tag       : public input_iterator_tag {};
-struct _LIBCPP_TYPE_VIS bidirectional_iterator_tag : public forward_iterator_tag {};
-struct _LIBCPP_TYPE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY input_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY forward_iterator_tag       : public input_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY bidirectional_iterator_tag : public forward_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {};
 
 template <class _Tp>
 struct __has_iterator_category
@@ -378,11 +394,11 @@
 //    the client expects instead of failing at compile time.
 
 template <class _Iter>
-struct _LIBCPP_TYPE_VIS iterator_traits
+struct _LIBCPP_TYPE_VIS_ONLY iterator_traits
     : __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {};
 
 template<class _Tp>
-struct _LIBCPP_TYPE_VIS iterator_traits<_Tp*>
+struct _LIBCPP_TYPE_VIS_ONLY iterator_traits<_Tp*>
 {
     typedef ptrdiff_t difference_type;
     typedef typename remove_const<_Tp>::type value_type;
@@ -413,7 +429,7 @@
 
 template<class _Category, class _Tp, class _Distance = ptrdiff_t,
          class _Pointer = _Tp*, class _Reference = _Tp&>
-struct _LIBCPP_TYPE_VIS iterator
+struct _LIBCPP_TYPE_VIS_ONLY iterator
 {
     typedef _Tp        value_type;
     typedef _Distance  difference_type;
@@ -510,7 +526,7 @@
 }
 
 template <class _Iter>
-class _LIBCPP_TYPE_VIS reverse_iterator
+class _LIBCPP_TYPE_VIS_ONLY reverse_iterator
     : public iterator<typename iterator_traits<_Iter>::iterator_category,
                       typename iterator_traits<_Iter>::value_type,
                       typename iterator_traits<_Iter>::difference_type,
@@ -617,7 +633,7 @@
 }
 
 template <class _Container>
-class _LIBCPP_TYPE_VIS back_insert_iterator
+class _LIBCPP_TYPE_VIS_ONLY back_insert_iterator
     : public iterator<output_iterator_tag,
                       void,
                       void,
@@ -650,7 +666,7 @@
 }
 
 template <class _Container>
-class _LIBCPP_TYPE_VIS front_insert_iterator
+class _LIBCPP_TYPE_VIS_ONLY front_insert_iterator
     : public iterator<output_iterator_tag,
                       void,
                       void,
@@ -683,7 +699,7 @@
 }
 
 template <class _Container>
-class _LIBCPP_TYPE_VIS insert_iterator
+class _LIBCPP_TYPE_VIS_ONLY insert_iterator
     : public iterator<output_iterator_tag,
                       void,
                       void,
@@ -719,7 +735,7 @@
 
 template <class _Tp, class _CharT = char,
           class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
-class _LIBCPP_TYPE_VIS istream_iterator
+class _LIBCPP_TYPE_VIS_ONLY istream_iterator
     : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
 {
 public:
@@ -758,7 +774,7 @@
 };
 
 template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
-class _LIBCPP_TYPE_VIS ostream_iterator
+class _LIBCPP_TYPE_VIS_ONLY ostream_iterator
     : public iterator<output_iterator_tag, void, void, void, void>
 {
 public:
@@ -787,7 +803,7 @@
 };
 
 template<class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS istreambuf_iterator
+class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator
     : public iterator<input_iterator_tag, _CharT,
                       typename _Traits::off_type, _CharT*,
                       _CharT>
@@ -858,7 +874,7 @@
                 {return !__a.equal(__b);}
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS ostreambuf_iterator
+class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator
     : public iterator<output_iterator_tag, void, void, void, void>
 {
 public:
@@ -899,7 +915,7 @@
 };
 
 template <class _Iter>
-class _LIBCPP_TYPE_VIS move_iterator
+class _LIBCPP_TYPE_VIS_ONLY move_iterator
 {
 private:
     _Iter __i;
@@ -1014,7 +1030,7 @@
 template <class _Iter>
 inline _LIBCPP_INLINE_VISIBILITY
 move_iterator<_Iter>
-make_move_iterator(const _Iter& __i)
+make_move_iterator(_Iter __i)
 {
     return move_iterator<_Iter>(__i);
 }
@@ -1091,6 +1107,9 @@
     iterator_type __i;
 public:
     _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+                : __i{}
+#endif
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __get_db()->__insert_i(this);
@@ -1135,7 +1154,14 @@
 #endif
         return *__i;
     }
-    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const _NOEXCEPT {return &(operator*());}
+    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable iterator");
+#endif
+        return (pointer)&reinterpret_cast<const volatile char&>(*__i);
+    }
     _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1185,12 +1211,13 @@
     _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;}
 
 private:
-    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
 #if _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
     {
         __get_db()->__insert_ic(this, __p);
     }
+#else
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
 #endif
 
     template <class _Up> friend class __wrap_iter;
@@ -1257,10 +1284,6 @@
 bool
 operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-    _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y),
-                   "Attempted to compare incomparable iterators");
-#endif
     return __x.base() == __y.base();
 }
 
@@ -1270,7 +1293,7 @@
 operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
-    _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y),
+    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
                    "Attempted to compare incomparable iterators");
 #endif
     return __x.base() < __y.base();
@@ -1346,7 +1369,7 @@
 operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
-    _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y),
+    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
                    "Attempted to subtract incompatible iterators");
 #endif
     return __x.base() - __y.base();
@@ -1362,422 +1385,6 @@
     return __x;
 }
 
-#ifdef _LIBCPP_DEBUG
-
-// __debug_iter
-
-template <class _Container, class _Iter> class __debug_iter;
-
-template <class _Container, class _Iter1, class _Iter2>
-_LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const __debug_iter<_Container, _Iter1>&, const __debug_iter<_Container, _Iter2>&);
-
-template <class _Container, class _Iter1, class _Iter2>
-_LIBCPP_INLINE_VISIBILITY
-bool
-operator<(const __debug_iter<_Container, _Iter1>&, const __debug_iter<_Container, _Iter2>&);
-
-template <class _Container, class _Iter1, class _Iter2>
-_LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const __debug_iter<_Container, _Iter1>&, const __debug_iter<_Container, _Iter2>&);
-
-template <class _Container, class _Iter1, class _Iter2>
-_LIBCPP_INLINE_VISIBILITY
-bool
-operator>(const __debug_iter<_Container, _Iter1>&, const __debug_iter<_Container, _Iter2>&);
-
-template <class _Container, class _Iter1, class _Iter2>
-_LIBCPP_INLINE_VISIBILITY
-bool
-operator>=(const __debug_iter<_Container, _Iter1>&, const __debug_iter<_Container, _Iter2>&);
-
-template <class _Container, class _Iter1, class _Iter2>
-_LIBCPP_INLINE_VISIBILITY
-bool
-operator<=(const __debug_iter<_Container, _Iter1>&, const __debug_iter<_Container, _Iter2>&);
-
-template <class _Container, class _Iter1, class _Iter2>
-_LIBCPP_INLINE_VISIBILITY
-typename __debug_iter<_Container, _Iter1>::difference_type
-operator-(const __debug_iter<_Container, _Iter1>&, const __debug_iter<_Container, _Iter2>&);
-
-template <class _Container, class _Iter>
-_LIBCPP_INLINE_VISIBILITY
-__debug_iter<_Container, _Iter>
-operator+(typename __debug_iter<_Container, _Iter>::difference_type, const __debug_iter<_Container, _Iter>&);
-
-template <class _Container, class _Iter>
-class __debug_iter
-{
-public:
-    typedef _Iter                                                      iterator_type;
-    typedef _Container                                                 __container_type;
-    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
-    typedef typename iterator_traits<iterator_type>::value_type        value_type;
-    typedef typename iterator_traits<iterator_type>::difference_type   difference_type;
-    typedef typename iterator_traits<iterator_type>::pointer           pointer;
-    typedef typename iterator_traits<iterator_type>::reference         reference;
-private:
-    iterator_type __i;
-    __debug_iter* __next;
-    __container_type* __cont;
-
-public:
-    _LIBCPP_INLINE_VISIBILITY __debug_iter() : __next(0), __cont(0) {}
-    _LIBCPP_INLINE_VISIBILITY __debug_iter(const __debug_iter& __x)
-        : __i(__x.base()), __next(0), __cont(0) {__set_owner(__x.__cont);}
-    __debug_iter& operator=(const __debug_iter& __x);
-    template <class _Up> _LIBCPP_INLINE_VISIBILITY __debug_iter(const __debug_iter<_Container, _Up>& __u,
-        typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0)
-        : __i(__u.base()), __next(0), __cont(0) {__set_owner(__u.__cont);}
-    _LIBCPP_INLINE_VISIBILITY ~__debug_iter() {__remove_owner();}
-    _LIBCPP_INLINE_VISIBILITY reference operator*() const {assert(__is_deref()); return *__i;}
-    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const {return &(operator*());}
-    _LIBCPP_INLINE_VISIBILITY __debug_iter& operator++() {assert(__can_increment()); ++__i; return *this;}
-    _LIBCPP_INLINE_VISIBILITY __debug_iter  operator++(int)
-        {__debug_iter __tmp(*this); operator++(); return __tmp;}
-    _LIBCPP_INLINE_VISIBILITY __debug_iter& operator--() {assert(__can_decrement()); --__i; return *this;}
-    _LIBCPP_INLINE_VISIBILITY __debug_iter  operator--(int)
-        {__debug_iter __tmp(*this); operator--(); return __tmp;}
-    _LIBCPP_INLINE_VISIBILITY __debug_iter  operator+ (difference_type __n) const
-        {__debug_iter __t(*this); __t += __n; return __t;}
-    __debug_iter& operator+=(difference_type __n);
-    _LIBCPP_INLINE_VISIBILITY __debug_iter  operator- (difference_type __n) const
-        {__debug_iter __t(*this); __t -= __n; return __t;}
-    _LIBCPP_INLINE_VISIBILITY __debug_iter& operator-=(difference_type __n)
-        {*this += -__n; return *this;}
-    _LIBCPP_INLINE_VISIBILITY reference        operator[](difference_type __n) const
-        {return *(*this + __n);}
-
-private:
-    _LIBCPP_INLINE_VISIBILITY __debug_iter(const __container_type* __c, iterator_type __x)
-        : __i(__x), __next(0), __cont(0) {__set_owner(__c);}
-    _LIBCPP_INLINE_VISIBILITY iterator_type base() const {return __i;}
-
-    void __set_owner(const __container_type* __c);
-    void __remove_owner();
-    static void __remove_all(__container_type* __c);
-    static void swap(__container_type* __x, __container_type* __y);
-
-    _LIBCPP_INLINE_VISIBILITY bool __is_deref() const
-        {return __is_deref(__is_random_access_iterator<iterator_type>());}
-    bool __is_deref(false_type) const;
-    bool __is_deref(true_type) const;
-    _LIBCPP_INLINE_VISIBILITY bool __can_decrement() const
-        {return __can_decrement(integral_constant<int, is_pointer<iterator_type>::value ? 2:
-                                                       __is_random_access_iterator<iterator_type>::value ? 1 : 0>());}
-    bool __can_decrement(integral_constant<int, 0>) const;
-    bool __can_decrement(integral_constant<int, 1>) const;
-    bool __can_decrement(integral_constant<int, 2>) const;
-    _LIBCPP_INLINE_VISIBILITY bool __can_increment() const
-        {return __can_increment(integral_constant<int, is_pointer<iterator_type>::value ? 2:
-                                                       __is_random_access_iterator<iterator_type>::value ? 1 : 0>());}
-    bool __can_increment(integral_constant<int, 0>) const;
-    bool __can_increment(integral_constant<int, 1>) const;
-    bool __can_increment(integral_constant<int, 2>) const;
-
-    _LIBCPP_INLINE_VISIBILITY bool __can_add(difference_type __n) const
-        {return __can_add(__n, is_pointer<iterator_type>());}
-    bool __can_add(difference_type __n, false_type) const;
-    bool __can_add(difference_type __n, true_type) const;
-
-    template <class _Cp, class _Up> friend class __debug_iter;
-    friend class _Container::__self;
-
-    template <class _Cp, class _Iter1, class _Iter2>
-    friend
-    bool
-    operator==(const __debug_iter<_Cp, _Iter1>&, const __debug_iter<_Cp, _Iter2>&);
-
-    template <class _Cp, class _Iter1, class _Iter2>
-    friend
-    bool
-    operator<(const __debug_iter<_Cp, _Iter1>&, const __debug_iter<_Cp, _Iter2>&);
-
-    template <class _Cp, class _Iter1, class _Iter2>
-    friend
-    bool
-    operator!=(const __debug_iter<_Cp, _Iter1>&, const __debug_iter<_Cp, _Iter2>&);
-
-    template <class _Cp, class _Iter1, class _Iter2>
-    friend
-    bool
-    operator>(const __debug_iter<_Cp, _Iter1>&, const __debug_iter<_Cp, _Iter2>&);
-
-    template <class _Cp, class _Iter1, class _Iter2>
-    friend
-    bool
-    operator>=(const __debug_iter<_Cp, _Iter1>&, const __debug_iter<_Cp, _Iter2>&);
-
-    template <class _Cp, class _Iter1, class _Iter2>
-    friend
-    bool
-    operator<=(const __debug_iter<_Cp, _Iter1>&, const __debug_iter<_Cp, _Iter2>&);
-
-    template <class _Cp, class _Iter1, class _Iter2>
-    friend
-    typename __debug_iter<_Cp, _Iter1>::difference_type
-    operator-(const __debug_iter<_Cp, _Iter1>&, const __debug_iter<_Cp, _Iter2>&);
-
-    template <class _Cp, class _Iter1>
-    friend
-    __debug_iter<_Cp, _Iter1>
-    operator+(typename __debug_iter<_Cp, _Iter1>::difference_type, const __debug_iter<_Cp, _Iter1>&);
-};
-
-template <class _Container, class _Iter>
-__debug_iter<_Container, _Iter>&
-__debug_iter<_Container, _Iter>::operator=(const __debug_iter& __x)
-{
-    if (this != &__x)
-    {
-        __remove_owner();
-        __i = __x.__i;
-        __set_owner(__x.__cont);
-    }
-    return *this;
-}
-
-template <class _Container, class _Iter>
-void
-__debug_iter<_Container, _Iter>::__set_owner(const __container_type* __c)
-{
-    __cont = const_cast<__container_type*>(__c);
-    __debug_iter*& __head = __cont->__get_iterator_list(this);
-    __next = __head;
-    __head = this;
-}
-
-template <class _Container, class _Iter>
-void
-__debug_iter<_Container, _Iter>::__remove_owner()
-{
-    if (__cont)
-    {
-        __debug_iter*& __head = __cont->__get_iterator_list(this);
-        if (__head == this)
-            __head = __next;
-        else
-        {
-            __debug_iter* __prev = __head;
-            for (__debug_iter* __p = __head->__next; __p != this; __p = __p->__next)
-                __prev = __p;
-            __prev->__next = __next;
-        }
-        __cont = 0;
-    }
-}
-
-template <class _Container, class _Iter>
-void
-__debug_iter<_Container, _Iter>::__remove_all(__container_type* __c)
-{
-    __debug_iter*& __head = __c->__get_iterator_list((__debug_iter*)0);
-    __debug_iter* __p = __head;
-    __head = 0;
-    while (__p)
-    {
-        __p->__cont = 0;
-        __debug_iter* __n = __p->__next;
-        __p->__next = 0;
-        __p = __n;
-    }
-}
-
-template <class _Container, class _Iter>
-void
-__debug_iter<_Container, _Iter>::swap(__container_type* __x, __container_type* __y)
-{
-    __debug_iter*& __head_x = __x->__get_iterator_list((__debug_iter*)0);
-    __debug_iter*& __head_y = __y->__get_iterator_list((__debug_iter*)0);
-    __debug_iter* __p = __head_x;
-    __head_x = __head_y;
-    __head_y = __p;
-    for (__p = __head_x; __p; __p = __p->__next)
-        __p->__cont = __x;
-    for (__p = __head_y; __p; __p = __p->__next)
-        __p->__cont = __y;
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__is_deref(false_type) const
-{
-    if (__cont == 0)
-        return false;
-    return __i != __cont->end().base();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__is_deref(true_type) const
-{
-    if (__cont == 0)
-        return false;
-    return __i < __cont->end().base();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_decrement(integral_constant<int, 0>) const
-{
-    if (__cont == 0)
-        return false;
-    return __i != __cont->begin().base();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_decrement(integral_constant<int, 1>) const
-{
-    if (__cont == 0)
-        return false;
-    iterator_type __b = __cont->begin().base();
-    return __b < __i && __i <= __b + __cont->size();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_decrement(integral_constant<int, 2>) const
-{
-    if (__cont == 0)
-        return false;
-    iterator_type __b = __cont->begin().base();
-    return __b < __i && __i <= __b + __cont->size();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_increment(integral_constant<int, 0>) const
-{
-    if (__cont == 0)
-        return false;
-    return __i != __cont->end().base();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_increment(integral_constant<int, 1>) const
-{
-    if (__cont == 0)
-        return false;
-    iterator_type __b = __cont->begin().base();
-    return __b <= __i && __i < __b + __cont->size();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_increment(integral_constant<int, 2>) const
-{
-    if (__cont == 0)
-        return false;
-    iterator_type __b = __cont->begin().base();
-    return __b <= __i && __i < __b + __cont->size();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_add(difference_type __n, false_type) const
-{
-    if (__cont == 0)
-        return false;
-    iterator_type __b = __cont->begin().base();
-    iterator_type __j = __i + __n;
-    return __b <= __j && __j <= __b + __cont->size();
-}
-
-template <class _Container, class _Iter>
-bool
-__debug_iter<_Container, _Iter>::__can_add(difference_type __n, true_type) const
-{
-    if (__cont == 0)
-        return false;
-    iterator_type __b = __cont->begin().base();
-    iterator_type __j = __i + __n;
-    return __b <= __j && __j <= __b + __cont->size();
-}
-
-template <class _Container, class _Iter>
-__debug_iter<_Container, _Iter>&
-__debug_iter<_Container, _Iter>::operator+=(difference_type __n)
-{
-    assert(__can_add(__n));
-    __i += __n;
-    return *this;
-}
-
-template <class _Container, class _Iter1, class _Iter2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const __debug_iter<_Container, _Iter1>& __x, const __debug_iter<_Container, _Iter2>& __y)
-{
-    assert(__x.__cont && __x.__cont == __y.__cont);
-    return __x.base() == __y.base();
-}
-
-template <class _Container, class _Iter1, class _Iter2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const __debug_iter<_Container, _Iter1>& __x, const __debug_iter<_Container, _Iter2>& __y)
-{
-    return !(__x == __y);
-}
-
-template <class _Container, class _Iter1, class _Iter2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<(const __debug_iter<_Container, _Iter1>& __x, const __debug_iter<_Container, _Iter2>& __y)
-{
-    assert(__x.__cont && __x.__cont == __y.__cont);
-    return __x.base() < __y.base();
-}
-
-template <class _Container, class _Iter1, class _Iter2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>(const __debug_iter<_Container, _Iter1>& __x, const __debug_iter<_Container, _Iter2>& __y)
-{
-    return __y < __x;
-}
-
-template <class _Container, class _Iter1, class _Iter2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>=(const __debug_iter<_Container, _Iter1>& __x, const __debug_iter<_Container, _Iter2>& __y)
-{
-    return !(__x < __y);
-}
-
-template <class _Container, class _Iter1, class _Iter2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<=(const __debug_iter<_Container, _Iter1>& __x, const __debug_iter<_Container, _Iter2>& __y)
-{
-    return !(__y < __x);
-}
-
-template <class _Container, class _Iter1, class _Iter2>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __debug_iter<_Container, _Iter1>::difference_type
-operator-(const __debug_iter<_Container, _Iter1>& __x, const __debug_iter<_Container, _Iter2>& __y)
-{
-    assert(__x.__cont && __x.__cont == __y.__cont);
-    return __x.base() - __y.base();
-}
-
-template <class _Container, class _Iter>
-inline _LIBCPP_INLINE_VISIBILITY
-__debug_iter<_Container, _Iter>
-operator+(typename __debug_iter<_Container, _Iter>::difference_type __n,
-          const __debug_iter<_Container, _Iter>& __x)
-{
-    return __x + __n;
-}
-
-#endif  // _LIBCPP_DEBUG
-
 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
 
 template <class _Cp>
@@ -1812,6 +1419,67 @@
     return __c.end();
 }
 
+#if _LIBCPP_STD_VER > 11
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto cbegin(const _Cp& __c) -> decltype(begin(__c))
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto cend(const _Cp& __c) -> decltype(end(__c))
+{
+    return __c.end();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rend(_Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rend(const _Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto crbegin(const _Cp& __c) -> decltype(rbegin(__c))
+{
+    return rbegin(__c);
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto crend(const _Cp& __c) -> decltype(rend(__c))
+{
+    return rend(__c);
+}
+
+#endif
+
+
 #else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
 
 template <class _Cp>
@@ -1864,6 +1532,37 @@
     return __array + _Np;
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array + _Np);
+}
+
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array);
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.end());
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.begin());
+}
+
+#endif
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_ITERATOR
diff --git a/include/limits b/include/limits
index ae46a29..1b8a87d 100644
--- a/include/limits
+++ b/include/limits
@@ -111,9 +111,13 @@
 
 #include <__undef_min_max>
 
-#if defined(_MSC_VER)
+#if defined(_LIBCPP_MSVCRT)
 #include "support/win32/limits_win32.h"
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
+
+#if defined(__IBMCPP__)
+#include "support/ibm/limits.h"
+#endif // __IBMCPP__
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -433,7 +437,7 @@
 };
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS numeric_limits
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits
     : private __libcpp_numeric_limits<typename remove_cv<_Tp>::type>
 {
     typedef __libcpp_numeric_limits<typename remove_cv<_Tp>::type> __base;
@@ -526,7 +530,7 @@
     _LIBCPP_CONSTEXPR const float_round_style numeric_limits<_Tp>::round_style;
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS numeric_limits<const _Tp>
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits<const _Tp>
     : private numeric_limits<_Tp>
 {
     typedef numeric_limits<_Tp> __base;
@@ -619,7 +623,7 @@
     _LIBCPP_CONSTEXPR const float_round_style numeric_limits<const _Tp>::round_style;
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS numeric_limits<volatile _Tp>
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits<volatile _Tp>
     : private numeric_limits<_Tp>
 {
     typedef numeric_limits<_Tp> __base;
@@ -712,7 +716,7 @@
     _LIBCPP_CONSTEXPR const float_round_style numeric_limits<volatile _Tp>::round_style;
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS numeric_limits<const volatile _Tp>
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits<const volatile _Tp>
     : private numeric_limits<_Tp>
 {
     typedef numeric_limits<_Tp> __base;
diff --git a/include/list b/include/list
index c6000c9..800a1a3 100644
--- a/include/list
+++ b/include/list
@@ -40,6 +40,7 @@
         noexcept(is_nothrow_default_constructible<allocator_type>::value);
     explicit list(const allocator_type& a);
     explicit list(size_type n);
+    explicit list(size_type n, const allocator_type& a); // C++14
     list(size_type n, const value_type& value);
     list(size_type n, const value_type& value, const allocator_type& a);
     template <class Iter>
@@ -178,6 +179,12 @@
 
 #include <__undef_min_max>
 
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -196,13 +203,20 @@
         rebind<__list_node<_Tp, _VoidPtr> >::other pointer;
 #endif
 
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+        rebind<__list_node_base> __base_pointer;
+#else
+        rebind<__list_node_base>::other __base_pointer;
+#endif
+
     pointer __prev_;
     pointer __next_;
 
     _LIBCPP_INLINE_VISIBILITY
     __list_node_base()
-        : __prev_(static_cast<pointer>(this)),
-          __next_(static_cast<pointer>(this))
+        : __prev_(static_cast<pointer>(pointer_traits<__base_pointer>::pointer_to(*this))),
+          __next_(static_cast<pointer>(pointer_traits<__base_pointer>::pointer_to(*this)))
           {}
 };
 
@@ -213,12 +227,12 @@
     _Tp __value_;
 };
 
-template <class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS list;
+template <class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS_ONLY list;
 template <class _Tp, class _Alloc> class __list_imp;
-template <class _Tp, class _VoidPtr> class _LIBCPP_TYPE_VIS __list_const_iterator;
+template <class _Tp, class _VoidPtr> class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator;
 
 template <class _Tp, class _VoidPtr>
-class _LIBCPP_TYPE_VIS __list_iterator
+class _LIBCPP_TYPE_VIS_ONLY __list_iterator
 {
     typedef typename pointer_traits<_VoidPtr>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
@@ -260,7 +274,7 @@
     typedef typename pointer_traits<pointer>::difference_type difference_type;
 
     _LIBCPP_INLINE_VISIBILITY
-    __list_iterator() _NOEXCEPT
+    __list_iterator() _NOEXCEPT : __ptr_(nullptr)
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __get_db()->__insert_i(this);
@@ -305,7 +319,14 @@
         return __ptr_->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return &(operator*());}
+    pointer operator->() const
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable list::iterator");
+#endif
+        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
+    }
 
     _LIBCPP_INLINE_VISIBILITY
     __list_iterator& operator++()
@@ -336,10 +357,6 @@
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator==(const __list_iterator& __x, const __list_iterator& __y)
     {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-        _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y),
-                       "Attempted to compare non-comparable list::iterator");
-#endif
         return __x.__ptr_ == __y.__ptr_;
     }
     friend _LIBCPP_INLINE_VISIBILITY
@@ -348,13 +365,13 @@
 };
 
 template <class _Tp, class _VoidPtr>
-class _LIBCPP_TYPE_VIS __list_const_iterator
+class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator
 {
     typedef typename pointer_traits<_VoidPtr>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-        rebind<const __list_node<_Tp, _VoidPtr> > __node_pointer;
+        rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;
 #else
-        rebind<const __list_node<_Tp, _VoidPtr> >::other __node_pointer;
+        rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;
 #endif
 
     __node_pointer __ptr_;
@@ -387,7 +404,7 @@
     typedef typename pointer_traits<pointer>::difference_type difference_type;
 
     _LIBCPP_INLINE_VISIBILITY
-    __list_const_iterator() _NOEXCEPT
+    __list_const_iterator() _NOEXCEPT : __ptr_(nullptr)
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __get_db()->__insert_i(this);
@@ -439,7 +456,14 @@
         return __ptr_->__value_;
     }
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return &(operator*());}
+    pointer operator->() const
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable list::iterator");
+#endif
+        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
+    }
 
     _LIBCPP_INLINE_VISIBILITY
     __list_const_iterator& operator++()
@@ -470,10 +494,6 @@
     friend _LIBCPP_INLINE_VISIBILITY
     bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y)
     {
-#if _LIBCPP_DEBUG_LEVEL >= 2
-        _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y),
-                       "Attempted to compare non-comparable list::const_iterator");
-#endif
         return __x.__ptr_ == __y.__ptr_;
     }
     friend _LIBCPP_INLINE_VISIBILITY
@@ -505,11 +525,20 @@
                                                                      __node_allocator;
     typedef allocator_traits<__node_allocator>                       __node_alloc_traits;
     typedef typename __node_alloc_traits::pointer                    __node_pointer;
-    typedef typename __node_alloc_traits::const_pointer              __node_const_pointer;
+    typedef typename __node_alloc_traits::pointer                    __node_const_pointer;
     typedef typename __alloc_traits::pointer                         pointer;
     typedef typename __alloc_traits::const_pointer                   const_pointer;
     typedef typename __alloc_traits::difference_type                 difference_type;
 
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__node_base>
+#else
+                rebind_alloc<__node_base>::other
+#endif
+                                                                     __node_base_allocator;
+    typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer;
+
     __node_base __end_;
     __compressed_pair<size_type, __node_allocator> __size_alloc_;
 
@@ -525,7 +554,7 @@
     const __node_allocator& __node_alloc() const _NOEXCEPT
         {return __size_alloc_.second();}
 
-    static void __unlink_nodes(__node_base& __f, __node_base& __l) _NOEXCEPT;
+    static void __unlink_nodes(__node_pointer __f, __node_pointer __l) _NOEXCEPT;
 
     __list_imp()
         _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value);
@@ -557,18 +586,22 @@
     iterator end() _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        return iterator(static_cast<__node_pointer>(&__end_), this);
+        return iterator(static_cast<__node_pointer>(
+                pointer_traits<__node_base_pointer>::pointer_to(__end_)), this);
 #else
-        return iterator(static_cast<__node_pointer>(&__end_));
+        return iterator(static_cast<__node_pointer>(
+                      pointer_traits<__node_base_pointer>::pointer_to(__end_)));
 #endif
     }
     _LIBCPP_INLINE_VISIBILITY
     const_iterator end() const _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
-        return const_iterator(static_cast<__node_const_pointer>(&__end_), this);
+        return const_iterator(static_cast<__node_const_pointer>(
+        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))), this);
 #else
-        return const_iterator(static_cast<__node_const_pointer>(&__end_));
+        return const_iterator(static_cast<__node_const_pointer>(
+        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))));
 #endif
     }
 
@@ -637,11 +670,11 @@
 template <class _Tp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 void
-__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_base& __f, __node_base& __l)
+__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_pointer __f, __node_pointer __l)
     _NOEXCEPT
 {
-    __f.__prev_->__next_ = __l.__next_;
-    __l.__next_->__prev_ = __f.__prev_;
+    __f->__prev_->__next_ = __l->__next_;
+    __l->__next_->__prev_ = __f->__prev_;
 }
 
 template <class _Tp, class _Alloc>
@@ -676,15 +709,16 @@
     {
         __node_allocator& __na = __node_alloc();
         __node_pointer __f = __end_.__next_;
-        __node_pointer __l = static_cast<__node_pointer>(&__end_);
-        __unlink_nodes(*__f, *__l->__prev_);
+        __node_pointer __l = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_));
+        __unlink_nodes(__f, __l->__prev_);
         __sz() = 0;
         while (__f != __l)
         {
-            __node& __n = *__f;
+            __node_pointer __n = __f;
             __f = __f->__next_;
-            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_));
-            __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1);
+            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+            __node_alloc_traits::deallocate(__na, __n, 1);
         }
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __c_node* __c = __get_db()->__find_c_and_lock(this);
@@ -719,16 +753,20 @@
     swap(__sz(), __c.__sz());
     swap(__end_, __c.__end_);
     if (__sz() == 0)
-        __end_.__next_ = __end_.__prev_ = &static_cast<__node&>(__end_);
+        __end_.__next_ = __end_.__prev_ = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_));
     else
         __end_.__prev_->__next_ = __end_.__next_->__prev_
-                                = &static_cast<__node&>(__end_);
+                                = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_));
     if (__c.__sz() == 0)
         __c.__end_.__next_ = __c.__end_.__prev_
-                           = &static_cast<__node&>(__c.__end_);
+                           = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_));
     else
         __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_
-                                    = &static_cast<__node&>(__c.__end_);
+                                    = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_));
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __libcpp_db* __db = __get_db();
     __c_node* __cn1 = __db->__find_c_and_lock(this);
@@ -740,7 +778,8 @@
     {
         --__p;
         const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == static_cast<__node_pointer>(&__c.__end_))
+        if (__i->__ptr_ == static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
         {
             __cn2->__add(*__p);
             if (--__cn1->end_ != __p)
@@ -753,7 +792,8 @@
     {
         --__p;
         const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == static_cast<__node_pointer>(&__end_))
+        if (__i->__ptr_ == static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_)))
         {
             __cn1->__add(*__p);
             if (--__cn2->end_ != __p)
@@ -767,7 +807,7 @@
 }
 
 template <class _Tp, class _Alloc = allocator<_Tp> >
-class _LIBCPP_TYPE_VIS list
+class _LIBCPP_TYPE_VIS_ONLY list
     : private __list_imp<_Tp, _Alloc>
 {
     typedef __list_imp<_Tp, _Alloc> base;
@@ -775,6 +815,8 @@
     typedef typename base::__node_allocator    __node_allocator;
     typedef typename base::__node_pointer      __node_pointer;
     typedef typename base::__node_alloc_traits __node_alloc_traits;
+    typedef typename base::__node_base         __node_base;
+    typedef typename base::__node_base_pointer __node_base_pointer;
 
 public:
     typedef _Tp                                      value_type;
@@ -801,13 +843,16 @@
 #endif
     }
     _LIBCPP_INLINE_VISIBILITY
-    list(const allocator_type& __a) : base(__a)
+    explicit list(const allocator_type& __a) : base(__a)
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __get_db()->__insert_c(this);
 #endif
     }
-    list(size_type __n);
+    explicit list(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit list(size_type __n, const allocator_type& __a);
+#endif
     list(size_type __n, const value_type& __x);
     list(size_type __n, const value_type& __x, const allocator_type& __a);
     template <class _InpIter>
@@ -1014,7 +1059,7 @@
 #endif  // _LIBCPP_DEBUG_LEVEL >= 2
 
 private:
-    static void __link_nodes(__node& __p, __node& __f, __node& __l);
+    static void __link_nodes(__node_pointer __p, __node_pointer __f, __node_pointer __l);
     iterator __iterator(size_type __n);
     template <class _Comp>
         static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
@@ -1028,12 +1073,12 @@
 template <class _Tp, class _Alloc>
 inline _LIBCPP_INLINE_VISIBILITY
 void
-list<_Tp, _Alloc>::__link_nodes(__node& __p, __node& __f, __node& __l)
+list<_Tp, _Alloc>::__link_nodes(__node_pointer __p, __node_pointer __f, __node_pointer __l)
 {
-    __p.__prev_->__next_ = &__f;
-    __f.__prev_ = __p.__prev_;
-    __p.__prev_ = &__l;
-    __l.__next_ = &__p;
+    __p->__prev_->__next_ = __f;
+    __f->__prev_ = __p->__prev_;
+    __p->__prev_ = __l;
+    __l->__next_ = __p;
 }
 
 template <class _Tp, class _Alloc>
@@ -1059,6 +1104,22 @@
 #endif
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __n > 0; --__n)
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        emplace_back();
+#else
+        push_back(value_type());
+#endif
+}
+#endif
+
 template <class _Tp, class _Alloc>
 list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
 {
@@ -1290,7 +1351,7 @@
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __hold->__prev_ = 0;
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-    __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
+    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
     ++base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
     return iterator(__hold.release(), this);
@@ -1307,9 +1368,9 @@
     _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
         "list::insert(iterator, n, x) called with an iterator not"
         " referring to this list");
-    iterator __r(const_cast<__node_pointer>(__p.__ptr_), this);
+    iterator __r(__p.__ptr_, this);
 #else
-    iterator __r(const_cast<__node_pointer>(__p.__ptr_));
+    iterator __r(__p.__ptr_);
 #endif
     if (__n > 0)
     {
@@ -1359,7 +1420,7 @@
             throw;
         }
 #endif  // _LIBCPP_NO_EXCEPTIONS
-        __link_nodes(const_cast<__node&>(*__p.__ptr_), *__r.__ptr_, *__e.__ptr_);
+        __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
     return __r;
@@ -1375,9 +1436,9 @@
     _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
         "list::insert(iterator, range) called with an iterator not"
         " referring to this list");
-    iterator __r(const_cast<__node_pointer>(__p.__ptr_), this);
+    iterator __r(__p.__ptr_, this);
 #else
-    iterator __r(const_cast<__node_pointer>(__p.__ptr_));
+    iterator __r(__p.__ptr_);
 #endif
     if (__f != __l)
     {
@@ -1427,7 +1488,7 @@
             throw;
         }
 #endif  // _LIBCPP_NO_EXCEPTIONS
-        __link_nodes(const_cast<__node&>(*__p.__ptr_), *__r.__ptr_, *__e.__ptr_);
+        __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
     return __r;
@@ -1441,7 +1502,7 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-    __link_nodes(*base::__end_.__next_, *__hold, *__hold);
+    __link_nodes(base::__end_.__next_, __hold.get(), __hold.get());
     ++base::__sz();
     __hold.release();
 }
@@ -1454,7 +1515,8 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
-    __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
+    __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __hold.get(), __hold.get());
     ++base::__sz();
     __hold.release();
 }
@@ -1469,7 +1531,7 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
-    __link_nodes(*base::__end_.__next_, *__hold, *__hold);
+    __link_nodes(base::__end_.__next_, __hold.get(), __hold.get());
     ++base::__sz();
     __hold.release();
 }
@@ -1482,7 +1544,8 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
-    __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
+    __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __hold.get(), __hold.get());
     ++base::__sz();
     __hold.release();
 }
@@ -1498,7 +1561,7 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
-    __link_nodes(*base::__end_.__next_, *__hold, *__hold);
+    __link_nodes(base::__end_.__next_, __hold.get(), __hold.get());
     ++base::__sz();
     __hold.release();
 }
@@ -1512,7 +1575,8 @@
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
-    __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold);
+    __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __hold.get(), __hold.get());
     ++base::__sz();
     __hold.release();
 }
@@ -1532,7 +1596,7 @@
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __hold->__prev_ = 0;
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
-    __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
+    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
     ++base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
     return iterator(__hold.release(), this);
@@ -1557,7 +1621,7 @@
     unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
     __hold->__prev_ = 0;
     __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
-    __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold);
+    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
     ++base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
     return iterator(__hold.release(), this);
@@ -1574,7 +1638,7 @@
 {
     _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list");
     __node_allocator& __na = base::__node_alloc();
-    __node& __n = *base::__end_.__next_;
+    __node_pointer __n = base::__end_.__next_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1583,7 +1647,7 @@
     {
         --__p;
         iterator* __i = static_cast<iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == &__n)
+        if (__i->__ptr_ == __n)
         {
             (*__p)->__c_ = nullptr;
             if (--__c->end_ != __p)
@@ -1592,17 +1656,17 @@
     }
     __get_db()->unlock();
 #endif
-    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_));
-    __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1);
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+    __node_alloc_traits::deallocate(__na, __n, 1);
 }
 
 template <class _Tp, class _Alloc>
 void
 list<_Tp, _Alloc>::pop_back()
 {
-    _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list");
+    _LIBCPP_ASSERT(!empty(), "list::pop_back() called with empty list");
     __node_allocator& __na = base::__node_alloc();
-    __node& __n = *base::__end_.__prev_;
+    __node_pointer __n = base::__end_.__prev_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1611,7 +1675,7 @@
     {
         --__p;
         iterator* __i = static_cast<iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == &__n)
+        if (__i->__ptr_ == __n)
         {
             (*__p)->__c_ = nullptr;
             if (--__c->end_ != __p)
@@ -1620,8 +1684,8 @@
     }
     __get_db()->unlock();
 #endif
-    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_));
-    __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1);
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+    __node_alloc_traits::deallocate(__na, __n, 1);
 }
 
 template <class _Tp, class _Alloc>
@@ -1636,8 +1700,8 @@
     _LIBCPP_ASSERT(__p != end(),
         "list::erase(iterator) called with a non-dereferenceable iterator");
     __node_allocator& __na = base::__node_alloc();
-    __node& __n = const_cast<__node&>(*__p.__ptr_);
-    __node_pointer __r = __n.__next_;
+    __node_pointer __n = __p.__ptr_;
+    __node_pointer __r = __n->__next_;
     base::__unlink_nodes(__n, __n);
     --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1646,7 +1710,7 @@
     {
         --__p;
         iterator* __i = static_cast<iterator*>((*__p)->__i_);
-        if (__i->__ptr_ == &__n)
+        if (__i->__ptr_ == __n)
         {
             (*__p)->__c_ = nullptr;
             if (--__c->end_ != __p)
@@ -1655,8 +1719,8 @@
     }
     __get_db()->unlock();
 #endif
-    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_));
-    __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1);
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+    __node_alloc_traits::deallocate(__na, __n, 1);
 #if _LIBCPP_DEBUG_LEVEL >= 2
     return iterator(__r, this);
 #else
@@ -1676,10 +1740,10 @@
     if (__f != __l)
     {
         __node_allocator& __na = base::__node_alloc();
-        base::__unlink_nodes(const_cast<__node&>(*__f.__ptr_), *__l.__ptr_->__prev_);
+        base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_);
         while (__f != __l)
         {
-            __node& __n = const_cast<__node&>(*__f.__ptr_);
+            __node_pointer __n = __f.__ptr_;
             ++__f;
             --base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1688,7 +1752,7 @@
             {
                 --__p;
                 iterator* __i = static_cast<iterator*>((*__p)->__i_);
-                if (__i->__ptr_ == &__n)
+                if (__i->__ptr_ == __n)
                 {
                     (*__p)->__c_ = nullptr;
                     if (--__c->end_ != __p)
@@ -1697,14 +1761,14 @@
             }
             __get_db()->unlock();
 #endif
-            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_));
-            __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1);
+            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+            __node_alloc_traits::deallocate(__na, __n, 1);
         }
     }
 #if _LIBCPP_DEBUG_LEVEL >= 2
-    return iterator(const_cast<__node_pointer>(__l.__ptr_), this);
+    return iterator(__l.__ptr_, this);
 #else
-    return iterator(const_cast<__node_pointer>(__l.__ptr_));
+    return iterator(__l.__ptr_);
 #endif
 }
 
@@ -1762,7 +1826,8 @@
             throw;
         }
 #endif  // _LIBCPP_NO_EXCEPTIONS
-        __link_nodes(static_cast<__node&>(base::__end_), *__r.__ptr_, *__e.__ptr_);
+        __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
 }
@@ -1821,7 +1886,8 @@
             throw;
         }
 #endif  // _LIBCPP_NO_EXCEPTIONS
-        __link_nodes(static_cast<__node&>(base::__end_), *__r.__ptr_, *__e.__ptr_);
+        __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_);
         base::__sz() += __ds;
     }
 }
@@ -1839,10 +1905,10 @@
 #endif
     if (!__c.empty())
     {
-        __node& __f = *__c.__end_.__next_;
-        __node& __l = *__c.__end_.__prev_;
+        __node_pointer __f = __c.__end_.__next_;
+        __node_pointer __l = __c.__end_.__prev_;
         base::__unlink_nodes(__f, __l);
-        __link_nodes(const_cast<__node&>(*__p.__ptr_), __f, __l);
+        __link_nodes(__p.__ptr_, __f, __l);
         base::__sz() += __c.__sz();
         __c.__sz() = 0;
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1853,7 +1919,8 @@
         {
             --__p;
             iterator* __i = static_cast<iterator*>((*__p)->__i_);
-            if (__i->__ptr_ != static_cast<__node_pointer>(&__c.__end_))
+            if (__i->__ptr_ != static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
             {
                 __cn1->__add(*__p);
                 (*__p)->__c_ = __cn1;
@@ -1883,9 +1950,9 @@
 #endif
     if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)
     {
-        __node& __f = const_cast<__node&>(*__i.__ptr_);
+        __node_pointer __f = __i.__ptr_;
         base::__unlink_nodes(__f, __f);
-        __link_nodes(const_cast<__node&>(*__p.__ptr_), __f, __f);
+        __link_nodes(__p.__ptr_, __f, __f);
         --__c.__sz();
         ++base::__sz();
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1896,7 +1963,7 @@
         {
             --__p;
             iterator* __j = static_cast<iterator*>((*__p)->__i_);
-            if (__j->__ptr_ == &__f)
+            if (__j->__ptr_ == __f)
             {
                 __cn1->__add(*__p);
                 (*__p)->__c_ = __cn1;
@@ -1937,11 +2004,11 @@
             __c.__sz() -= __s;
             base::__sz() += __s;
         }
-        __node& __first = const_cast<__node&>(*__f.__ptr_);
+        __node_pointer __first = __f.__ptr_;
         --__l;
-        __node& __last = const_cast<__node&>(*__l.__ptr_);
+        __node_pointer __last = __l.__ptr_;
         base::__unlink_nodes(__first, __last);
-        __link_nodes(const_cast<__node&>(*__p.__ptr_), __first, __last);
+        __link_nodes(__p.__ptr_, __first, __last);
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __libcpp_db* __db = __get_db();
         __c_node* __cn1 = __db->__find_c_and_lock(this);
@@ -1950,7 +2017,7 @@
         {
             --__p;
             iterator* __j = static_cast<iterator*>((*__p)->__i_);
-            for (__node_pointer __k = const_cast<__node_pointer>(__f.__ptr_);
+            for (__node_pointer __k = __f.__ptr_;
                                           __k != __l.__ptr_; __k = __k->__next_)
             {
                 if (__j->__ptr_ == __k)
@@ -2056,12 +2123,12 @@
                     ;
                 base::__sz() += __ds;
                 __c.__sz() -= __ds;
-                __node& __f = *__f2.__ptr_;
-                __node& __l = *__m2.__ptr_->__prev_;
+                __node_pointer __f = __f2.__ptr_;
+                __node_pointer __l = __m2.__ptr_->__prev_;
                 __f2 = __m2;
                 base::__unlink_nodes(__f, __l);
                 __m2 = _VSTD::next(__f1);
-                __link_nodes(*__f1.__ptr_, __f, __l);
+                __link_nodes(__f1.__ptr_, __f, __l);
                 __f1 = __m2;
             }
             else
@@ -2076,7 +2143,8 @@
         {
             --__p;
             iterator* __i = static_cast<iterator*>((*__p)->__i_);
-            if (__i->__ptr_ != static_cast<__node_pointer>(&__c.__end_))
+            if (__i->__ptr_ != static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
             {
                 __cn1->__add(*__p);
                 (*__p)->__c_ = __cn1;
@@ -2119,9 +2187,9 @@
     case 2:
         if (__comp(*--__e2, *__f1))
         {
-            __node& __f = *__e2.__ptr_;
+            __node_pointer __f = __e2.__ptr_;
             base::__unlink_nodes(__f, __f);
-            __link_nodes(*__f1.__ptr_, __f, __f);
+            __link_nodes(__f1.__ptr_, __f, __f);
             return __e2;
         }
         return __f1;
@@ -2135,13 +2203,13 @@
         iterator __m2 = _VSTD::next(__f2);
         for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
             ;
-        __node& __f = *__f2.__ptr_;
-        __node& __l = *__m2.__ptr_->__prev_;
+        __node_pointer __f = __f2.__ptr_;
+        __node_pointer __l = __m2.__ptr_->__prev_;
         __r = __f2;
         __e1 = __f2 = __m2;
         base::__unlink_nodes(__f, __l);
         __m2 = _VSTD::next(__f1);
-        __link_nodes(*__f1.__ptr_, __f, __l);
+        __link_nodes(__f1.__ptr_, __f, __l);
         __f1 = __m2;
     }
     else
@@ -2153,14 +2221,14 @@
             iterator __m2 = _VSTD::next(__f2);
             for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
                 ;
-            __node& __f = *__f2.__ptr_;
-            __node& __l = *__m2.__ptr_->__prev_;
+            __node_pointer __f = __f2.__ptr_;
+            __node_pointer __l = __m2.__ptr_->__prev_;
             if (__e1 == __f2)
                 __e1 = __m2;
             __f2 = __m2;
             base::__unlink_nodes(__f, __l);
             __m2 = _VSTD::next(__f1);
-            __link_nodes(*__f1.__ptr_, __f, __l);
+            __link_nodes(__f1.__ptr_, __f, __l);
             __f1 = __m2;
         }
         else
@@ -2198,7 +2266,8 @@
 bool
 list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
 {
-    return __i->__ptr_ != &this->__end_;
+    return __i->__ptr_ != static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(this->__end_)));
 }
 
 template <class _Tp, class _Alloc>
diff --git a/include/locale b/include/locale
index bd3a8c1..cc0fcf6 100644
--- a/include/locale
+++ b/include/locale
@@ -93,10 +93,12 @@
     typedef typename Codecvt::state_type                      state_type;
     typedef typename wide_string::traits_type::int_type       int_type;
 
-    wstring_convert(Codecvt* pcvt = new Codecvt);
+    explicit wstring_convert(Codecvt* pcvt = new Codecvt);          // explicit in C++14
     wstring_convert(Codecvt* pcvt, state_type state);
-    wstring_convert(const byte_string& byte_err,
+    explicit wstring_convert(const byte_string& byte_err,           // explicit in C++14
                     const wide_string& wide_err = wide_string());
+    wstring_convert(const wstring_convert&) = delete;               // C++14
+    wstring_convert & operator=(const wstring_convert &) = delete;  // C++14
     ~wstring_convert();
 
     wide_string from_bytes(char byte);
@@ -109,7 +111,7 @@
     byte_string to_bytes(const wide_string& wstr);
     byte_string to_bytes(const Elem* first, const Elem* last);
 
-    size_t converted() const;
+    size_t converted() const; // noexcept in C++14
     state_type state() const;
 };
 
@@ -120,9 +122,12 @@
 public:
     typedef typename Tr::state_type state_type;
 
-    wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
-                    state_type state = state_type());
-
+    explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
+                    state_type state = state_type());       // explicit in C++14
+    wbuffer_convert(const wbuffer_convert&) = delete;               // C++14
+    wbuffer_convert & operator=(const wbuffer_convert &) = delete;  // C++14
+    ~wbuffer_convert();                                             // C++14
+    
     streambuf* rdbuf() const;
     streambuf* rdbuf(streambuf* bytebuf);
 
@@ -186,13 +191,13 @@
 #endif
 #include <cstdlib>
 #include <ctime>
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
 #include <support/win32/locale_win32.h>
 #elif defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
 // Nothing.
-#else // _WIN32
+#else // _LIBCPP_MSVCRT
 #include <nl_types.h>
-#endif  // !_WIN32
+#endif  // !_LIBCPP_MSVCRT
 
 #ifdef __APPLE__
 #include <Availability.h>
@@ -208,10 +213,12 @@
 
 #if defined(__APPLE__) || defined(__FreeBSD__)
 #  define _LIBCPP_GET_C_LOCALE 0
+#elif defined(__NetBSD__)
+#  define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
 #else
 #  define _LIBCPP_GET_C_LOCALE __cloc()
    // Get the C locale object
-   locale_t __cloc();
+   _LIBCPP_FUNC_VIS locale_t __cloc();
 #define __cloc_defined
 #endif
 
@@ -224,7 +231,7 @@
 // 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(_NEWLIB_VERSION) // @LOCALMOD
+#if defined(__linux__) || defined(EMSCRIPTEN) || defined(_AIX) || defined(_NEWLIB_VERSION) // @LOCALMOD
 
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
 decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
@@ -234,7 +241,7 @@
   return MB_CUR_MAX_L(__l);
 }
 #else  // _LIBCPP_LOCALE__L_EXTENSIONS
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
 {
   __locale_raii __current(uselocale(__l), uselocale);
@@ -242,7 +249,7 @@
 }
 #endif // _LIBCPP_LOCALE__L_EXTENSIONS
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 wint_t __btowc_l(int __c, locale_t __l)
 {
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
@@ -253,7 +260,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 int __wctob_l(wint_t __c, locale_t __l)
 {
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
@@ -264,7 +271,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
                       size_t __len, mbstate_t *__ps, locale_t __l)
 {
@@ -276,7 +283,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
 {
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
@@ -287,7 +294,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
                       size_t __len, mbstate_t *__ps, locale_t __l)
 {
@@ -299,7 +306,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
                    mbstate_t *__ps, locale_t __l)
 {
@@ -311,7 +318,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
 {
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
@@ -322,7 +329,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
 {
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
@@ -333,7 +340,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 lconv *__localeconv_l(locale_t __l)
 {
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
@@ -344,7 +351,7 @@
 #endif
 }
 
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
                      mbstate_t *__ps, locale_t __l)
 {
@@ -357,20 +364,6 @@
 }
 
 inline
-int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) {
-  va_list __va;
-  va_start(__va, __format);
-#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-  int __res = vsprintf_l(__s, __l, __format, __va);
-#else
-  __locale_raii __current(uselocale(__l), uselocale);
-  int __res = vsprintf(__s, __format, __va);
-#endif
-  va_end(__va);
-  return __res;
-}
-
-inline
 int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
   va_list __va;
   va_start(__va, __format);
@@ -542,7 +535,7 @@
     return __kb;
 }
 
-struct __num_get_base
+struct _LIBCPP_TYPE_VIS __num_get_base
 {
     static const int __num_get_buf_sz = 40;
 
@@ -550,6 +543,7 @@
     static const char __src[33];
 };
 
+_LIBCPP_FUNC_VIS
 void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
                       ios_base::iostate& __err);
 
@@ -700,11 +694,11 @@
     return 0;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(struct __num_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(struct __num_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS num_get
+class _LIBCPP_TYPE_VIS_ONLY num_get
     : public locale::facet,
       private __num_get<_CharT>
 {
@@ -799,26 +793,61 @@
     _LIBCPP_ALWAYS_INLINE
     ~num_get() {}
 
+    template <class _Fp>
+    iter_type __do_get_floating_point
+                            (iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, _Fp& __v) const;
+
+    template <class _Signed>
+    iter_type __do_get_signed
+                            (iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, _Signed& __v) const;
+
+    template <class _Unsigned>
+    iter_type __do_get_unsigned
+                            (iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, _Unsigned& __v) const;
+
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
                              ios_base::iostate& __err, bool& __v) const;
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, long& __v) const;
+                             ios_base::iostate& __err, long& __v) const
+    { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, long long& __v) const;
+                             ios_base::iostate& __err, long long& __v) const
+    { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, unsigned short& __v) const;
+                             ios_base::iostate& __err, unsigned short& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, unsigned int& __v) const;
+                             ios_base::iostate& __err, unsigned int& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, unsigned long& __v) const;
+                             ios_base::iostate& __err, unsigned long& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, unsigned long long& __v) const;
+                             ios_base::iostate& __err, unsigned long long& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, float& __v) const;
+                             ios_base::iostate& __err, float& __v) const
+    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, double& __v) const;
+                             ios_base::iostate& __err, double& __v) const
+    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
-                             ios_base::iostate& __err, long double& __v) const;
+                             ios_base::iostate& __err, long double& __v) const
+    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
+
     virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
                              ios_base::iostate& __err, void*& __v) const;
 };
@@ -960,12 +989,15 @@
     return __b;
 }
 
+// signed
+
 template <class _CharT, class _InputIterator>
+template <class _Signed>
 _InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
                                         ios_base& __iob,
                                         ios_base::iostate& __err,
-                                        long& __v) const
+                                        _Signed& __v) const
 {
     // Stage 1
     int __base = this->__get_base(__iob);
@@ -998,7 +1030,7 @@
     if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
         *__g_end++ = __dc;
     // Stage 3
-    __v = __num_get_signed_integral<long>(__a, __a_end, __err, __base);
+    __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
     // Digit grouping checked
     __check_grouping(__grouping, __g, __g_end, __err);
     // EOF checked
@@ -1007,12 +1039,15 @@
     return __b;
 }
 
+// unsigned
+
 template <class _CharT, class _InputIterator>
+template <class _Unsigned>
 _InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
                                         ios_base& __iob,
                                         ios_base::iostate& __err,
-                                        long long& __v) const
+                                        _Unsigned& __v) const
 {
     // Stage 1
     int __base = this->__get_base(__iob);
@@ -1045,7 +1080,7 @@
     if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
         *__g_end++ = __dc;
     // Stage 3
-    __v = __num_get_signed_integral<long long>(__a, __a_end, __err, __base);
+    __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
     // Digit grouping checked
     __check_grouping(__grouping, __g, __g_end, __err);
     // EOF checked
@@ -1054,200 +1089,15 @@
     return __b;
 }
 
-template <class _CharT, class _InputIterator>
-_InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
-                                        ios_base& __iob,
-                                        ios_base::iostate& __err,
-                                        unsigned short& __v) const
-{
-    // Stage 1
-    int __base = this->__get_base(__iob);
-    // Stage 2
-    char_type __atoms[26];
-    char_type __thousands_sep;
-    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
-    string __buf;
-    __buf.resize(__buf.capacity());
-    char* __a = &__buf[0];
-    char* __a_end = __a;
-    unsigned __g[__num_get_base::__num_get_buf_sz];
-    unsigned* __g_end = __g;
-    unsigned __dc = 0;
-    for (; __b != __e; ++__b)
-    {
-        if (__a_end - __a == __buf.size())
-        {
-            size_t __tmp = __buf.size();
-            __buf.resize(2*__buf.size());
-            __buf.resize(__buf.capacity());
-            __a = &__buf[0];
-            __a_end = __a + __tmp;
-        }
-        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
-                                    __thousands_sep, __grouping, __g, __g_end,
-                                    __atoms))
-            break;
-    }
-    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
-        *__g_end++ = __dc;
-    // Stage 3
-    __v = __num_get_unsigned_integral<unsigned short>(__a, __a_end, __err, __base);
-    // Digit grouping checked
-    __check_grouping(__grouping, __g, __g_end, __err);
-    // EOF checked
-    if (__b == __e)
-        __err |= ios_base::eofbit;
-    return __b;
-}
+// floating point
 
 template <class _CharT, class _InputIterator>
+template <class _Fp>
 _InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
                                         ios_base& __iob,
                                         ios_base::iostate& __err,
-                                        unsigned int& __v) const
-{
-    // Stage 1
-    int __base = this->__get_base(__iob);
-    // Stage 2
-    char_type __atoms[26];
-    char_type __thousands_sep;
-    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
-    string __buf;
-    __buf.resize(__buf.capacity());
-    char* __a = &__buf[0];
-    char* __a_end = __a;
-    unsigned __g[__num_get_base::__num_get_buf_sz];
-    unsigned* __g_end = __g;
-    unsigned __dc = 0;
-    for (; __b != __e; ++__b)
-    {
-        if (__a_end - __a == __buf.size())
-        {
-            size_t __tmp = __buf.size();
-            __buf.resize(2*__buf.size());
-            __buf.resize(__buf.capacity());
-            __a = &__buf[0];
-            __a_end = __a + __tmp;
-        }
-        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
-                                    __thousands_sep, __grouping, __g, __g_end,
-                                    __atoms))
-            break;
-    }
-    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
-        *__g_end++ = __dc;
-    // Stage 3
-    __v = __num_get_unsigned_integral<unsigned int>(__a, __a_end, __err, __base);
-    // Digit grouping checked
-    __check_grouping(__grouping, __g, __g_end, __err);
-    // EOF checked
-    if (__b == __e)
-        __err |= ios_base::eofbit;
-    return __b;
-}
-
-template <class _CharT, class _InputIterator>
-_InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
-                                        ios_base& __iob,
-                                        ios_base::iostate& __err,
-                                        unsigned long& __v) const
-{
-    // Stage 1
-    int __base = this->__get_base(__iob);
-    // Stage 2
-    char_type __atoms[26];
-    char_type __thousands_sep;
-    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
-    string __buf;
-    __buf.resize(__buf.capacity());
-    char* __a = &__buf[0];
-    char* __a_end = __a;
-    unsigned __g[__num_get_base::__num_get_buf_sz];
-    unsigned* __g_end = __g;
-    unsigned __dc = 0;
-    for (; __b != __e; ++__b)
-    {
-        if (__a_end - __a == __buf.size())
-        {
-            size_t __tmp = __buf.size();
-            __buf.resize(2*__buf.size());
-            __buf.resize(__buf.capacity());
-            __a = &__buf[0];
-            __a_end = __a + __tmp;
-        }
-        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
-                                    __thousands_sep, __grouping, __g, __g_end,
-                                    __atoms))
-            break;
-    }
-    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
-        *__g_end++ = __dc;
-    // Stage 3
-    __v = __num_get_unsigned_integral<unsigned long>(__a, __a_end, __err, __base);
-    // Digit grouping checked
-    __check_grouping(__grouping, __g, __g_end, __err);
-    // EOF checked
-    if (__b == __e)
-        __err |= ios_base::eofbit;
-    return __b;
-}
-
-template <class _CharT, class _InputIterator>
-_InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
-                                        ios_base& __iob,
-                                        ios_base::iostate& __err,
-                                        unsigned long long& __v) const
-{
-    // Stage 1
-    int __base = this->__get_base(__iob);
-    // Stage 2
-    char_type __atoms[26];
-    char_type __thousands_sep;
-    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
-    string __buf;
-    __buf.resize(__buf.capacity());
-    char* __a = &__buf[0];
-    char* __a_end = __a;
-    unsigned __g[__num_get_base::__num_get_buf_sz];
-    unsigned* __g_end = __g;
-    unsigned __dc = 0;
-    for (; __b != __e; ++__b)
-    {
-        if (__a_end - __a == __buf.size())
-        {
-            size_t __tmp = __buf.size();
-            __buf.resize(2*__buf.size());
-            __buf.resize(__buf.capacity());
-            __a = &__buf[0];
-            __a_end = __a + __tmp;
-        }
-        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
-                                    __thousands_sep, __grouping, __g, __g_end,
-                                    __atoms))
-            break;
-    }
-    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
-        *__g_end++ = __dc;
-    // Stage 3
-    __v = __num_get_unsigned_integral<unsigned long long>(__a, __a_end, __err, __base);
-    // Digit grouping checked
-    __check_grouping(__grouping, __g, __g_end, __err);
-    // EOF checked
-    if (__b == __e)
-        __err |= ios_base::eofbit;
-    return __b;
-}
-
-template <class _CharT, class _InputIterator>
-_InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
-                                        ios_base& __iob,
-                                        ios_base::iostate& __err,
-                                        float& __v) const
+                                        _Fp& __v) const
 {
     // Stage 1, nothing to do
     // Stage 2
@@ -1285,111 +1135,7 @@
     if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
         *__g_end++ = __dc;
     // Stage 3
-    __v = __num_get_float<float>(__a, __a_end, __err);
-    // Digit grouping checked
-    __check_grouping(__grouping, __g, __g_end, __err);
-    // EOF checked
-    if (__b == __e)
-        __err |= ios_base::eofbit;
-    return __b;
-}
-
-template <class _CharT, class _InputIterator>
-_InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
-                                        ios_base& __iob,
-                                        ios_base::iostate& __err,
-                                        double& __v) const
-{
-    // Stage 1, nothing to do
-    // Stage 2
-    char_type __atoms[32];
-    char_type __decimal_point;
-    char_type __thousands_sep;
-    string __grouping = this->__stage2_float_prep(__iob, __atoms,
-                                                  __decimal_point,
-                                                  __thousands_sep);
-    string __buf;
-    __buf.resize(__buf.capacity());
-    char* __a = &__buf[0];
-    char* __a_end = __a;
-    unsigned __g[__num_get_base::__num_get_buf_sz];
-    unsigned* __g_end = __g;
-    unsigned __dc = 0;
-    bool __in_units = true;
-    char __exp = 'E';
-    for (; __b != __e; ++__b)
-    {
-        if (__a_end - __a == __buf.size())
-        {
-            size_t __tmp = __buf.size();
-            __buf.resize(2*__buf.size());
-            __buf.resize(__buf.capacity());
-            __a = &__buf[0];
-            __a_end = __a + __tmp;
-        }
-        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
-                                      __decimal_point, __thousands_sep,
-                                      __grouping, __g, __g_end,
-                                      __dc, __atoms))
-            break;
-    }
-    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
-        *__g_end++ = __dc;
-    // Stage 3
-    __v = __num_get_float<double>(__a, __a_end, __err);
-    // Digit grouping checked
-    __check_grouping(__grouping, __g, __g_end, __err);
-    // EOF checked
-    if (__b == __e)
-        __err |= ios_base::eofbit;
-    return __b;
-}
-
-template <class _CharT, class _InputIterator>
-_InputIterator
-num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
-                                        ios_base& __iob,
-                                        ios_base::iostate& __err,
-                                        long double& __v) const
-{
-    // Stage 1, nothing to do
-    // Stage 2
-    char_type __atoms[32];
-    char_type __decimal_point;
-    char_type __thousands_sep;
-    string __grouping = this->__stage2_float_prep(__iob, __atoms,
-                                                  __decimal_point,
-                                                  __thousands_sep);
-    string __buf;
-    __buf.resize(__buf.capacity());
-    char* __a = &__buf[0];
-    char* __a_end = __a;
-    unsigned __g[__num_get_base::__num_get_buf_sz];
-    unsigned* __g_end = __g;
-    unsigned __dc = 0;
-    bool __in_units = true;
-    char __exp = 'E';
-    for (; __b != __e; ++__b)
-    {
-        if (__a_end - __a == __buf.size())
-        {
-            size_t __tmp = __buf.size();
-            __buf.resize(2*__buf.size());
-            __buf.resize(__buf.capacity());
-            __a = &__buf[0];
-            __a_end = __a + __tmp;
-        }
-        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
-                                      __decimal_point, __thousands_sep,
-                                      __grouping, __g, __g_end,
-                                      __dc, __atoms))
-            break;
-    }
-    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
-        *__g_end++ = __dc;
-    // Stage 3
-    __v = __num_get_float<long double>(__a, __a_end, __err);
+    __v = __num_get_float<_Fp>(__a, __a_end, __err);
     // Digit grouping checked
     __check_grouping(__grouping, __g, __g_end, __err);
     // EOF checked
@@ -1449,10 +1195,10 @@
     return __b;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class num_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class num_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
 
-struct __num_put_base
+struct _LIBCPP_TYPE_VIS __num_put_base
 {
 protected:
     static void __format_int(char* __fmt, const char* __len, bool __signd,
@@ -1599,11 +1345,11 @@
         __op = __ob + (__np - __nb);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(struct __num_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(struct __num_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
 
 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS num_put
+class _LIBCPP_TYPE_VIS_ONLY num_put
     : public locale::facet,
       private __num_put<_CharT>
 {
@@ -1783,7 +1529,12 @@
         return do_put(__s, __iob, __fl, (unsigned long)__v);
     const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
     typedef typename numpunct<char_type>::string_type string_type;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    string_type __tmp(__v ? __np.truename() : __np.falsename());
+    string_type __nm = _VSTD::move(__tmp);
+#else
     string_type __nm = __v ? __np.truename() : __np.falsename();
+#endif
     for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
         *__s = *__i;
     return __s;
@@ -1803,9 +1554,9 @@
                           + 1;
     char __nar[__nbuf];
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
 #else
-    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
 #endif
     char* __ne = __nar + __nc;
     char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -1833,9 +1584,9 @@
                           + 1;
     char __nar[__nbuf];
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
 #else
-    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
 #endif
     char* __ne = __nar + __nc;
     char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -1863,9 +1614,9 @@
                           + 1;
     char __nar[__nbuf];
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
 #else
-    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
 #endif
     char* __ne = __nar + __nc;
     char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -1893,9 +1644,9 @@
                           + 1;
     char __nar[__nbuf];
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
 #else
-    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
 #endif
     char* __ne = __nar + __nc;
     char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -2057,9 +1808,9 @@
     const unsigned __nbuf = 20;
     char __nar[__nbuf];
 #ifdef _LIBCPP_LOCALE__L_EXTENSIONS
-    int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
 #else
-    int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v);
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
 #endif
     char* __ne = __nar + __nc;
     char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -2079,8 +1830,8 @@
     return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class num_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class num_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>)
 
 template <class _CharT, class _InputIterator>
 _LIBCPP_HIDDEN
@@ -2122,7 +1873,7 @@
 };
 
 template <class _CharT>
-class __time_get_c_storage  // purposefully not decorated
+class _LIBCPP_TYPE_VIS __time_get_c_storage
 {
 protected:
     typedef basic_string<_CharT> string_type;
@@ -2137,7 +1888,7 @@
 };
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS time_get
+class _LIBCPP_TYPE_VIS_ONLY time_get
     : public locale::facet,
       public time_base,
       private __time_get_c_storage<_CharT>
@@ -2746,10 +2497,10 @@
     return __b;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class time_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class time_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
 
-class __time_get
+class _LIBCPP_TYPE_VIS __time_get
 {
 protected:
     locale_t __loc_;
@@ -2760,7 +2511,7 @@
 };
 
 template <class _CharT>
-class __time_get_storage
+class _LIBCPP_TYPE_VIS __time_get_storage
     : public __time_get
 {
 protected:
@@ -2787,7 +2538,7 @@
 };
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS time_get_byname
+class _LIBCPP_TYPE_VIS_ONLY time_get_byname
     : public time_get<_CharT, _InputIterator>,
       private __time_get_storage<_CharT>
 {
@@ -2829,10 +2580,10 @@
     virtual const string_type& __X() const      {return this->__X_;}
 };
 
-_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<char>)
-_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
 
-class __time_put
+class _LIBCPP_TYPE_VIS __time_put
 {
     locale_t __loc_;
 protected:
@@ -2847,7 +2598,7 @@
 };
 
 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS time_put
+class _LIBCPP_TYPE_VIS_ONLY time_put
     : public locale::facet,
       private __time_put
 {
@@ -2942,11 +2693,11 @@
     return _VSTD::copy(__nb, __ne, __s);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class time_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class time_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
 
 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS time_put_byname
+class _LIBCPP_TYPE_VIS_ONLY time_put_byname
     : public time_put<_CharT, _OutputIterator>
 {
 public:
@@ -2963,8 +2714,8 @@
     ~time_put_byname() {}
 };
 
-_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<char>)
-_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
 
 // money_base
 
@@ -2980,7 +2731,7 @@
 // moneypunct
 
 template <class _CharT, bool _International = false>
-class _LIBCPP_TYPE_VIS moneypunct
+class _LIBCPP_TYPE_VIS_ONLY moneypunct
     : public locale::facet,
       public money_base
 {
@@ -3030,15 +2781,15 @@
 const bool
 moneypunct<_CharT, _International>::intl;
 
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, false>)
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, true>)
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, false>)
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
 
 // moneypunct_byname
 
 template <class _CharT, bool _International = false>
-class _LIBCPP_TYPE_VIS moneypunct_byname
+class _LIBCPP_TYPE_VIS_ONLY moneypunct_byname
     : public moneypunct<_CharT, _International>
 {
 public:
@@ -3087,10 +2838,10 @@
 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
 
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, false>)
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, true>)
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, false>)
-_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
 
 // money_get
 
@@ -3146,11 +2897,11 @@
     }
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class __money_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class __money_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS money_get
+class _LIBCPP_TYPE_VIS_ONLY money_get
     : public locale::facet,
       private __money_get<_CharT>
 {
@@ -3204,7 +2955,7 @@
 locale::id
 money_get<_CharT, _InputIterator>::id;
 
-void __do_nothing(void*);
+_LIBCPP_FUNC_VIS void __do_nothing(void*);
 
 template <class _Tp>
 _LIBCPP_HIDDEN
@@ -3334,7 +3085,7 @@
             bool __more_needed = __trailing_sign ||
                                  (__p < 2)       ||
                                  (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
-            bool __sb = __flags & ios_base::showbase;
+            bool __sb = (__flags & ios_base::showbase) != 0;
             if (__sb || __more_needed)
             {
                 typename string_type::const_iterator __sym_space_end = __sym.begin();
@@ -3527,8 +3278,8 @@
     return __b;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class money_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class money_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
 
 // money_put
 
@@ -3702,11 +3453,11 @@
         __mi = __mb;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class __money_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class __money_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
 
 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
-class _LIBCPP_TYPE_VIS money_put
+class _LIBCPP_TYPE_VIS_ONLY money_put
     : public locale::facet,
       private __money_put<_CharT>
 {
@@ -3859,8 +3610,8 @@
     return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class money_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class money_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
 
 // messages
 
@@ -3873,7 +3624,7 @@
 };
 
 template <class _CharT>
-class _LIBCPP_TYPE_VIS messages
+class _LIBCPP_TYPE_VIS_ONLY messages
     : public locale::facet,
       public messages_base
 {
@@ -3969,11 +3720,11 @@
 #endif // !_WIN32
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class messages<char>)
-_LIBCPP_EXTERN_TEMPLATE(class messages<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)
 
 template <class _CharT>
-class _LIBCPP_TYPE_VIS messages_byname
+class _LIBCPP_TYPE_VIS_ONLY messages_byname
     : public messages<_CharT>
 {
 public:
@@ -3993,13 +3744,13 @@
     ~messages_byname() {}
 };
 
-_LIBCPP_EXTERN_TEMPLATE(class messages_byname<char>)
-_LIBCPP_EXTERN_TEMPLATE(class messages_byname<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
 
 template<class _Codecvt, class _Elem = wchar_t,
          class _Wide_alloc = allocator<_Elem>,
          class _Byte_alloc = allocator<char> >
-class _LIBCPP_TYPE_VIS wstring_convert
+class _LIBCPP_TYPE_VIS_ONLY wstring_convert
 {
 public:
     typedef basic_string<char, char_traits<char>, _Byte_alloc>   byte_string;
@@ -4017,9 +3768,9 @@
     wstring_convert(const wstring_convert& __wc);
     wstring_convert& operator=(const wstring_convert& __wc);
 public:
-    wstring_convert(_Codecvt* __pcvt = new _Codecvt);
+    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
     wstring_convert(_Codecvt* __pcvt, state_type __state);
-    wstring_convert(const byte_string& __byte_err,
+    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
                     const wide_string& __wide_err = wide_string());
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     wstring_convert(wstring_convert&& __wc);
@@ -4049,7 +3800,7 @@
     byte_string to_bytes(const _Elem* __first, const _Elem* __last);
 
     _LIBCPP_ALWAYS_INLINE
-    size_t converted() const {return __cvtcount_;}
+    size_t converted() const _NOEXCEPT {return __cvtcount_;}
     _LIBCPP_ALWAYS_INLINE
     state_type state() const {return __cvtstate_;}
 };
@@ -4252,7 +4003,7 @@
 }
 
 template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
-class _LIBCPP_TYPE_VIS wbuffer_convert
+class _LIBCPP_TYPE_VIS_ONLY wbuffer_convert
     : public basic_streambuf<_Elem, _Tr>
 {
 public:
@@ -4283,8 +4034,8 @@
     wbuffer_convert(const wbuffer_convert&);
     wbuffer_convert& operator=(const wbuffer_convert&);
 public:
-    wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt,
-                    state_type __state = state_type());
+    _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0, 
+            _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
     ~wbuffer_convert();
 
     _LIBCPP_INLINE_VISIBILITY
diff --git a/include/map b/include/map
index abc07a3..009e8e2 100644
--- a/include/map
+++ b/include/map
@@ -77,7 +77,12 @@
     map(map&& m, const allocator_type& a);
     map(initializer_list<value_type> il, const key_compare& comp = key_compare());
     map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
-    ~map();
+    template <class InputIterator>
+        map(InputIterator first, InputIterator last, const allocator_type& a)
+            : map(first, last, Compare(), a) {}  // C++14
+    map(initializer_list<value_type> il, const allocator_type& a)
+        : map(il, Compare(), a) {}  // C++14
+   ~map();
 
     map& operator=(const map& m);
     map& operator=(map&& m)
@@ -149,13 +154,34 @@
     // map operations:
           iterator find(const key_type& k);
     const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);              // C++14
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+    template<typename K>
+      size_type count(const K& x) const;
+
     size_type      count(const key_type& k) const;
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
           iterator upper_bound(const key_type& k);
     const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
+
     pair<iterator,iterator>             equal_range(const key_type& k);
     pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
 };
 
 template <class Key, class T, class Compare, class Allocator>
@@ -252,6 +278,11 @@
     multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
     multimap(initializer_list<value_type> il, const key_compare& comp,
              const allocator_type& a);
+    template <class InputIterator>
+        multimap(InputIterator first, InputIterator last, const allocator_type& a)
+            : multimap(first, last, Compare(), a) {} // C++14
+    multimap(initializer_list<value_type> il, const allocator_type& a)
+        : multimap(il, Compare(), a) {} // C++14
     ~multimap();
 
     multimap& operator=(const multimap& m);
@@ -317,13 +348,34 @@
     // map operations:
           iterator find(const key_type& k);
     const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);              // C++14
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+    template<typename K>
+      size_type count(const K& x) const;
+
     size_type      count(const key_type& k) const;
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
           iterator upper_bound(const key_type& k);
     const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
+
     pair<iterator,iterator>             equal_range(const key_type& k);
     pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
 };
 
 template <class Key, class T, class Compare, class Allocator>
@@ -381,7 +433,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Key, class _Tp, class _Compare, bool = is_empty<_Compare>::value
+template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value
 #if __has_feature(is_final)
                                                         && !__is_final(_Compare)
 #endif
@@ -389,8 +441,6 @@
 class __map_value_compare
     : private _Compare
 {
-    typedef pair<typename std::remove_const<_Key>::type, _Tp> _Pp;
-    typedef pair<const _Key, _Tp> _CP;
 public:
     _LIBCPP_INLINE_VISIBILITY
     __map_value_compare()
@@ -404,41 +454,34 @@
     const _Compare& key_comp() const _NOEXCEPT {return *this;}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _CP& __x, const _CP& __y) const
-        {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _CP& __x, const _Pp& __y) const
-        {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
+        {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y.__cc.first);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _CP& __x, const _Key& __y) const
-        {return static_cast<const _Compare&>(*this)(__x.first, __y);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _CP& __y) const
-        {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Pp& __y) const
-        {return static_cast<const _Compare&>(*this)(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Key& __y) const
-        {return static_cast<const _Compare&>(*this)(__x.first, __y);}
+        {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Key& __x, const _CP& __y) const
-        {return static_cast<const _Compare&>(*this)(__x, __y.first);}
+        {return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
+
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Pp& __y) const
-        {return static_cast<const _Compare&>(*this)(__x, __y.first);}
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () ( const _K2& __x, const _CP& __y ) const
+        {return static_cast<const _Compare&>(*this) (__x, __y.__cc.first);}
+
+    template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Key& __y) const
-        {return static_cast<const _Compare&>(*this)(__x, __y);}
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () (const _CP& __x, const _K2& __y) const
+        {return static_cast<const _Compare&>(*this) (__x.__cc.first, __y);}
+#endif
 };
 
-template <class _Key, class _Tp, class _Compare>
-class __map_value_compare<_Key, _Tp, _Compare, false>
+template <class _Key, class _CP, class _Compare>
+class __map_value_compare<_Key, _CP, _Compare, false>
 {
     _Compare comp;
 
-    typedef pair<typename std::remove_const<_Key>::type, _Tp> _Pp;
-    typedef pair<const _Key, _Tp> _CP;
-
 public:
     _LIBCPP_INLINE_VISIBILITY
     __map_value_compare()
@@ -453,31 +496,27 @@
 
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _CP& __x, const _CP& __y) const
-        {return comp(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _CP& __x, const _Pp& __y) const
-        {return comp(__x.first, __y.first);}
+        {return comp(__x.__cc.first, __y.__cc.first);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _CP& __x, const _Key& __y) const
-        {return comp(__x.first, __y);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _CP& __y) const
-        {return comp(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Pp& __y) const
-        {return comp(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Key& __y) const
-        {return comp(__x.first, __y);}
+        {return comp(__x.__cc.first, __y);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Key& __x, const _CP& __y) const
-        {return comp(__x, __y.first);}
+        {return comp(__x, __y.__cc.first);}
+
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Pp& __y) const
-        {return comp(__x, __y.first);}
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () ( const _K2& __x, const _CP& __y ) const
+        {return comp (__x, __y.__cc.first);}
+
+    template <typename _K2>
     _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Key& __y) const
-        {return comp(__x, __y);}
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () (const _CP& __x, const _K2& __y) const
+        {return comp (__x.__cc.first, __y);}
+#endif
 };
 
 template <class _Allocator>
@@ -489,8 +528,8 @@
 public:
     typedef typename __alloc_traits::pointer    pointer;
 private:
-    typedef typename value_type::first_type     first_type;
-    typedef typename value_type::second_type    second_type;
+    typedef typename value_type::value_type::first_type     first_type;
+    typedef typename value_type::value_type::second_type    second_type;
 
     allocator_type& __na_;
 
@@ -522,9 +561,9 @@
     void operator()(pointer __p) _NOEXCEPT
     {
         if (__second_constructed)
-            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
         if (__first_constructed)
-            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
         if (__p)
             __alloc_traits::deallocate(__na_, __p, 1);
     }
@@ -536,14 +575,83 @@
     class multimap;
 template <class _TreeIterator> class __map_const_iterator;
 
+#if __cplusplus >= 201103L
+
+template <class _Key, class _Tp>
+union __value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+
+    value_type __cc;
+    __nc_value_type __nc;
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(_Args&& ...__args)
+        : __cc(std::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const __value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(__value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(__value_type&& __v)
+        : __nc(std::move(__v.__nc)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type& operator=(const __value_type& __v)
+        {__nc = __v.__cc; return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type& operator=(__value_type&& __v)
+        {__nc = std::move(__v.__nc); return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__value_type() {__cc.~value_type();}
+};
+
+#else
+
+template <class _Key, class _Tp>
+struct __value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+
+    value_type __cc;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type() {}
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const _A0& __a0)
+        : __cc(__a0) {}
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const _A0& __a0, const _A1& __a1)
+        : __cc(__a0, __a1) {}
+};
+
+#endif
+
 template <class _TreeIterator>
-class _LIBCPP_TYPE_VIS __map_iterator
+class _LIBCPP_TYPE_VIS_ONLY __map_iterator
 {
     _TreeIterator __i_;
 
     typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
-    typedef const typename _TreeIterator::value_type::first_type __key_type;
-    typedef typename _TreeIterator::value_type::second_type      __mapped_type;
+    typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
+    typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
 public:
     typedef bidirectional_iterator_tag                           iterator_category;
     typedef pair<__key_type, __mapped_type>                      value_type;
@@ -564,9 +672,9 @@
     __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
 
     _LIBCPP_INLINE_VISIBILITY
-    reference operator*() const {return *operator->();}
+    reference operator*() const {return __i_->__cc;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return (pointer)__i_.operator->();}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
 
     _LIBCPP_INLINE_VISIBILITY
     __map_iterator& operator++() {++__i_; return *this;}
@@ -596,19 +704,19 @@
     bool operator!=(const __map_iterator& __x, const __map_iterator& __y)
         {return __x.__i_ != __y.__i_;}
 
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS map;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS multimap;
-    template <class> friend class _LIBCPP_TYPE_VIS __map_const_iterator;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
 };
 
 template <class _TreeIterator>
-class _LIBCPP_TYPE_VIS __map_const_iterator
+class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator
 {
     _TreeIterator __i_;
 
     typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
-    typedef const typename _TreeIterator::value_type::first_type __key_type;
-    typedef typename _TreeIterator::value_type::second_type      __mapped_type;
+    typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
+    typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
 public:
     typedef bidirectional_iterator_tag                           iterator_category;
     typedef pair<__key_type, __mapped_type>                      value_type;
@@ -634,9 +742,9 @@
                 : __i_(__i.__i_) {}
 
     _LIBCPP_INLINE_VISIBILITY
-    reference operator*() const {return *operator->();}
+    reference operator*() const {return __i_->__cc;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return (pointer)__i_.operator->();}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
 
     _LIBCPP_INLINE_VISIBILITY
     __map_const_iterator& operator++() {++__i_; return *this;}
@@ -665,26 +773,27 @@
     bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)
         {return __x.__i_ != __y.__i_;}
 
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS map;
-    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS multimap;
-    template <class, class, class> friend class _LIBCPP_TYPE_VIS __tree_const_iterator;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
 };
 
 template <class _Key, class _Tp, class _Compare = less<_Key>,
           class _Allocator = allocator<pair<const _Key, _Tp> > >
-class _LIBCPP_TYPE_VIS map
+class _LIBCPP_TYPE_VIS_ONLY map
 {
 public:
     // types:
     typedef _Key                                     key_type;
     typedef _Tp                                      mapped_type;
     typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
     typedef _Compare                                 key_compare;
     typedef _Allocator                               allocator_type;
     typedef value_type&                              reference;
     typedef const value_type&                        const_reference;
 
-    class _LIBCPP_TYPE_VIS value_compare
+    class _LIBCPP_TYPE_VIS_ONLY value_compare
         : public binary_function<value_type, value_type, bool>
     {
         friend class map;
@@ -699,8 +808,9 @@
     };
 
 private:
-    typedef pair<key_type, mapped_type>                             __value_type;
-    typedef __map_value_compare<key_type, mapped_type, key_compare> __vc;
+
+    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
+    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
     typedef typename allocator_traits<allocator_type>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
             rebind_alloc<__value_type>
@@ -754,6 +864,13 @@
             insert(__f, __l);
         }
 
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY 
+    map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+        : map(__f, __l, key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     map(const map& __m)
         : __tree_(__m.__tree_)
@@ -764,7 +881,14 @@
     _LIBCPP_INLINE_VISIBILITY
     map& operator=(const map& __m)
         {
+#if __cplusplus >= 201103L
             __tree_ = __m.__tree_;
+#else
+            __tree_.clear();
+            __tree_.value_comp() = __m.__tree_.value_comp();
+            __tree_.__copy_assign_alloc(__m.__tree_);
+            insert(__m.begin(), __m.end());
+#endif
             return *this;
         }
 
@@ -805,6 +929,12 @@
             insert(__il.begin(), __il.end());
         }
 
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    map(initializer_list<value_type> __il, const allocator_type& __a)
+        : map(__il, key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     map& operator=(initializer_list<value_type> __il)
         {
@@ -951,6 +1081,17 @@
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_unique(__k);}
@@ -960,18 +1101,51 @@
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
         {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     iterator upper_bound(const key_type& __k)
         {return __tree_.upper_bound(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
         {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator,iterator> equal_range(const key_type& __k)
         {return __tree_.__equal_range_unique(__k);}
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
         {return __tree_.__equal_range_unique(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_unique(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
+#endif
 
 private:
     typedef typename __base::__node                    __node;
@@ -986,32 +1160,17 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     __node_holder __construct_node();
     template <class _A0>
-        typename enable_if
-        <
-            is_constructible<value_type, _A0>::value,
-            __node_holder
-        >::type
-         __construct_node(_A0&& __a0);
-    template <class _A0>
-        typename enable_if
-        <
-            is_constructible<key_type, _A0>::value,
-            __node_holder
-        >::type
-         __construct_node(_A0&& __a0);
+        __node_holder __construct_node(_A0&& __a0);
+    __node_holder __construct_node_with_key(key_type&& __k);
 #ifndef _LIBCPP_HAS_NO_VARIADICS
     template <class _A0, class _A1, class ..._Args>
         __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
 #endif  // _LIBCPP_HAS_NO_VARIADICS
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    __node_holder __construct_node(const key_type& __k);
 #endif
+    __node_holder __construct_node_with_key(const key_type& __k);
 
     __node_base_pointer&
         __find_equal_key(__node_base_pointer& __parent, const key_type& __k);
-    __node_base_pointer&
-        __find_equal_key(const_iterator __hint,
-                         __node_base_pointer& __parent, const key_type& __k);
     __node_base_const_pointer
         __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const;
 };
@@ -1030,97 +1189,37 @@
     {
         while (true)
         {
-            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.first))
+            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
             {
                 if (__nd->__left_ != nullptr)
                     __nd = static_cast<__node_pointer>(__nd->__left_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__left_;
                 }
             }
-            else if (__tree_.value_comp().key_comp()(__nd->__value_.first, __k))
+            else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
             {
                 if (__nd->__right_ != nullptr)
                     __nd = static_cast<__node_pointer>(__nd->__right_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return __parent->__right_;
                 }
             }
             else
             {
-                __parent = __nd;
+                __parent = static_cast<__node_base_pointer>(__nd);
                 return __parent;
             }
         }
     }
-    __parent = __tree_.__end_node();
+    __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
     return __parent->__left_;
 }
 
-// Find place to insert if __k doesn't exist
-// First check prior to __hint.
-// Next check after __hint.
-// Next do O(log N) search.
-// Set __parent to parent of null leaf
-// Return reference to null leaf
-// If __k exists, set parent to node of __k and return reference to node of __k
-template <class _Key, class _Tp, class _Compare, class _Allocator>
-typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&
-map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(const_iterator __hint,
-                                                       __node_base_pointer& __parent,
-                                                       const key_type& __k)
-{
-    if (__hint == end() || __tree_.value_comp().key_comp()(__k, __hint->first))  // check before
-    {
-        // __k < *__hint
-        const_iterator __prior = __hint;
-        if (__prior == begin() || __tree_.value_comp().key_comp()((--__prior)->first, __k))
-        {
-            // *prev(__hint) < __k < *__hint
-            if (__hint.__ptr_->__left_ == nullptr)
-            {
-                __parent = const_cast<__node_pointer&>(__hint.__ptr_);
-                return __parent->__left_;
-            }
-            else
-            {
-                __parent = const_cast<__node_pointer&>(__prior.__ptr_);
-                return __parent->__right_;
-            }
-        }
-        // __k <= *prev(__hint)
-        return __find_equal_key(__parent, __k);
-    }
-    else if (__tree_.value_comp().key_comp()(__hint->first, __k))  // check after
-    {
-        // *__hint < __k
-        const_iterator __next = _VSTD::next(__hint);
-        if (__next == end() || __tree_.value_comp().key_comp()(__k, __next->first))
-        {
-            // *__hint < __k < *next(__hint)
-            if (__hint.__ptr_->__right_ == nullptr)
-            {
-                __parent = const_cast<__node_pointer&>(__hint.__ptr_);
-                return __parent->__right_;
-            }
-            else
-            {
-                __parent = const_cast<__node_pointer&>(__next.__ptr_);
-                return __parent->__left_;
-            }
-        }
-        // *next(__hint) <= __k
-        return __find_equal_key(__parent, __k);
-    }
-    // else __k == *__hint
-    __parent = const_cast<__node_pointer&>(__hint.__ptr_);
-    return __parent;
-}
-
 // Find __k
 // Set __parent to parent of null leaf and
 //    return reference to null leaf iv __k does not exist.
@@ -1135,34 +1234,34 @@
     {
         while (true)
         {
-            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.first))
+            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
             {
                 if (__nd->__left_ != nullptr)
                     __nd = static_cast<__node_pointer>(__nd->__left_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return const_cast<const __node_base_const_pointer&>(__parent->__left_);
                 }
             }
-            else if (__tree_.value_comp().key_comp()(__nd->__value_.first, __k))
+            else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
             {
                 if (__nd->__right_ != nullptr)
                     __nd = static_cast<__node_pointer>(__nd->__right_);
                 else
                 {
-                    __parent = __nd;
+                    __parent = static_cast<__node_base_pointer>(__nd);
                     return const_cast<const __node_base_const_pointer&>(__parent->__right_);
                 }
             }
             else
             {
-                __parent = __nd;
+                __parent = static_cast<__node_base_pointer>(__nd);
                 return __parent;
             }
         }
     }
-    __parent = __tree_.__end_node();
+    __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
     return const_cast<const __node_base_const_pointer&>(__parent->__left_);
 }
 
@@ -1187,20 +1286,16 @@
 {
     __node_allocator& __na = __tree_.__node_alloc();
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
     __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
     return __h;
 }
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 template <class _A0>
-typename enable_if
-<
-    is_constructible<pair<const _Key, _Tp>, _A0>::value,
-    typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
 map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
 {
     __node_allocator& __na = __tree_.__node_alloc();
@@ -1212,19 +1307,14 @@
 }
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
-template <class _A0>
-typename enable_if
-<
-    is_constructible<_Key, _A0>::value,
-    typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
-map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k)
 {
     __node_allocator& __na = __tree_.__node_alloc();
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), _VSTD::forward<_A0>(__a0));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));
     __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
     return __h;
 }
@@ -1248,23 +1338,21 @@
 
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
-map<_Key, _Tp, _Compare, _Allocator>::__construct_node(const key_type& __k)
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)
 {
     __node_allocator& __na = __tree_.__node_alloc();
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
     __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
-    return _VSTD::move(__h);
+    return _VSTD::move(__h);  // explicitly moved for C++03
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 _Tp&
 map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
@@ -1274,11 +1362,11 @@
     __node_pointer __r = static_cast<__node_pointer>(__child);
     if (__child == nullptr)
     {
-        __node_holder __h = __construct_node(__k);
-        __tree_.__insert_node_at(__parent, __child, __h.get());
+        __node_holder __h = __construct_node_with_key(__k);
+        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
         __r = __h.release();
     }
-    return __r->__value_.second;
+    return __r->__value_.__cc.second;
 }
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1292,11 +1380,11 @@
     __node_pointer __r = static_cast<__node_pointer>(__child);
     if (__child == nullptr)
     {
-        __node_holder __h = __construct_node(_VSTD::move(__k));
-        __tree_.__insert_node_at(__parent, __child, __h.get());
+        __node_holder __h = __construct_node_with_key(_VSTD::move(__k));
+        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
         __r = __h.release();
     }
-    return __r->__value_.second;
+    return __r->__value_.__cc.second;
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1311,7 +1399,7 @@
     if (__child == nullptr)
         throw out_of_range("map::at:  key not found");
 #endif  // _LIBCPP_NO_EXCEPTIONS
-    return static_cast<__node_pointer>(__child)->__value_.second;
+    return static_cast<__node_pointer>(__child)->__value_.__cc.second;
 }
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
@@ -1324,7 +1412,7 @@
     if (__child == nullptr)
         throw out_of_range("map::at:  key not found");
 #endif  // _LIBCPP_NO_EXCEPTIONS
-    return static_cast<__node_const_pointer>(__child)->__value_.second;
+    return static_cast<__node_const_pointer>(__child)->__value_.__cc.second;
 }
 
 #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1422,19 +1510,20 @@
 
 template <class _Key, class _Tp, class _Compare = less<_Key>,
           class _Allocator = allocator<pair<const _Key, _Tp> > >
-class _LIBCPP_TYPE_VIS multimap
+class _LIBCPP_TYPE_VIS_ONLY multimap
 {
 public:
     // types:
     typedef _Key                                     key_type;
     typedef _Tp                                      mapped_type;
     typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
     typedef _Compare                                 key_compare;
     typedef _Allocator                               allocator_type;
     typedef value_type&                              reference;
     typedef const value_type&                        const_reference;
 
-    class _LIBCPP_TYPE_VIS value_compare
+    class _LIBCPP_TYPE_VIS_ONLY value_compare
         : public binary_function<value_type, value_type, bool>
     {
         friend class multimap;
@@ -1450,8 +1539,9 @@
     };
 
 private:
-    typedef pair<key_type, mapped_type>                             __value_type;
-    typedef __map_value_compare<key_type, mapped_type, key_compare> __vc;
+
+    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
+    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
     typedef typename allocator_traits<allocator_type>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
             rebind_alloc<__value_type>
@@ -1505,6 +1595,13 @@
             insert(__f, __l);
         }
 
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY 
+    multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+        : multimap(__f, __l, key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     multimap(const multimap& __m)
         : __tree_(__m.__tree_.value_comp(),
@@ -1516,7 +1613,14 @@
     _LIBCPP_INLINE_VISIBILITY
     multimap& operator=(const multimap& __m)
         {
+#if __cplusplus >= 201103L
             __tree_ = __m.__tree_;
+#else
+            __tree_.clear();
+            __tree_.value_comp() = __m.__tree_.value_comp();
+            __tree_.__copy_assign_alloc(__m.__tree_);
+            insert(__m.begin(), __m.end());
+#endif
             return *this;
         }
 
@@ -1557,6 +1661,12 @@
             insert(__il.begin(), __il.end());
         }
 
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    multimap(initializer_list<value_type> __il, const allocator_type& __a)
+        : multimap(__il, key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     multimap& operator=(initializer_list<value_type> __il)
         {
@@ -1692,6 +1802,17 @@
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_multi(__k);}
@@ -1701,18 +1822,51 @@
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
             {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     iterator upper_bound(const key_type& __k)
             {return __tree_.upper_bound(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
             {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator,iterator>             equal_range(const key_type& __k)
             {return __tree_.__equal_range_multi(__k);}
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
             {return __tree_.__equal_range_multi(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
+#endif
 
 private:
     typedef typename __base::__node                    __node;
@@ -1725,18 +1879,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     __node_holder __construct_node();
     template <class _A0>
-        typename enable_if
-        <
-            is_constructible<value_type, _A0>::value,
-            __node_holder
-        >::type
-         __construct_node(_A0&& __a0);
-    template <class _A0>
-        typename enable_if
-        <
-            is_constructible<key_type, _A0>::value,
-            __node_holder
-        >::type
+        __node_holder
          __construct_node(_A0&& __a0);
 #ifndef _LIBCPP_HAS_NO_VARIADICS
     template <class _A0, class _A1, class ..._Args>
@@ -1766,20 +1909,16 @@
 {
     __node_allocator& __na = __tree_.__node_alloc();
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
     __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
     return __h;
 }
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
 template <class _A0>
-typename enable_if
-<
-    is_constructible<pair<const _Key, _Tp>, _A0>::value,
-    typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
+typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
 multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
 {
     __node_allocator& __na = __tree_.__node_alloc();
@@ -1790,24 +1929,6 @@
     return __h;
 }
 
-template <class _Key, class _Tp, class _Compare, class _Allocator>
-template <class _A0>
-typename enable_if
-<
-    is_constructible<_Key, _A0>::value,
-    typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
->::type
-multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
-{
-    __node_allocator& __na = __tree_.__node_alloc();
-    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), _VSTD::forward<_A0>(__a0));
-    __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
-    __h.get_deleter().__second_constructed = true;
-    return __h;
-}
-
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
diff --git a/include/memory b/include/memory
index 912a43f..b382f70 100644
--- a/include/memory
+++ b/include/memory
@@ -90,7 +90,7 @@
     template <class T>
         static void destroy(allocator_type& a, T* p);
 
-    static size_type max_size(const allocator_type& a);
+    static size_type max_size(const allocator_type& a); // noexcept in C++14
 
     static allocator_type
         select_on_container_copy_construction(const allocator_type& a);
@@ -350,6 +350,10 @@
     bad_weak_ptr() noexcept;
 };
 
+template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
+template<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
+template<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
+
 template<class T>
 class shared_ptr
 {
@@ -492,8 +496,8 @@
     long use_count() const noexcept;
     bool expired() const noexcept;
     shared_ptr<T> lock() const noexcept;
-    template<class U> bool owner_before(shared_ptr<U> const& b);
-    template<class U> bool owner_before(weak_ptr<U> const& b);
+    template<class U> bool owner_before(shared_ptr<U> const& b) const;
+    template<class U> bool owner_before(weak_ptr<U> const& b) const;
 };
 
 // weak_ptr specialized algorithms:
@@ -614,60 +618,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// addressof
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_Tp*
-addressof(_Tp& __x) _NOEXCEPT
-{
-    return (_Tp*)&reinterpret_cast<const volatile char&>(__x);
-}
-
-#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)
-// Objective-C++ Automatic Reference Counting uses qualified pointers
-// that require special addressof() signatures. When
-// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
-// itself is providing these definitions. Otherwise, we provide them.
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__strong _Tp*
-addressof(__strong _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-
-#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__weak _Tp*
-addressof(__weak _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-#endif
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__autoreleasing _Tp*
-addressof(__autoreleasing _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__unsafe_unretained _Tp*
-addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
-{
-  return &__x;
-}
-#endif
+// addressof moved to <__functional_base>
 
 template <class _Tp> class allocator;
 
 template <>
-class _LIBCPP_TYPE_VIS allocator<void>
+class _LIBCPP_TYPE_VIS_ONLY allocator<void>
 {
 public:
     typedef void*             pointer;
@@ -678,7 +634,7 @@
 };
 
 template <>
-class _LIBCPP_TYPE_VIS allocator<const void>
+class _LIBCPP_TYPE_VIS_ONLY allocator<const void>
 {
 public:
     typedef const void*       pointer;
@@ -913,7 +869,7 @@
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
 template <class _Ptr>
-struct _LIBCPP_TYPE_VIS pointer_traits
+struct _LIBCPP_TYPE_VIS_ONLY pointer_traits
 {
     typedef _Ptr                                                     pointer;
     typedef typename __pointer_traits_element_type<pointer>::type    element_type;
@@ -936,7 +892,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS pointer_traits<_Tp*>
+struct _LIBCPP_TYPE_VIS_ONLY pointer_traits<_Tp*>
 {
     typedef _Tp*      pointer;
     typedef _Tp       element_type;
@@ -961,13 +917,13 @@
 
 namespace __has_pointer_type_imp
 {
-    template <class _Up> static __two test(...);
-    template <class _Up> static char test(typename _Up::pointer* = 0);
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::pointer* = 0);
 }
 
 template <class _Tp>
 struct __has_pointer_type
-    : public integral_constant<bool, sizeof(__has_pointer_type_imp::test<_Tp>(0)) == 1>
+    : public integral_constant<bool, sizeof(__has_pointer_type_imp::__test<_Tp>(0)) == 1>
 {
 };
 
@@ -1443,7 +1399,7 @@
 };
 
 template <class _Alloc>
-struct _LIBCPP_TYPE_VIS allocator_traits
+struct _LIBCPP_TYPE_VIS_ONLY allocator_traits
 {
     typedef _Alloc                              allocator_type;
     typedef typename allocator_type::value_type value_type;
@@ -1527,7 +1483,7 @@
             {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}
 
     _LIBCPP_INLINE_VISIBILITY
-    static size_type max_size(const allocator_type& __a)
+    static size_type max_size(const allocator_type& __a) _NOEXCEPT
         {return __max_size(__has_max_size<const allocator_type>(), __a);}
 
     _LIBCPP_INLINE_VISIBILITY
@@ -1649,7 +1605,7 @@
 // allocator
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS allocator
+class _LIBCPP_TYPE_VIS_ONLY allocator
 {
 public:
     typedef size_t            size_type;
@@ -1741,7 +1697,7 @@
 };
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS allocator<const _Tp>
+class _LIBCPP_TYPE_VIS_ONLY allocator<const _Tp>
 {
 public:
     typedef size_t            size_type;
@@ -1750,7 +1706,7 @@
     typedef const _Tp*        const_pointer;
     typedef const _Tp&        reference;
     typedef const _Tp&        const_reference;
-    typedef _Tp               value_type;
+    typedef const _Tp         value_type;
 
     typedef true_type propagate_on_container_move_assignment;
 
@@ -1839,7 +1795,7 @@
 bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
 
 template <class _OutputIterator, class _Tp>
-class _LIBCPP_TYPE_VIS raw_storage_iterator
+class _LIBCPP_TYPE_VIS_ONLY raw_storage_iterator
     : public iterator<output_iterator_tag,
                       _Tp,                                         // purposefully not C++03
                       ptrdiff_t,                                   // purposefully not C++03
@@ -1892,7 +1848,7 @@
 };
 
 template<class _Tp>
-class _LIBCPP_TYPE_VIS auto_ptr
+class _LIBCPP_TYPE_VIS_ONLY auto_ptr
 {
 private:
     _Tp* __ptr_;
@@ -1936,7 +1892,7 @@
 };
 
 template <>
-class _LIBCPP_TYPE_VIS auto_ptr<void>
+class _LIBCPP_TYPE_VIS_ONLY auto_ptr<void>
 {
 public:
     typedef void element_type;
@@ -1998,7 +1954,7 @@
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
         : __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
 
-#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
@@ -2017,8 +1973,6 @@
             return *this;
         }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
         _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
@@ -2036,9 +1990,7 @@
             return *this;
         }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
@@ -2095,7 +2047,7 @@
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
         : _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
 
-#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
@@ -2113,8 +2065,6 @@
             return *this;
         }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
         _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
@@ -2131,9 +2081,7 @@
             return *this;
         }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
@@ -2191,7 +2139,7 @@
                    is_nothrow_move_constructible<_T2>::value)
         : _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {}
 
-#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
@@ -2209,8 +2157,6 @@
             return *this;
         }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
         _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
@@ -2227,9 +2173,7 @@
             return *this;
         }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
@@ -2285,7 +2229,7 @@
     _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
         : _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {}
 
-#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
@@ -2303,8 +2247,6 @@
             return *this;
         }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
     _LIBCPP_INLINE_VISIBILITY
     __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
         _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
@@ -2321,9 +2263,7 @@
             return *this;
         }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
@@ -2376,7 +2316,7 @@
     _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)
         : base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {}
 
-#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
     _LIBCPP_INLINE_VISIBILITY
     __compressed_pair(const __compressed_pair& __p)
@@ -2393,7 +2333,6 @@
             return *this;
         }
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
     __compressed_pair(__compressed_pair&& __p)
         _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
@@ -2409,9 +2348,7 @@
             return *this;
         }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
@@ -2472,7 +2409,7 @@
 // default_delete
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS default_delete
+struct _LIBCPP_TYPE_VIS_ONLY default_delete
 {
 #ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;
@@ -2491,7 +2428,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS default_delete<_Tp[]>
+struct _LIBCPP_TYPE_VIS_ONLY default_delete<_Tp[]>
 {
 public:
 #ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
@@ -2514,7 +2451,7 @@
 };
 
 template <class _Tp, class _Dp = default_delete<_Tp> >
-class _LIBCPP_TYPE_VIS unique_ptr
+class _LIBCPP_TYPE_VIS_ONLY unique_ptr
 {
 public:
     typedef _Tp element_type;
@@ -2693,7 +2630,7 @@
 };
 
 template <class _Tp, class _Dp>
-class _LIBCPP_TYPE_VIS unique_ptr<_Tp[], _Dp>
+class _LIBCPP_TYPE_VIS_ONLY unique_ptr<_Tp[], _Dp>
 {
 public:
     typedef _Tp element_type;
@@ -3079,8 +3016,61 @@
 
 #endif
 
+#if _LIBCPP_STD_VER > 11
+
+template<class _Tp>
+struct __unique_if
+{
+    typedef unique_ptr<_Tp> __unique_single;
+};
+
+template<class _Tp>
+struct __unique_if<_Tp[]>
+{
+    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
+};
+
+template<class _Tp, size_t _Np>
+struct __unique_if<_Tp[_Np]>
+{
+    typedef void __unique_array_known_bound;
+};
+
+template<class _Tp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_single
+make_unique(_Args&&... __args)
+{
+    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_array_unknown_bound
+make_unique(size_t __n)
+{
+    typedef typename remove_extent<_Tp>::type _Up;
+    return unique_ptr<_Tp>(new _Up[__n]());
+}
+
+template<class _Tp, class... _Args>
+    typename __unique_if<_Tp>::__unique_array_known_bound
+    make_unique(_Args&&...) = delete;
+
+#endif  // _LIBCPP_STD_VER > 11
+
 template <class _Tp> struct hash;
 
+template <class _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_Size
+__loadword(const void* __p)
+{
+    _Size __r;
+    std::memcpy(&__r, __p, sizeof(__r));
+    return __r;
+}
+
 // We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
 // is 64 bits.  This is because cityhash64 uses 64bit x 64bit
 // multiplication, which can be very slow on 32-bit systems.
@@ -3104,7 +3094,7 @@
     const unsigned char* __data = static_cast<const unsigned char*>(__key);
     for (; __len >= 4; __data += 4, __len -= 4)
     {
-        _Size __k = *(const _Size*)__data;
+        _Size __k = __loadword<_Size>(__data);
         __k *= __m;
         __k ^= __k >> __r;
         __k *= __m;
@@ -3163,13 +3153,13 @@
 
   static _Size __hash_len_0_to_16(const char* __s, _Size __len) {
     if (__len > 8) {
-      const _Size __a = *(const _Size*)__s;
-      const _Size __b = *(const _Size*)(__s + __len - 8);
+      const _Size __a = __loadword<_Size>(__s);
+      const _Size __b = __loadword<_Size>(__s + __len - 8);
       return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;
     }
     if (__len >= 4) {
-      const uint32_t __a = *(const uint32_t*)(__s);
-      const uint32_t __b = *(const uint32_t*)(__s + __len - 4);
+      const uint32_t __a = __loadword<uint32_t>(__s);
+      const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);
       return __hash_len_16(__len + (__a << 3), __b);
     }
     if (__len > 0) {
@@ -3185,10 +3175,10 @@
   }
 
   static _Size __hash_len_17_to_32(const char *__s, _Size __len) {
-    const _Size __a = *(const _Size*)(__s) * __k1;
-    const _Size __b = *(const _Size*)(__s + 8);
-    const _Size __c = *(const _Size*)(__s + __len - 8) * __k2;
-    const _Size __d = *(const _Size*)(__s + __len - 16) * __k0;
+    const _Size __a = __loadword<_Size>(__s) * __k1;
+    const _Size __b = __loadword<_Size>(__s + 8);
+    const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;
+    const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;
     return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,
                          __a + __rotate(__b ^ __k3, 20) - __c + __len);
   }
@@ -3209,33 +3199,33 @@
   // Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.
   static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
       const char* __s, _Size __a, _Size __b) {
-    return __weak_hash_len_32_with_seeds(*(const _Size*)(__s),
-                                         *(const _Size*)(__s + 8),
-                                         *(const _Size*)(__s + 16),
-                                         *(const _Size*)(__s + 24),
+    return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),
+                                         __loadword<_Size>(__s + 8),
+                                         __loadword<_Size>(__s + 16),
+                                         __loadword<_Size>(__s + 24),
                                          __a,
                                          __b);
   }
 
   // Return an 8-byte hash for 33 to 64 bytes.
   static _Size __hash_len_33_to_64(const char *__s, size_t __len) {
-    _Size __z = *(const _Size*)(__s + 24);
-    _Size __a = *(const _Size*)(__s) +
-                (__len + *(const _Size*)(__s + __len - 16)) * __k0;
+    _Size __z = __loadword<_Size>(__s + 24);
+    _Size __a = __loadword<_Size>(__s) +
+                (__len + __loadword<_Size>(__s + __len - 16)) * __k0;
     _Size __b = __rotate(__a + __z, 52);
     _Size __c = __rotate(__a, 37);
-    __a += *(const _Size*)(__s + 8);
+    __a += __loadword<_Size>(__s + 8);
     __c += __rotate(__a, 7);
-    __a += *(const _Size*)(__s + 16);
+    __a += __loadword<_Size>(__s + 16);
     _Size __vf = __a + __z;
     _Size __vs = __b + __rotate(__a, 31) + __c;
-    __a = *(const _Size*)(__s + 16) + *(const _Size*)(__s + __len - 32);
-    __z += *(const _Size*)(__s + __len - 8);
+    __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);
+    __z += __loadword<_Size>(__s + __len - 8);
     __b = __rotate(__a + __z, 52);
     __c = __rotate(__a, 37);
-    __a += *(const _Size*)(__s + __len - 24);
+    __a += __loadword<_Size>(__s + __len - 24);
     __c += __rotate(__a, 7);
-    __a += *(const _Size*)(__s + __len - 16);
+    __a += __loadword<_Size>(__s + __len - 16);
     _Size __wf = __a + __z;
     _Size __ws = __b + __rotate(__a, 31) + __c;
     _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);
@@ -3261,26 +3251,26 @@
 
   // For strings over 64 bytes we hash the end first, and then as we
   // loop we keep 56 bytes of state: v, w, x, y, and z.
-  _Size __x = *(const _Size*)(__s + __len - 40);
-  _Size __y = *(const _Size*)(__s + __len - 16) +
-              *(const _Size*)(__s + __len - 56);
-  _Size __z = __hash_len_16(*(const _Size*)(__s + __len - 48) + __len,
-                          *(const _Size*)(__s + __len - 24));
+  _Size __x = __loadword<_Size>(__s + __len - 40);
+  _Size __y = __loadword<_Size>(__s + __len - 16) +
+              __loadword<_Size>(__s + __len - 56);
+  _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,
+                          __loadword<_Size>(__s + __len - 24));
   pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
   pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
-  __x = __x * __k1 + *(const _Size*)(__s);
+  __x = __x * __k1 + __loadword<_Size>(__s);
 
   // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
   __len = (__len - 1) & ~static_cast<_Size>(63);
   do {
-    __x = __rotate(__x + __y + __v.first + *(const _Size*)(__s + 8), 37) * __k1;
-    __y = __rotate(__y + __v.second + *(const _Size*)(__s + 48), 42) * __k1;
+    __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;
+    __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;
     __x ^= __w.second;
-    __y += __v.first + *(const _Size*)(__s + 40);
+    __y += __v.first + __loadword<_Size>(__s + 40);
     __z = __rotate(__z + __w.first, 33) * __k1;
     __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
     __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
-                                        __y + *(const _Size*)(__s + 16));
+                                        __y + __loadword<_Size>(__s + 16));
     std::swap(__z, __x);
     __s += 64;
     __len -= 64;
@@ -3395,7 +3385,7 @@
 };
 
 template<class _Tp>
-struct _LIBCPP_TYPE_VIS hash<_Tp*>
+struct _LIBCPP_TYPE_VIS_ONLY hash<_Tp*>
     : public unary_function<_Tp*, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -3412,7 +3402,7 @@
 };
 
 template <class _Tp, class _Dp>
-struct _LIBCPP_TYPE_VIS hash<unique_ptr<_Tp, _Dp> >
+struct _LIBCPP_TYPE_VIS_ONLY hash<unique_ptr<_Tp, _Dp> >
 {
     typedef unique_ptr<_Tp, _Dp> argument_type;
     typedef size_t               result_type;
@@ -3585,9 +3575,9 @@
     virtual const char* what() const  _NOEXCEPT;
 };
 
-template<class _Tp> class _LIBCPP_TYPE_VIS weak_ptr;
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY weak_ptr;
 
-class __shared_count
+class _LIBCPP_TYPE_VIS __shared_count
 {
     __shared_count(const __shared_count&);
     __shared_count& operator=(const __shared_count&);
@@ -3609,7 +3599,7 @@
     long use_count() const _NOEXCEPT {return __shared_owners_ + 1;}
 };
 
-class __shared_weak_count
+class _LIBCPP_TYPE_VIS __shared_weak_count
     : private __shared_count
 {
     long __shared_weak_owners_;
@@ -3754,10 +3744,10 @@
     __a.deallocate(this, 1);
 }
 
-template<class _Tp> class _LIBCPP_TYPE_VIS enable_shared_from_this;
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this;
 
 template<class _Tp>
-class _LIBCPP_TYPE_VIS shared_ptr
+class _LIBCPP_TYPE_VIS_ONLY shared_ptr
 {
 public:
     typedef _Tp element_type;
@@ -3886,8 +3876,8 @@
         <
             !is_array<_Yp>::value &&
             is_convertible<_Yp*, element_type*>::value,
-            shared_ptr&
-        >::type
+            shared_ptr
+        >::type&
         operator=(auto_ptr<_Yp>&& __r);
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template<class _Yp>
@@ -4026,8 +4016,8 @@
     _LIBCPP_INLINE_VISIBILITY
     void __enable_weak_this(const void*) _NOEXCEPT {}
 
-    template <class _Up> friend class _LIBCPP_TYPE_VIS shared_ptr;
-    template <class _Up> friend class _LIBCPP_TYPE_VIS weak_ptr;
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr;
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr;
 };
 
 template<class _Tp>
@@ -4513,8 +4503,8 @@
 <
     !is_array<_Yp>::value &&
     is_convertible<_Yp*, _Tp*>::value,
-    shared_ptr<_Tp>&
->::type
+    shared_ptr<_Tp>
+>::type&
 shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
 {
     shared_ptr(_VSTD::move(__r)).swap(*this);
@@ -4923,7 +4913,7 @@
 #endif  // _LIBCPP_NO_RTTI
 
 template<class _Tp>
-class _LIBCPP_TYPE_VIS weak_ptr
+class _LIBCPP_TYPE_VIS_ONLY weak_ptr
 {
 public:
     typedef _Tp element_type;
@@ -4998,8 +4988,8 @@
         bool owner_before(const weak_ptr<_Up>& __r) const
         {return __cntrl_ < __r.__cntrl_;}
 
-    template <class _Up> friend class _LIBCPP_TYPE_VIS weak_ptr;
-    template <class _Up> friend class _LIBCPP_TYPE_VIS shared_ptr;
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr;
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr;
 };
 
 template<class _Tp>
@@ -5199,7 +5189,7 @@
 template <class _Tp> struct owner_less;
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS owner_less<shared_ptr<_Tp> >
+struct _LIBCPP_TYPE_VIS_ONLY owner_less<shared_ptr<_Tp> >
     : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
 {
     typedef bool result_type;
@@ -5215,7 +5205,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS owner_less<weak_ptr<_Tp> >
+struct _LIBCPP_TYPE_VIS_ONLY owner_less<weak_ptr<_Tp> >
     : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
 {
     typedef bool result_type;
@@ -5231,7 +5221,7 @@
 };
 
 template<class _Tp>
-class _LIBCPP_TYPE_VIS enable_shared_from_this
+class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this
 {
     mutable weak_ptr<_Tp> __weak_this_;
 protected:
@@ -5256,7 +5246,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS hash<shared_ptr<_Tp> >
+struct _LIBCPP_TYPE_VIS_ONLY hash<shared_ptr<_Tp> >
 {
     typedef shared_ptr<_Tp>      argument_type;
     typedef size_t               result_type;
@@ -5274,7 +5264,7 @@
 
 #if __has_feature(cxx_atomic)
 
-class __sp_mut
+class _LIBCPP_TYPE_VIS __sp_mut
 {
     void* __lx;
 public:
@@ -5418,11 +5408,11 @@
     operator int() const {return __v_;}
 };
 
-void declare_reachable(void* __p);
-void declare_no_pointers(char* __p, size_t __n);
-void undeclare_no_pointers(char* __p, size_t __n);
-pointer_safety get_pointer_safety() _NOEXCEPT;
-void* __undeclare_reachable(void* __p);
+_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
+_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
+_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
+_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
+_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
 
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -5432,7 +5422,7 @@
     return static_cast<_Tp*>(__undeclare_reachable(__p));
 }
 
-void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
+_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/mutex b/include/mutex
index e2b5d6b..e0c02ad 100644
--- a/include/mutex
+++ b/include/mutex
@@ -441,7 +441,7 @@
 
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
-struct _LIBCPP_TYPE_VIS once_flag
+struct _LIBCPP_TYPE_VIS_ONLY once_flag
 {
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR
@@ -527,7 +527,7 @@
     (*__p)();
 }
 
-void __call_once(volatile unsigned long&, void*, void(*)(void*));
+_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*));
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
diff --git a/include/new b/include/new
index 1e85798..ea4a4a0 100644
--- a/include/new
+++ b/include/new
@@ -27,6 +27,18 @@
     virtual const char* what() const noexcept;
 };
 
+class bad_array_length : public bad_alloc // C++14
+{
+public:
+    bad_array_length() noexcept;
+};
+
+class bad_array_new_length : public bad_alloc
+{
+public:
+    bad_array_new_length() noexcept;
+};
+
 struct nothrow_t {};
 extern const nothrow_t nothrow;
 typedef void (*new_handler)();
@@ -81,7 +93,22 @@
     virtual const char* what() const _NOEXCEPT;
 };
 
-void __throw_bad_alloc();  // not in C++ spec
+#if defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
+
+class _LIBCPP_EXCEPTION_ABI bad_array_length
+    : public bad_alloc
+{
+public:
+    bad_array_length() _NOEXCEPT;
+    virtual ~bad_array_length() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
+
+#endif  // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
+
+_LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec
 
 struct _LIBCPP_TYPE_VIS nothrow_t {};
 extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
@@ -91,27 +118,33 @@
 
 }  // std
 
-_LIBCPP_FUNC_VIS void* operator new(std::size_t __sz)
+#if defined(_WIN32) && !defined(cxx_EXPORTS)
+# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS_ONLY
+#else
+# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS
+#endif
+
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz)
 #if !__has_feature(cxx_noexcept)
     throw(std::bad_alloc)
 #endif
 ;
-_LIBCPP_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
-_LIBCPP_FUNC_VIS void  operator delete(void* __p) _NOEXCEPT;
-_LIBCPP_FUNC_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
 
-_LIBCPP_FUNC_VIS void* operator new[](std::size_t __sz)
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz)
 #if !__has_feature(cxx_noexcept)
     throw(std::bad_alloc)
 #endif
 ;
-_LIBCPP_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
-_LIBCPP_FUNC_VIS void  operator delete[](void* __p) _NOEXCEPT;
-_LIBCPP_FUNC_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
 
-_LIBCPP_INLINE_VISIBILITY inline void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
-_LIBCPP_INLINE_VISIBILITY inline void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
-_LIBCPP_INLINE_VISIBILITY inline void  operator delete  (void*, void*) _NOEXCEPT {}
-_LIBCPP_INLINE_VISIBILITY inline void  operator delete[](void*, void*) _NOEXCEPT {}
+inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
+inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
+inline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}
+inline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {}
 
 #endif  // _LIBCPP_NEW
diff --git a/include/numeric b/include/numeric
index c201a5f..e520c8e 100644
--- a/include/numeric
+++ b/include/numeric
@@ -157,7 +157,7 @@
         {
             typename iterator_traits<_InputIterator>::value_type __t2(*__first);
             *__result = __t2 - __t1;
-            __t1 = __t2;
+            __t1 = _VSTD::move(__t2);
         }
     }
     return __result;
@@ -177,7 +177,7 @@
         {
             typename iterator_traits<_InputIterator>::value_type __t2(*__first);
             *__result = __binary_op(__t2, __t1);
-            __t1 = __t2;
+            __t1 = _VSTD::move(__t2);
         }
     }
     return __result;
diff --git a/include/ostream b/include/ostream
index eac9c8f..041314a 100644
--- a/include/ostream
+++ b/include/ostream
@@ -32,6 +32,7 @@
     virtual ~basic_ostream();
 
     // 27.7.2.3 Assign/swap
+    basic_ostream& operator=(const basic_ostream& rhs) = delete; // C++14
     basic_ostream& operator=(basic_ostream&& rhs);
     void swap(basic_ostream& rhs);
 
@@ -140,7 +141,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_ostream
+class _LIBCPP_TYPE_VIS_ONLY basic_ostream
     : virtual public basic_ios<_CharT, _Traits>
 {
 public:
@@ -161,6 +162,9 @@
 #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);
@@ -169,7 +173,7 @@
 public:
 
     // 27.7.2.4 Prefix/suffix:
-    class _LIBCPP_TYPE_VIS sentry;
+    class _LIBCPP_TYPE_VIS_ONLY sentry;
 
     // 27.7.2.6 Formatted output:
     basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&));
@@ -207,7 +211,7 @@
 };
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_ostream<_CharT, _Traits>::sentry
+class _LIBCPP_TYPE_VIS_ONLY basic_ostream<_CharT, _Traits>::sentry
 {
     bool __ok_;
     basic_ostream<_CharT, _Traits>& __os_;
@@ -1155,7 +1159,8 @@
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
 {
-    if (!this->fail())
+    sentry __s(*this);
+    if (__s)
     {
         if (this->rdbuf()->pubseekpos(__pos, ios_base::out) == pos_type(-1))
             this->setstate(ios_base::failbit);
@@ -1168,8 +1173,12 @@
 basic_ostream<_CharT, _Traits>&
 basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)
 {
-    if (!this->fail())
-        this->rdbuf()->pubseekoff(__off, __dir, ios_base::out);
+    sentry __s(*this);
+    if (__s)
+    {
+        if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::out) == pos_type(-1))
+            this->setstate(ios_base::failbit);
+    }
     return *this;
 }
 
@@ -1278,8 +1287,8 @@
                          use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class basic_ostream<char>)
-_LIBCPP_EXTERN_TEMPLATE(class basic_ostream<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<wchar_t>)
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/queue b/include/queue
index 8d1a9df..bdfd706 100644
--- a/include/queue
+++ b/include/queue
@@ -177,7 +177,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp, class _Container> class _LIBCPP_TYPE_VIS queue;
+template <class _Tp, class _Container> class _LIBCPP_TYPE_VIS_ONLY queue;
 
 template <class _Tp, class _Container>
 _LIBCPP_INLINE_VISIBILITY
@@ -190,7 +190,7 @@
 operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);
 
 template <class _Tp, class _Container = deque<_Tp> >
-class _LIBCPP_TYPE_VIS queue
+class _LIBCPP_TYPE_VIS_ONLY queue
 {
 public:
     typedef _Container                               container_type;
@@ -376,14 +376,14 @@
 }
 
 template <class _Tp, class _Container, class _Alloc>
-struct _LIBCPP_TYPE_VIS uses_allocator<queue<_Tp, _Container>, _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<queue<_Tp, _Container>, _Alloc>
     : public uses_allocator<_Container, _Alloc>
 {
 };
 
 template <class _Tp, class _Container = vector<_Tp>,
           class _Compare = less<typename _Container::value_type> >
-class _LIBCPP_TYPE_VIS priority_queue
+class _LIBCPP_TYPE_VIS_ONLY priority_queue
 {
 public:
     typedef _Container                               container_type;
@@ -707,7 +707,7 @@
 }
 
 template <class _Tp, class _Container, class _Compare, class _Alloc>
-struct _LIBCPP_TYPE_VIS uses_allocator<priority_queue<_Tp, _Container, _Compare>, _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<priority_queue<_Tp, _Container, _Compare>, _Alloc>
     : public uses_allocator<_Container, _Alloc>
 {
 };
diff --git a/include/random b/include/random
index 92722ea..c0db1ab 100644
--- a/include/random
+++ b/include/random
@@ -1813,7 +1813,7 @@
 };
 
 template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
-class _LIBCPP_TYPE_VIS linear_congruential_engine;
+class _LIBCPP_TYPE_VIS_ONLY linear_congruential_engine;
 
 template <class _CharT, class _Traits,
           class _Up, _Up _Ap, _Up _Cp, _Up _Np>
@@ -1829,7 +1829,7 @@
            linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
 
 template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
-class _LIBCPP_TYPE_VIS linear_congruential_engine
+class _LIBCPP_TYPE_VIS_ONLY linear_congruential_engine
 {
 public:
     // types
@@ -1880,7 +1880,7 @@
         seed(_Sseq& __q)
             {__seed(__q, integral_constant<unsigned,
                 1 + (__m == 0 ? (sizeof(result_type) * __CHAR_BIT__ - 1)/32
-                             :  (__m-1) / 0x100000000ull)>());}
+                             :  (__m > 0x100000000ull))>());}
 
     // generating functions
     _LIBCPP_INLINE_VISIBILITY
@@ -1969,37 +1969,10 @@
     uint32_t __ar[__k+3];
     __q.generate(__ar, __ar + __k + 3);
     result_type __s = static_cast<result_type>((__ar[3] +
-                                                (uint64_t)__ar[4] << 32) % __m);
+                                              ((uint64_t)__ar[4] << 32)) % __m);
     __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
 }
 
-template <class _CharT, class _Traits>
-class __save_flags
-{
-    typedef basic_ios<_CharT, _Traits> __stream_type;
-    typedef typename __stream_type::fmtflags fmtflags;
-
-    __stream_type& __stream_;
-    fmtflags       __fmtflags_;
-    _CharT         __fill_;
-
-    __save_flags(const __save_flags&);
-    __save_flags& operator=(const __save_flags&);
-public:
-    _LIBCPP_INLINE_VISIBILITY
-    explicit __save_flags(__stream_type& __stream)
-        : __stream_(__stream),
-          __fmtflags_(__stream.flags()),
-          __fill_(__stream.fill())
-        {}
-    _LIBCPP_INLINE_VISIBILITY
-    ~__save_flags()
-    {
-        __stream_.flags(__fmtflags_);
-        __stream_.fill(__fill_);
-    }
-};
-
 template <class _CharT, class _Traits,
           class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -2038,7 +2011,7 @@
 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
-class _LIBCPP_TYPE_VIS mersenne_twister_engine;
+class _LIBCPP_TYPE_VIS_ONLY mersenne_twister_engine;
 
 template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
           _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
@@ -2080,7 +2053,7 @@
 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
-class _LIBCPP_TYPE_VIS mersenne_twister_engine
+class _LIBCPP_TYPE_VIS_ONLY mersenne_twister_engine
 {
 public:
     // types
@@ -2526,7 +2499,7 @@
 // subtract_with_carry_engine
 
 template<class _UIntType, size_t __w, size_t __s, size_t __r>
-class _LIBCPP_TYPE_VIS subtract_with_carry_engine;
+class _LIBCPP_TYPE_VIS_ONLY subtract_with_carry_engine;
 
 template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
 bool
@@ -2554,7 +2527,7 @@
            subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
 
 template<class _UIntType, size_t __w, size_t __s, size_t __r>
-class _LIBCPP_TYPE_VIS subtract_with_carry_engine
+class _LIBCPP_TYPE_VIS_ONLY subtract_with_carry_engine
 {
 public:
     // types
@@ -2837,7 +2810,7 @@
 // discard_block_engine
 
 template<class _Engine, size_t __p, size_t __r>
-class _LIBCPP_TYPE_VIS discard_block_engine
+class _LIBCPP_TYPE_VIS_ONLY discard_block_engine
 {
     _Engine __e_;
     int     __n_;
@@ -3010,7 +2983,7 @@
 // independent_bits_engine
 
 template<class _Engine, size_t __w, class _UIntType>
-class _LIBCPP_TYPE_VIS independent_bits_engine
+class _LIBCPP_TYPE_VIS_ONLY independent_bits_engine
 {
     template <class _UI, _UI _R0, size_t _Wp, size_t _Mp>
     class __get_n
@@ -3273,7 +3246,7 @@
 };
 
 template<class _Engine, size_t __k>
-class _LIBCPP_TYPE_VIS shuffle_order_engine
+class _LIBCPP_TYPE_VIS_ONLY shuffle_order_engine
 {
     static_assert(0 < __k, "shuffle_order_engine invalid parameters");
 public:
@@ -3502,7 +3475,9 @@
 
 class _LIBCPP_TYPE_VIS random_device
 {
+#if !defined(_WIN32)
     int __f_;
+#endif // defined(_WIN32)
 public:
     // types
     typedef unsigned result_type;
@@ -3534,7 +3509,7 @@
 
 // seed_seq
 
-class _LIBCPP_TYPE_VIS seed_seq
+class _LIBCPP_TYPE_VIS_ONLY seed_seq
 {
 public:
     // types
@@ -3548,7 +3523,7 @@
 public:
     // constructors
     _LIBCPP_INLINE_VISIBILITY
-    seed_seq() {}
+    seed_seq() _NOEXCEPT {}
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     template<class _Tp>
         _LIBCPP_INLINE_VISIBILITY
@@ -3566,7 +3541,7 @@
 
     // property functions
     _LIBCPP_INLINE_VISIBILITY
-    size_t size() const {return __v_.size();}
+    size_t size() const _NOEXCEPT {return __v_.size();}
     template<class _OutputIterator>
         _LIBCPP_INLINE_VISIBILITY
         void param(_OutputIterator __dest) const
@@ -3711,13 +3686,13 @@
 // uniform_real_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS uniform_real_distribution
+class _LIBCPP_TYPE_VIS_ONLY uniform_real_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __a_;
         result_type __b_;
@@ -3832,13 +3807,13 @@
 
 // bernoulli_distribution
 
-class _LIBCPP_TYPE_VIS bernoulli_distribution
+class _LIBCPP_TYPE_VIS_ONLY bernoulli_distribution
 {
 public:
     // types
     typedef bool result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         double __p_;
     public:
@@ -3941,13 +3916,13 @@
 // binomial_distribution
 
 template<class _IntType = int>
-class _LIBCPP_TYPE_VIS binomial_distribution
+class _LIBCPP_TYPE_VIS_ONLY binomial_distribution
 {
 public:
     // types
     typedef _IntType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __t_;
         double __p_;
@@ -4106,13 +4081,13 @@
 // exponential_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS exponential_distribution
+class _LIBCPP_TYPE_VIS_ONLY exponential_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __lambda_;
     public:
@@ -4221,13 +4196,13 @@
 // normal_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS normal_distribution
+class _LIBCPP_TYPE_VIS_ONLY normal_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __mean_;
         result_type __stddev_;
@@ -4389,13 +4364,13 @@
 // lognormal_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS lognormal_distribution
+class _LIBCPP_TYPE_VIS_ONLY lognormal_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         normal_distribution<result_type> __nd_;
     public:
@@ -4514,13 +4489,13 @@
 // poisson_distribution
 
 template<class _IntType = int>
-class _LIBCPP_TYPE_VIS poisson_distribution
+class _LIBCPP_TYPE_VIS_ONLY poisson_distribution
 {
 public:
     // types
     typedef _IntType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         double __mean_;
         double __s_;
@@ -4745,13 +4720,13 @@
 // weibull_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS weibull_distribution
+class _LIBCPP_TYPE_VIS_ONLY weibull_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __a_;
         result_type __b_;
@@ -4859,13 +4834,13 @@
 }
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS extreme_value_distribution
+class _LIBCPP_TYPE_VIS_ONLY extreme_value_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __a_;
         result_type __b_;
@@ -4980,13 +4955,13 @@
 // gamma_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS gamma_distribution
+class _LIBCPP_TYPE_VIS_ONLY gamma_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __alpha_;
         result_type __beta_;
@@ -5152,13 +5127,13 @@
 // negative_binomial_distribution
 
 template<class _IntType = int>
-class _LIBCPP_TYPE_VIS negative_binomial_distribution
+class _LIBCPP_TYPE_VIS_ONLY negative_binomial_distribution
 {
 public:
     // types
     typedef _IntType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __k_;
         double __p_;
@@ -5287,13 +5262,13 @@
 // geometric_distribution
 
 template<class _IntType = int>
-class _LIBCPP_TYPE_VIS geometric_distribution
+class _LIBCPP_TYPE_VIS_ONLY geometric_distribution
 {
 public:
     // types
     typedef _IntType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         double __p_;
     public:
@@ -5389,13 +5364,13 @@
 // chi_squared_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS chi_squared_distribution
+class _LIBCPP_TYPE_VIS_ONLY chi_squared_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __n_;
     public:
@@ -5495,13 +5470,13 @@
 // cauchy_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS cauchy_distribution
+class _LIBCPP_TYPE_VIS_ONLY cauchy_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __a_;
         result_type __b_;
@@ -5618,13 +5593,13 @@
 // fisher_f_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS fisher_f_distribution
+class _LIBCPP_TYPE_VIS_ONLY fisher_f_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __m_;
         result_type __n_;
@@ -5740,13 +5715,13 @@
 // student_t_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS student_t_distribution
+class _LIBCPP_TYPE_VIS_ONLY student_t_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         result_type __n_;
     public:
@@ -5853,13 +5828,13 @@
 // discrete_distribution
 
 template<class _IntType = int>
-class _LIBCPP_TYPE_VIS discrete_distribution
+class _LIBCPP_TYPE_VIS_ONLY discrete_distribution
 {
 public:
     // types
     typedef _IntType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         vector<double> __p_;
     public:
@@ -5928,8 +5903,8 @@
         discrete_distribution(size_t __nw, double __xmin, double __xmax,
                               _UnaryOperation __fw)
         : __p_(__nw, __xmin, __xmax, __fw) {}
-    explicit discrete_distribution(const param_type& __p)
     _LIBCPP_INLINE_VISIBILITY
+    explicit discrete_distribution(const param_type& __p)
         : __p_(__p) {}
     _LIBCPP_INLINE_VISIBILITY
     void reset() {}
@@ -6084,13 +6059,13 @@
 // piecewise_constant_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS piecewise_constant_distribution
+class _LIBCPP_TYPE_VIS_ONLY piecewise_constant_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         vector<result_type> __b_;
         vector<result_type> __densities_;
@@ -6408,13 +6383,13 @@
 // piecewise_linear_distribution
 
 template<class _RealType = double>
-class _LIBCPP_TYPE_VIS piecewise_linear_distribution
+class _LIBCPP_TYPE_VIS_ONLY piecewise_linear_distribution
 {
 public:
     // types
     typedef _RealType result_type;
 
-    class _LIBCPP_TYPE_VIS param_type
+    class _LIBCPP_TYPE_VIS_ONLY param_type
     {
         vector<result_type> __b_;
         vector<result_type> __densities_;
diff --git a/include/ratio b/include/ratio
index f4e741e..48dcd81 100644
--- a/include/ratio
+++ b/include/ratio
@@ -231,7 +231,7 @@
 };
 
 template <intmax_t _Num, intmax_t _Den = 1>
-class _LIBCPP_TYPE_VIS ratio
+class _LIBCPP_TYPE_VIS_ONLY ratio
 {
     static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range");
     static_assert(_Den != 0, "ratio divide by 0");
@@ -292,7 +292,7 @@
 #else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_multiply
+struct _LIBCPP_TYPE_VIS_ONLY ratio_multiply
     : public __ratio_multiply<_R1, _R2>::type {};
 
 #endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
@@ -319,7 +319,7 @@
 #else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_divide
+struct _LIBCPP_TYPE_VIS_ONLY ratio_divide
     : public __ratio_divide<_R1, _R2>::type {};
 
 #endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
@@ -354,7 +354,7 @@
 #else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_add
+struct _LIBCPP_TYPE_VIS_ONLY ratio_add
     : public __ratio_add<_R1, _R2>::type {};
 
 #endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
@@ -389,7 +389,7 @@
 #else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_subtract
+struct _LIBCPP_TYPE_VIS_ONLY ratio_subtract
     : public __ratio_subtract<_R1, _R2>::type {};
 
 #endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
@@ -397,11 +397,11 @@
 // ratio_equal
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_equal
+struct _LIBCPP_TYPE_VIS_ONLY ratio_equal
     : public integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> {};
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_not_equal
+struct _LIBCPP_TYPE_VIS_ONLY ratio_not_equal
     : public integral_constant<bool, !ratio_equal<_R1, _R2>::value> {};
 
 // ratio_less
@@ -460,19 +460,19 @@
 };
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_less
+struct _LIBCPP_TYPE_VIS_ONLY ratio_less
     : public integral_constant<bool, __ratio_less<_R1, _R2>::value> {};
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_less_equal
+struct _LIBCPP_TYPE_VIS_ONLY ratio_less_equal
     : public integral_constant<bool, !ratio_less<_R2, _R1>::value> {};
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_greater
+struct _LIBCPP_TYPE_VIS_ONLY ratio_greater
     : public integral_constant<bool, ratio_less<_R2, _R1>::value> {};
 
 template <class _R1, class _R2>
-struct _LIBCPP_TYPE_VIS ratio_greater_equal
+struct _LIBCPP_TYPE_VIS_ONLY ratio_greater_equal
     : public integral_constant<bool, !ratio_less<_R1, _R2>::value> {};
 
 template <class _R1, class _R2>
diff --git a/include/regex b/include/regex
index d1afa54..ffe39cf 100644
--- a/include/regex
+++ b/include/regex
@@ -925,7 +925,7 @@
 };
 
 template <class _CharT>
-struct _LIBCPP_TYPE_VIS regex_traits
+struct _LIBCPP_TYPE_VIS_ONLY regex_traits
 {
 public:
     typedef _CharT                  char_type;
@@ -970,7 +970,7 @@
     bool isctype(char_type __c, char_class_type __m) const;
     _LIBCPP_INLINE_VISIBILITY
     int value(char_type __ch, int __radix) const
-        {return __value(__ch, __radix);}
+        {return __regex_traits_value(__ch, __radix);}
     locale_type imbue(locale_type __l);
     _LIBCPP_INLINE_VISIBILITY
     locale_type getloc()const {return __loc_;}
@@ -1001,11 +1001,11 @@
         __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
                            bool __icase, wchar_t) const;
 
-    static int __value(unsigned char __ch, int __radix);
+    static int __regex_traits_value(unsigned char __ch, int __radix);
     _LIBCPP_INLINE_VISIBILITY
-    int __value(char __ch, int __radix) const
-        {return __value(static_cast<unsigned char>(__ch), __radix);}
-    int __value(wchar_t __ch, int __radix) const;
+    int __regex_traits_value(char __ch, int __radix) const
+        {return __regex_traits_value(static_cast<unsigned char>(__ch), __radix);}
+    int __regex_traits_value(wchar_t __ch, int __radix) const;
 };
 
 template <class _CharT>
@@ -1100,7 +1100,7 @@
 
 // lookup_collatename is very FreeBSD-specific
 
-string __get_collation_name(const char* __s);
+_LIBCPP_FUNC_VIS string __get_collation_name(const char* __s);
 
 template <class _CharT>
 template <class _ForwardIterator>
@@ -1161,7 +1161,7 @@
 
 // lookup_classname
 
-ctype_base::mask __get_classname(const char* __s, bool __icase);
+ctype_base::mask _LIBCPP_FUNC_VIS __get_classname(const char* __s, bool __icase);
 
 template <class _CharT>
 template <class _ForwardIterator>
@@ -1207,7 +1207,7 @@
 
 template <class _CharT>
 int
-regex_traits<_CharT>::__value(unsigned char __ch, int __radix)
+regex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix)
 {
     if ((__ch & 0xF8u) == 0x30)  // '0' <= __ch && __ch <= '7'
         return __ch - '0';
@@ -1228,18 +1228,18 @@
 template <class _CharT>
 inline _LIBCPP_INLINE_VISIBILITY
 int
-regex_traits<_CharT>::__value(wchar_t __ch, int __radix) const
+regex_traits<_CharT>::__regex_traits_value(wchar_t __ch, int __radix) const
 {
-    return __value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
+    return __regex_traits_value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
 }
 
 template <class _CharT> class __node;
 
-template <class _BidirectionalIterator> class _LIBCPP_TYPE_VIS sub_match;
+template <class _BidirectionalIterator> class _LIBCPP_TYPE_VIS_ONLY sub_match;
 
 template <class _BidirectionalIterator,
           class _Allocator = allocator<sub_match<_BidirectionalIterator> > >
-class _LIBCPP_TYPE_VIS match_results;
+class _LIBCPP_TYPE_VIS_ONLY match_results;
 
 template <class _CharT>
 struct __state
@@ -2014,6 +2014,9 @@
     virtual void __exec(__state&) const;
 };
 
+template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<char>::__exec(__state&) const;
+template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<wchar_t>::__exec(__state&) const;
+
 // __match_char
 
 template <class _CharT>
@@ -2415,7 +2418,7 @@
 template <class _CharT, class _Traits> class __lookahead;
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
-class _LIBCPP_TYPE_VIS basic_regex
+class _LIBCPP_TYPE_VIS_ONLY basic_regex
 {
 public:
     // types:
@@ -2769,7 +2772,7 @@
     void __push_end_marked_subexpression(unsigned);
     void __push_empty();
     void __push_word_boundary(bool);
-    void __push_lookahead(const basic_regex&, bool);
+    void __push_lookahead(const basic_regex&, bool, unsigned);
 
     template <class _Allocator>
         bool
@@ -2843,6 +2846,15 @@
                  const basic_regex<_Cp, _Tp>& __e,
                  regex_constants::match_flag_type __flags);
 
+    template <class _Iter, class _Ap, class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(__wrap_iter<_Iter> __first,
+                 __wrap_iter<_Iter> __last,
+                 match_results<__wrap_iter<_Iter>, _Ap>& __m,
+                 const basic_regex<_Cp, _Tp>& __e,
+                 regex_constants::match_flag_type __flags);
+
     template <class, class> friend class __lookahead;
 };
 
@@ -2898,6 +2910,7 @@
     typedef __owns_one_state<_CharT> base;
 
     basic_regex<_CharT, _Traits> __exp_;
+    unsigned __mexp_;
     bool __invert_;
 
     __lookahead(const __lookahead&);
@@ -2906,8 +2919,8 @@
     typedef _VSTD::__state<_CharT> __state;
 
     _LIBCPP_INLINE_VISIBILITY
-    __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s)
-        : base(__s), __exp_(__exp), __invert_(__invert) {}
+    __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)
+        : base(__s), __exp_(__exp), __invert_(__invert), __mexp_(__mexp) {}
 
     virtual void __exec(__state&) const;
 };
@@ -2921,11 +2934,14 @@
     bool __matched = __exp_.__match_at_start_ecma(__s.__current_, __s.__last_,
                                                   __m,
                                                   __s.__flags_ | regex_constants::match_continuous,
-                                                  true);
+                                                  __s.__at_first_ && __s.__current_ == __s.__first_);
     if (__matched != __invert_)
     {
         __s.__do_ = __state::__accept_but_not_consume;
         __s.__node_ = this->first();
+        for (unsigned __i = 1; __i < __m.size(); ++__i) {
+            __s.__sub_matches_[__mexp_ + __i - 1] = __m.__matches_[__i];
+        }
     }
     else
     {
@@ -3420,6 +3436,7 @@
                 case '+':
                 case '?':
                 case '{':
+                case '}':
                     __push_char(*__temp);
                     __first = ++__temp;
                     break;
@@ -3768,7 +3785,7 @@
                 }
                 __ml->__add_range(_VSTD::move(__start_range), _VSTD::move(__end_range));
             }
-            else
+            else if (!__start_range.empty())
             {
                 if (__start_range.size() == 1)
                     __ml->__add_char(__start_range[0]);
@@ -3776,7 +3793,7 @@
                     __ml->__add_digraph(__start_range[0], __start_range[1]);
             }
         }
-        else
+        else if (!__start_range.empty())
         {
             if (__start_range.size() == 1)
                 __ml->__add_char(__start_range[0]);
@@ -3903,7 +3920,7 @@
         {
             __val = 8 * __val + *__first - '0';
             if (++__first != __last && ('0' <= *__first && *__first <= '7'))
-                __val = 8 * __val + *__first - '0';
+                __val = 8 * __val + *__first++ - '0';
         }
         if (__str)
             *__str = _CharT(__val);
@@ -4158,7 +4175,9 @@
                                 basic_regex __exp;
                                 __exp.__flags_ = __flags_;
                                 __temp = __exp.__parse(++__temp, __last);
-                                __push_lookahead(_VSTD::move(__exp), false);
+                                unsigned __mexp = __exp.__marked_count_;
+                                __push_lookahead(_VSTD::move(__exp), false, __marked_count_);
+                                __marked_count_ += __mexp;
 #ifndef _LIBCPP_NO_EXCEPTIONS
                                 if (__temp == __last || *__temp != ')')
                                     throw regex_error(regex_constants::error_paren);
@@ -4171,7 +4190,9 @@
                                 basic_regex __exp;
                                 __exp.__flags_ = __flags_;
                                 __temp = __exp.__parse(++__temp, __last);
-                                __push_lookahead(_VSTD::move(__exp), true);
+                                unsigned __mexp = __exp.__marked_count_;
+                                __push_lookahead(_VSTD::move(__exp), true, __marked_count_);
+                                __marked_count_ += __mexp;
 #ifndef _LIBCPP_NO_EXCEPTIONS
                                 if (__temp == __last || *__temp != ')')
                                     throw regex_error(regex_constants::error_paren);
@@ -4408,7 +4429,8 @@
         case 'c':
             if ((__t = _VSTD::next(__first)) != __last)
             {
-                if ('A' <= *__t <= 'Z' || 'a' <= *__t <= 'z')
+                if (('A' <= *__t && *__t <= 'Z') || 
+                    ('a' <= *__t && *__t <= 'z'))
                 {
                     if (__str)
                         *__str = _CharT(*__t % 32);
@@ -4416,7 +4438,15 @@
                         __push_char(_CharT(*__t % 32));
                     __first = ++__t;
                 }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                else 
+                    throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
             }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            else
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
             break;
         case 'u':
             ++__first;
@@ -4481,7 +4511,7 @@
                 ++__first;
             }
 #ifndef _LIBCPP_NO_EXCEPTIONS
-            else if (__str)
+            else
                 throw regex_error(regex_constants::error_escape);
 #endif  // _LIBCPP_NO_EXCEPTIONS
             break;
@@ -4740,10 +4770,11 @@
 template <class _CharT, class _Traits>
 void
 basic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp,
-                                               bool __invert)
+                                               bool __invert,
+                                               unsigned __mexp)
 {
     __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert,
-                                                           __end_->first());
+                                                           __end_->first(), __mexp);
     __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
 }
 
@@ -4753,7 +4784,7 @@
 // sub_match
 
 template <class _BidirectionalIterator>
-class _LIBCPP_TYPE_VIS sub_match
+class _LIBCPP_TYPE_VIS_ONLY sub_match
     : public pair<_BidirectionalIterator, _BidirectionalIterator>
 {
 public:
@@ -5176,7 +5207,7 @@
 }
 
 template <class _BidirectionalIterator, class _Allocator>
-class _LIBCPP_TYPE_VIS match_results
+class _LIBCPP_TYPE_VIS_ONLY match_results
 {
 public:
     typedef _Allocator                                        allocator_type;
@@ -5763,7 +5794,8 @@
 {
     __m.__init(1 + mark_count(), __first, __last,
                                     __flags & regex_constants::__no_update_pos);
-    if (__match_at_start(__first, __last, __m, __flags, true))
+    if (__match_at_start(__first, __last, __m, __flags, 
+                                    !(__flags & regex_constants::__no_update_pos)))
     {
         __m.__prefix_.second = __m[0].first;
         __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
@@ -5800,9 +5832,25 @@
              const basic_regex<_CharT, _Traits>& __e,
              regex_constants::match_flag_type __flags = regex_constants::match_default)
 {
-    basic_string<_CharT> __s(__first, __last);
+    int __offset = (__flags & regex_constants::match_prev_avail) ? 1 : 0;
+    basic_string<_CharT> __s(_VSTD::prev(__first, __offset), __last);
     match_results<const _CharT*> __mc;
-    bool __r = __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
+    bool __r = __e.__search(__s.data() + __offset, __s.data() + __s.size(), __mc, __flags);
+    __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);
+    return __r;
+}
+
+template <class _Iter, class _Allocator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(__wrap_iter<_Iter> __first,
+             __wrap_iter<_Iter> __last,
+             match_results<__wrap_iter<_Iter>, _Allocator>& __m,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    match_results<const _CharT*> __mc;
+    bool __r = __e.__search(__first.base(), __last.base(), __mc, __flags);
     __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);
     return __r;
 }
@@ -5962,7 +6010,7 @@
 template <class _BidirectionalIterator,
           class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
           class _Traits = regex_traits<_CharT> >
-class _LIBCPP_TYPE_VIS regex_iterator
+class _LIBCPP_TYPE_VIS_ONLY regex_iterator
 {
 public:
     typedef basic_regex<_CharT, _Traits>          regex_type;
@@ -6044,7 +6092,7 @@
 {
     __flags_ |= regex_constants::__no_update_pos;
     _BidirectionalIterator __start = __match_[0].second;
-    if (__match_.length() == 0)
+    if (__match_.empty())
     {
         if (__start == __end_)
         {
@@ -6074,7 +6122,7 @@
 template <class _BidirectionalIterator,
           class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
           class _Traits = regex_traits<_CharT> >
-class _LIBCPP_TYPE_VIS regex_token_iterator
+class _LIBCPP_TYPE_VIS_ONLY regex_token_iterator
 {
 public:
     typedef basic_regex<_CharT, _Traits>      regex_type;
diff --git a/include/scoped_allocator b/include/scoped_allocator
index 9253234..aa8bece 100644
--- a/include/scoped_allocator
+++ b/include/scoped_allocator
@@ -365,7 +365,7 @@
 };
 
 template <class _OuterAlloc, class... _InnerAllocs>
-class _LIBCPP_TYPE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
+class _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
     : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
 {
     typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
diff --git a/include/set b/include/set
index 11ea965..a537c5f 100644
--- a/include/set
+++ b/include/set
@@ -66,6 +66,11 @@
     set(initializer_list<value_type> il, const value_compare& comp = value_compare());
     set(initializer_list<value_type> il, const value_compare& comp,
         const allocator_type& a);
+    template <class InputIterator>
+        set(InputIterator first, InputIterator last, const allocator_type& a)
+            : set(first, last, Compare(), a) {}  // C++14
+    set(initializer_list<value_type> il, const allocator_type& a)
+        : set(il, Compare(), a) {}  // C++14
     ~set();
 
     set& operator=(const set& s);
@@ -129,13 +134,33 @@
     // set operations:
           iterator find(const key_type& k);
     const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+    template<typename K>
+      size_type count(const K& x) const;        // C++14
+
     size_type      count(const key_type& k) const;
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
           iterator upper_bound(const key_type& k);
     const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
     pair<iterator,iterator>             equal_range(const key_type& k);
     pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
 };
 
 template <class Key, class Compare, class Allocator>
@@ -222,6 +247,11 @@
     multiset(initializer_list<value_type> il, const value_compare& comp = value_compare());
     multiset(initializer_list<value_type> il, const value_compare& comp,
              const allocator_type& a);
+    template <class InputIterator>
+        multiset(InputIterator first, InputIterator last, const allocator_type& a)
+            : set(first, last, Compare(), a) {}  // C++14
+    multiset(initializer_list<value_type> il, const allocator_type& a)
+        : set(il, Compare(), a) {}  // C++14
     ~multiset();
 
     multiset& operator=(const multiset& s);
@@ -285,13 +315,32 @@
     // set operations:
           iterator find(const key_type& k);
     const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+
     size_type      count(const key_type& k) const;
           iterator lower_bound(const key_type& k);
     const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
           iterator upper_bound(const key_type& k);
     const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
+
     pair<iterator,iterator>             equal_range(const key_type& k);
     pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
 };
 
 template <class Key, class Compare, class Allocator>
@@ -346,7 +395,7 @@
 
 template <class _Key, class _Compare = less<_Key>,
           class _Allocator = allocator<_Key> >
-class _LIBCPP_TYPE_VIS set
+class _LIBCPP_TYPE_VIS_ONLY set
 {
 public:
     // types:
@@ -403,6 +452,13 @@
             insert(__f, __l);
         }
 
+#if _LIBCPP_STD_VER > 11
+        template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY 
+        set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+            : set(__f, __l, key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     set(const set& __s)
         : __tree_(__s.__tree_)
@@ -455,6 +511,12 @@
             insert(__il.begin(), __il.end());
         }
 
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    set(initializer_list<value_type> __il, const allocator_type& __a)
+        : set(__il, key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     set& operator=(initializer_list<value_type> __il)
         {
@@ -579,6 +641,17 @@
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_unique(__k);}
@@ -588,18 +661,51 @@
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
         {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     iterator upper_bound(const key_type& __k)
         {return __tree_.upper_bound(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
         {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator,iterator> equal_range(const key_type& __k)
         {return __tree_.__equal_range_unique(__k);}
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
         {return __tree_.__equal_range_unique(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_unique(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
+#endif
 };
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -685,7 +791,7 @@
 
 template <class _Key, class _Compare = less<_Key>,
           class _Allocator = allocator<_Key> >
-class _LIBCPP_TYPE_VIS multiset
+class _LIBCPP_TYPE_VIS_ONLY multiset
 {
 public:
     // types:
@@ -734,6 +840,13 @@
             insert(__f, __l);
         }
 
+#if _LIBCPP_STD_VER > 11
+        template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY 
+        multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+            : multiset(__f, __l, key_compare(), __a) {}
+#endif
+
     template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         multiset(_InputIterator __f, _InputIterator __l,
@@ -793,6 +906,12 @@
             insert(__il.begin(), __il.end());
         }
 
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    multiset(initializer_list<value_type> __il, const allocator_type& __a)
+        : multiset(__il, key_compare(), __a) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     multiset& operator=(initializer_list<value_type> __il)
         {
@@ -917,27 +1036,72 @@
     iterator find(const key_type& __k)             {return __tree_.find(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     size_type      count(const key_type& __k) const
         {return __tree_.__count_multi(__k);}
+
     _LIBCPP_INLINE_VISIBILITY
     iterator lower_bound(const key_type& __k)
         {return __tree_.lower_bound(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator lower_bound(const key_type& __k) const
             {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     iterator upper_bound(const key_type& __k)
             {return __tree_.upper_bound(__k);}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator upper_bound(const key_type& __k) const
             {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator,iterator>             equal_range(const key_type& __k)
             {return __tree_.__equal_range_multi(__k);}
     _LIBCPP_INLINE_VISIBILITY
     pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
             {return __tree_.__equal_range_multi(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
+#endif
 };
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
diff --git a/include/shared_mutex b/include/shared_mutex
new file mode 100644
index 0000000..5b1f53a
--- /dev/null
+++ b/include/shared_mutex
@@ -0,0 +1,419 @@
+// -*- C++ -*-
+//===------------------------ shared_mutex --------------------------------===//
+//
+//                     The 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_SHARED_MUTEX
+#define _LIBCPP_SHARED_MUTEX
+
+/*
+    shared_mutex synopsis
+
+// C++1y
+
+namespace std
+{
+
+class shared_mutex
+{
+public:
+    shared_mutex();
+    ~shared_mutex();
+
+    shared_mutex(const shared_mutex&) = delete;
+    shared_mutex& operator=(const shared_mutex&) = delete;
+
+    // Exclusive ownership
+    void lock(); // blocking
+    bool try_lock();
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+
+    // Shared ownership
+    void lock_shared(); // blocking
+    bool try_lock_shared();
+    template <class Rep, class Period>
+        bool
+        try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool
+        try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock_shared();
+};
+
+template <class Mutex>
+class shared_lock
+{
+public:
+    typedef Mutex mutex_type;
+
+    // Shared locking
+    shared_lock() noexcept;
+    explicit shared_lock(mutex_type& m); // blocking
+    shared_lock(mutex_type& m, defer_lock_t) noexcept;
+    shared_lock(mutex_type& m, try_to_lock_t);
+    shared_lock(mutex_type& m, adopt_lock_t);
+    template <class Clock, class Duration>
+        shared_lock(mutex_type& m,
+                    const chrono::time_point<Clock, Duration>& abs_time);
+    template <class Rep, class Period>
+        shared_lock(mutex_type& m,
+                    const chrono::duration<Rep, Period>& rel_time);
+    ~shared_lock();
+
+    shared_lock(shared_lock const&) = delete;
+    shared_lock& operator=(shared_lock const&) = delete;
+
+    shared_lock(shared_lock&& u) noexcept;
+    shared_lock& operator=(shared_lock&& u) noexcept;
+
+    void lock(); // blocking
+    bool try_lock();
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+
+    // Setters
+    void swap(shared_lock& u) noexcept;
+    mutex_type* release() noexcept;
+
+    // Getters
+    bool owns_lock() const noexcept;
+    explicit operator bool () const noexcept;
+    mutex_type* mutex() const noexcept;
+};
+
+template <class Mutex>
+    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
+
+}  // std
+
+*/
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX)
+
+#include <__mutex_base>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS shared_mutex
+{
+    mutex               __mut_;
+    condition_variable  __gate1_;
+    condition_variable  __gate2_;
+    unsigned            __state_;
+
+    static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
+    static const unsigned __n_readers_ = ~__write_entered_;
+public:
+    shared_mutex();
+    _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;
+
+    shared_mutex(const shared_mutex&) = delete;
+    shared_mutex& operator=(const shared_mutex&) = delete;
+
+    // Exclusive ownership
+    void lock();
+    bool try_lock();
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        bool
+        try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
+        {
+            return try_lock_until(chrono::steady_clock::now() + __rel_time);
+        }
+    template <class _Clock, class _Duration>
+        bool
+        try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
+    void unlock();
+
+    // Shared ownership
+    void lock_shared();
+    bool try_lock_shared();
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        bool
+        try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
+        {
+            return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
+        }
+    template <class _Clock, class _Duration>
+        bool
+        try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
+    void unlock_shared();
+};
+
+template <class _Clock, class _Duration>
+bool
+shared_mutex::try_lock_until(
+                        const chrono::time_point<_Clock, _Duration>& __abs_time)
+{
+    unique_lock<mutex> __lk(__mut_);
+    if (__state_ & __write_entered_)
+    {
+        while (true)
+        {
+            cv_status __status = __gate1_.wait_until(__lk, __abs_time);
+            if ((__state_ & __write_entered_) == 0)
+                break;
+            if (__status == cv_status::timeout)
+                return false;
+        }
+    }
+    __state_ |= __write_entered_;
+    if (__state_ & __n_readers_)
+    {
+        while (true)
+        {
+            cv_status __status = __gate2_.wait_until(__lk, __abs_time);
+            if ((__state_ & __n_readers_) == 0)
+                break;
+            if (__status == cv_status::timeout)
+            {
+                __state_ &= ~__write_entered_;
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+template <class _Clock, class _Duration>
+bool
+shared_mutex::try_lock_shared_until(
+                        const chrono::time_point<_Clock, _Duration>& __abs_time)
+{
+    unique_lock<mutex> __lk(__mut_);
+    if ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+    {
+        while (true)
+        {
+            cv_status status = __gate1_.wait_until(__lk, __abs_time);
+            if ((__state_ & __write_entered_) == 0 &&
+                                       (__state_ & __n_readers_) < __n_readers_)
+                break;
+            if (status == cv_status::timeout)
+                return false;
+        }
+    }
+    unsigned __num_readers = (__state_ & __n_readers_) + 1;
+    __state_ &= ~__n_readers_;
+    __state_ |= __num_readers;
+    return true;
+}
+
+template <class _Mutex>
+class shared_lock
+{
+public:
+    typedef _Mutex mutex_type;
+
+private:
+    mutex_type* __m_;
+    bool __owns_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock() noexcept
+        : __m_(nullptr),
+          __owns_(false)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit shared_lock(mutex_type& __m)
+        : __m_(&__m),
+          __owns_(true)
+        {__m_->lock_shared();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(mutex_type& __m, defer_lock_t) noexcept
+        : __m_(&__m),
+          __owns_(false)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(mutex_type& __m, try_to_lock_t)
+        : __m_(&__m),
+          __owns_(__m.try_lock_shared())
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(mutex_type& __m, adopt_lock_t)
+        : __m_(&__m),
+          __owns_(true)
+        {}
+
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        shared_lock(mutex_type& __m,
+                    const chrono::time_point<_Clock, _Duration>& __abs_time)
+            : __m_(&__m),
+              __owns_(__m.try_lock_shared_until(__abs_time))
+            {}
+
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        shared_lock(mutex_type& __m,
+                    const chrono::duration<_Rep, _Period>& __rel_time)
+            : __m_(&__m),
+              __owns_(__m.try_lock_shared_for(__rel_time))
+            {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~shared_lock()
+    {
+        if (__owns_)
+            __m_->unlock_shared();
+    }
+
+    shared_lock(shared_lock const&) = delete;
+    shared_lock& operator=(shared_lock const&) = delete;
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(shared_lock&& __u) noexcept
+        : __m_(__u.__m_),
+          __owns_(__u.__owns_)
+        {
+            __u.__m_ = nullptr;
+            __u.__owns_ = false;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock& operator=(shared_lock&& __u) noexcept
+    {
+        if (__owns_)
+            __m_->unlock_shared();
+        __m_ = nullptr;
+        __owns_ = false;
+        __m_ = __u.__m_;
+        __owns_ = __u.__owns_;
+        __u.__m_ = nullptr;
+        __u.__owns_ = false;
+        return *this;
+    }
+
+    void lock();
+    bool try_lock();
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+
+    // Setters
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(shared_lock& __u) noexcept
+    {
+        _VSTD::swap(__m_, __u.__m_);
+        _VSTD::swap(__owns_, __u.__owns_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    mutex_type* release() noexcept
+    {
+        mutex_type* __m = __m_;
+        __m_ = nullptr;
+        __owns_ = false;
+        return __m;
+    }
+
+    // Getters
+    _LIBCPP_INLINE_VISIBILITY
+    bool owns_lock() const noexcept {return __owns_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit operator bool () const noexcept {return __owns_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    mutex_type* mutex() const noexcept {return __m_;}
+};
+
+template <class _Mutex>
+void
+shared_lock<_Mutex>::lock()
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::lock: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::lock: already locked");
+    __m_->lock_shared();
+    __owns_ = true;
+}
+
+template <class _Mutex>
+bool
+shared_lock<_Mutex>::try_lock()
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked");
+    __owns_ = __m_->try_lock_shared();
+    return __owns_;
+}
+
+template <class _Mutex>
+template <class _Rep, class _Period>
+bool
+shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked");
+    __owns_ = __m_->try_lock_shared_for(__d);
+    return __owns_;
+}
+
+template <class _Mutex>
+template <class _Clock, class _Duration>
+bool
+shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked");
+    __owns_ = __m_->try_lock_shared_until(__t);
+    return __owns_;
+}
+
+template <class _Mutex>
+void
+shared_lock<_Mutex>::unlock()
+{
+    if (!__owns_)
+        __throw_system_error(EPERM, "shared_lock::unlock: not locked");
+    __m_->unlock_shared();
+    __owns_ = false;
+}
+
+template <class _Mutex>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) noexcept
+    {__x.swap(__y);}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STD_VER > 11
+
+#endif  // _LIBCPP_SHARED_MUTEX
diff --git a/include/sstream b/include/sstream
index a8f8148..f90d446 100644
--- a/include/sstream
+++ b/include/sstream
@@ -186,7 +186,7 @@
 // basic_stringbuf
 
 template <class _CharT, class _Traits, class _Allocator>
-class _LIBCPP_TYPE_VIS basic_stringbuf
+class _LIBCPP_TYPE_VIS_ONLY basic_stringbuf
     : public basic_streambuf<_CharT, _Traits>
 {
 public:
@@ -613,7 +613,7 @@
 // basic_istringstream
 
 template <class _CharT, class _Traits, class _Allocator>
-class _LIBCPP_TYPE_VIS basic_istringstream
+class _LIBCPP_TYPE_VIS_ONLY basic_istringstream
     : public basic_istream<_CharT, _Traits>
 {
 public:
@@ -732,7 +732,7 @@
 // basic_ostringstream
 
 template <class _CharT, class _Traits, class _Allocator>
-class _LIBCPP_TYPE_VIS basic_ostringstream
+class _LIBCPP_TYPE_VIS_ONLY basic_ostringstream
     : public basic_ostream<_CharT, _Traits>
 {
 public:
@@ -851,7 +851,7 @@
 // basic_stringstream
 
 template <class _CharT, class _Traits, class _Allocator>
-class _LIBCPP_TYPE_VIS basic_stringstream
+class _LIBCPP_TYPE_VIS_ONLY basic_stringstream
     : public basic_iostream<_CharT, _Traits>
 {
 public:
diff --git a/include/stack b/include/stack
index b8a7f4c..30909c1 100644
--- a/include/stack
+++ b/include/stack
@@ -91,7 +91,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp, class _Container> class _LIBCPP_TYPE_VIS stack;
+template <class _Tp, class _Container> class _LIBCPP_TYPE_VIS_ONLY stack;
 
 template <class _Tp, class _Container>
 _LIBCPP_INLINE_VISIBILITY
@@ -104,7 +104,7 @@
 operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
 
 template <class _Tp, class _Container = deque<_Tp> >
-class _LIBCPP_TYPE_VIS stack
+class _LIBCPP_TYPE_VIS_ONLY stack
 {
 public:
     typedef _Container                               container_type;
@@ -282,7 +282,7 @@
 }
 
 template <class _Tp, class _Container, class _Alloc>
-struct _LIBCPP_TYPE_VIS uses_allocator<stack<_Tp, _Container>, _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<stack<_Tp, _Container>, _Alloc>
     : public uses_allocator<_Container, _Alloc>
 {
 };
diff --git a/include/streambuf b/include/streambuf
index 8261594..6adfc92 100644
--- a/include/streambuf
+++ b/include/streambuf
@@ -119,7 +119,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _CharT, class _Traits>
-class _LIBCPP_TYPE_VIS basic_streambuf
+class _LIBCPP_TYPE_VIS_ONLY basic_streambuf
 {
 public:
     // types:
@@ -553,11 +553,11 @@
     return traits_type::eof();
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class basic_streambuf<char>)
-_LIBCPP_EXTERN_TEMPLATE(class basic_streambuf<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<wchar_t>)
 
-_LIBCPP_EXTERN_TEMPLATE(class basic_ios<char>)
-_LIBCPP_EXTERN_TEMPLATE(class basic_ios<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<wchar_t>)
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/string b/include/string
index 85eb463..e8bd69f 100644
--- a/include/string
+++ b/include/string
@@ -100,8 +100,8 @@
         noexcept(is_nothrow_move_constructible<allocator_type>::value);
     basic_string(const basic_string& str, size_type pos, size_type n = npos,
                  const allocator_type& a = allocator_type());
-    basic_string(const_pointer s, const allocator_type& a = allocator_type());
-    basic_string(const_pointer s, size_type n, const allocator_type& a = allocator_type());
+    basic_string(const value_type* s, const allocator_type& a = allocator_type());
+    basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
     basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
     template<class InputIterator>
         basic_string(InputIterator begin, InputIterator end,
@@ -117,7 +117,7 @@
         noexcept(
              allocator_type::propagate_on_container_move_assignment::value &&
              is_nothrow_move_assignable<allocator_type>::value);
-    basic_string& operator=(const_pointer s);
+    basic_string& operator=(const value_type* s);
     basic_string& operator=(value_type c);
     basic_string& operator=(initializer_list<value_type>);
 
@@ -156,14 +156,14 @@
     reference       at(size_type n);
 
     basic_string& operator+=(const basic_string& str);
-    basic_string& operator+=(const_pointer s);
+    basic_string& operator+=(const value_type* s);
     basic_string& operator+=(value_type c);
     basic_string& operator+=(initializer_list<value_type>);
 
     basic_string& append(const basic_string& str);
     basic_string& append(const basic_string& str, size_type pos, size_type n);
-    basic_string& append(const_pointer s, size_type n);
-    basic_string& append(const_pointer s);
+    basic_string& append(const value_type* s, size_type n);
+    basic_string& append(const value_type* s);
     basic_string& append(size_type n, value_type c);
     template<class InputIterator>
         basic_string& append(InputIterator first, InputIterator last);
@@ -179,8 +179,8 @@
     basic_string& assign(const basic_string& str);
     basic_string& assign(basic_string&& str);
     basic_string& assign(const basic_string& str, size_type pos, size_type n);
-    basic_string& assign(const_pointer s, size_type n);
-    basic_string& assign(const_pointer s);
+    basic_string& assign(const value_type* s, size_type n);
+    basic_string& assign(const value_type* s);
     basic_string& assign(size_type n, value_type c);
     template<class InputIterator>
         basic_string& assign(InputIterator first, InputIterator last);
@@ -189,8 +189,8 @@
     basic_string& insert(size_type pos1, const basic_string& str);
     basic_string& insert(size_type pos1, const basic_string& str,
                          size_type pos2, size_type n);
-    basic_string& insert(size_type pos, const_pointer s, size_type n);
-    basic_string& insert(size_type pos, const_pointer s);
+    basic_string& insert(size_type pos, const value_type* s, size_type n);
+    basic_string& insert(size_type pos, const value_type* s);
     basic_string& insert(size_type pos, size_type n, value_type c);
     iterator      insert(const_iterator p, value_type c);
     iterator      insert(const_iterator p, size_type n, value_type c);
@@ -205,66 +205,66 @@
     basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
     basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
                           size_type pos2, size_type n2);
-    basic_string& replace(size_type pos, size_type n1, const_pointer s, size_type n2);
-    basic_string& replace(size_type pos, size_type n1, const_pointer s);
+    basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);
+    basic_string& replace(size_type pos, size_type n1, const value_type* s);
     basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);
     basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
-    basic_string& replace(const_iterator i1, const_iterator i2, const_pointer s, size_type n);
-    basic_string& replace(const_iterator i1, const_iterator i2, const_pointer s);
+    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n);
+    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);
     basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);
     template<class InputIterator>
         basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
     basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);
 
-    size_type copy(pointer s, size_type n, size_type pos = 0) const;
+    size_type copy(value_type* s, size_type n, size_type pos = 0) const;
     basic_string substr(size_type pos = 0, size_type n = npos) const;
 
     void swap(basic_string& str)
         noexcept(!allocator_type::propagate_on_container_swap::value ||
                  __is_nothrow_swappable<allocator_type>::value)
 
-    const_pointer c_str() const noexcept;
-    const_pointer data() const noexcept;
+    const value_type* c_str() const noexcept;
+    const value_type* data() const noexcept;
 
     allocator_type get_allocator() const noexcept;
 
     size_type find(const basic_string& str, size_type pos = 0) const noexcept;
-    size_type find(const_pointer s, size_type pos, size_type n) const noexcept;
-    size_type find(const_pointer s, size_type pos = 0) const noexcept;
+    size_type find(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find(const value_type* s, size_type pos = 0) const noexcept;
     size_type find(value_type c, size_type pos = 0) const noexcept;
 
     size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
-    size_type rfind(const_pointer s, size_type pos, size_type n) const noexcept;
-    size_type rfind(const_pointer s, size_type pos = npos) const noexcept;
+    size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
     size_type rfind(value_type c, size_type pos = npos) const noexcept;
 
     size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
-    size_type find_first_of(const_pointer s, size_type pos, size_type n) const noexcept;
-    size_type find_first_of(const_pointer s, size_type pos = 0) const noexcept;
+    size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;
     size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
 
     size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
-    size_type find_last_of(const_pointer s, size_type pos, size_type n) const noexcept;
-    size_type find_last_of(const_pointer s, size_type pos = npos) const noexcept;
+    size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
     size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
 
     size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
-    size_type find_first_not_of(const_pointer s, size_type pos, size_type n) const noexcept;
-    size_type find_first_not_of(const_pointer s, size_type pos = 0) const noexcept;
+    size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;
     size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
 
     size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
-    size_type find_last_not_of(const_pointer s, size_type pos, size_type n) const noexcept;
-    size_type find_last_not_of(const_pointer s, size_type pos = npos) const noexcept;
+    size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
     size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
 
     int compare(const basic_string& str) const noexcept;
     int compare(size_type pos1, size_type n1, const basic_string& str) const;
     int compare(size_type pos1, size_type n1, const basic_string& str,
                 size_type pos2, size_type n2) const;
-    int compare(const_pointer s) const noexcept;
-    int compare(size_type pos1, size_type n1, const_pointer s) const;
-    int compare(size_type pos1, size_type n1, const_pointer s, size_type n2) const;
+    int compare(const value_type* s) const noexcept;
+    int compare(size_type pos1, size_type n1, const value_type* s) const;
+    int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;
 
     bool __invariants() const;
 };
@@ -422,6 +422,11 @@
 template <> struct hash<u32string>;
 template <> struct hash<wstring>;
 
+basic_string<char>     operator "" s( const char *str,     size_t len ); // C++14
+basic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len ); // C++14
+basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14
+basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14
+
 }  // std
 
 */
@@ -442,7 +447,7 @@
 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
 #include <cstdint>
 #endif
-#if defined(_LIBCPP_NO_EXCEPTIONS) || defined(_LIBCPP_DEBUG)
+#if defined(_LIBCPP_NO_EXCEPTIONS)
 #include <cassert>
 #endif
 
@@ -457,7 +462,7 @@
 // fpos
 
 template <class _StateT>
-class _LIBCPP_TYPE_VIS fpos
+class _LIBCPP_TYPE_VIS_ONLY fpos
 {
 private:
     _StateT __st_;
@@ -494,7 +499,7 @@
 // char_traits
 
 template <class _CharT>
-struct _LIBCPP_TYPE_VIS char_traits
+struct _LIBCPP_TYPE_VIS_ONLY char_traits
 {
     typedef _CharT    char_type;
     typedef int       int_type;
@@ -600,6 +605,7 @@
 _CharT*
 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     char_type* __r = __s1;
     for (; __n; --__n, ++__s1, ++__s2)
         assign(*__s1, *__s2);
@@ -620,7 +626,7 @@
 // char_traits<char>
 
 template <>
-struct _LIBCPP_TYPE_VIS char_traits<char>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<char>
 {
     typedef char      char_type;
     typedef int       int_type;
@@ -651,7 +657,10 @@
         {return (char_type*)memmove(__s1, __s2, __n);}
     _LIBCPP_INLINE_VISIBILITY
     static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
-        {return (char_type*)memcpy(__s1, __s2, __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)
         {return (char_type*)memset(__s, to_int_type(__a), __n);}
@@ -676,7 +685,7 @@
 // char_traits<wchar_t>
 
 template <>
-struct _LIBCPP_TYPE_VIS char_traits<wchar_t>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t>
 {
     typedef wchar_t   char_type;
     typedef wint_t    int_type;
@@ -708,7 +717,10 @@
         {return (char_type*)wmemmove(__s1, __s2, __n);}
     _LIBCPP_INLINE_VISIBILITY
     static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
-        {return (char_type*)wmemcpy(__s1, __s2, __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)
         {return (char_type*)wmemset(__s, __a, __n);}
@@ -733,7 +745,7 @@
 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
 
 template <>
-struct _LIBCPP_TYPE_VIS char_traits<char16_t>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t>
 {
     typedef char16_t       char_type;
     typedef uint_least16_t int_type;
@@ -836,6 +848,7 @@
 char16_t*
 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     char_type* __r = __s1;
     for (; __n; --__n, ++__s1, ++__s2)
         assign(*__s1, *__s2);
@@ -853,7 +866,7 @@
 }
 
 template <>
-struct _LIBCPP_TYPE_VIS char_traits<char32_t>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t>
 {
     typedef char32_t       char_type;
     typedef uint_least32_t int_type;
@@ -956,6 +969,7 @@
 char32_t*
 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     char_type* __r = __s1;
     for (; __n; --__n, ++__s1, ++__s2)
         assign(*__s1, *__s2);
@@ -998,7 +1012,7 @@
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
 
 template <bool>
-class __basic_string_common
+class _LIBCPP_TYPE_VIS_ONLY __basic_string_common
 {
 protected:
     void __throw_length_error() const;
@@ -1027,14 +1041,14 @@
 #endif
 }
 
-#ifdef _MSC_VER
+#ifdef _LIBCPP_MSVC
 #pragma warning( push )
 #pragma warning( disable: 4231 )
-#endif // _MSC_VER
-_LIBCPP_EXTERN_TEMPLATE(class __basic_string_common<true>)
-#ifdef _MSC_VER
+#endif // _LIBCPP_MSVC
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __basic_string_common<true>)
+#ifdef _LIBCPP_MSVC
 #pragma warning( pop )
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVC
 
 #ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT
 
@@ -1052,7 +1066,7 @@
 #endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
 
 template<class _CharT, class _Traits, class _Allocator>
-class _LIBCPP_TYPE_VIS basic_string
+class _LIBCPP_TYPE_VIS_ONLY basic_string
     : private __basic_string_common<true>
 {
 public:
@@ -1067,13 +1081,13 @@
     typedef const value_type&                            const_reference;
     typedef typename __alloc_traits::pointer             pointer;
     typedef typename __alloc_traits::const_pointer       const_pointer;
-#ifdef _LIBCPP_DEBUG
-    typedef __debug_iter<basic_string, pointer>          iterator;
-    typedef __debug_iter<basic_string, const_pointer>    const_iterator;
 
-    friend class __debug_iter<basic_string, pointer>;
-    friend class __debug_iter<basic_string, const_pointer>;
-#elif defined(_LIBCPP_RAW_ITERATORS)
+    static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD");
+    static_assert((is_same<_CharT, value_type>::value),
+                  "traits_type::char_type must be the same type as CharT");
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+#if defined(_LIBCPP_RAW_ITERATORS)
     typedef pointer                                      iterator;
     typedef const_pointer                                const_iterator;
 #else  // defined(_LIBCPP_RAW_ITERATORS)
@@ -1147,9 +1161,9 @@
 
 #endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
 
-    union __lx{__long __lx; __short __lxx;};
+    union __ulx{__long __lx; __short __lxx;};
 
-    enum {__n_words = sizeof(__lx) / sizeof(size_type)};
+    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
 
     struct __raw
     {
@@ -1168,15 +1182,6 @@
 
     __compressed_pair<__rep, allocator_type> __r_;
 
-#ifdef _LIBCPP_DEBUG
-
-    pair<iterator*, const_iterator*> __iterator_list_;
-
-    _LIBCPP_INLINE_VISIBILITY iterator*&       __get_iterator_list(iterator*)       {return __iterator_list_.first;}
-    _LIBCPP_INLINE_VISIBILITY const_iterator*& __get_iterator_list(const_iterator*) {return __iterator_list_.second;}
-
-#endif  // _LIBCPP_DEBUG
-
 public:
     static const size_type npos = -1;
 
@@ -1192,13 +1197,13 @@
     _LIBCPP_INLINE_VISIBILITY
     basic_string(basic_string&& __str, const allocator_type& __a);
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    _LIBCPP_INLINE_VISIBILITY basic_string(const_pointer __s);
+    _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(const_pointer __s, const allocator_type& __a);
+    basic_string(const value_type* __s, const allocator_type& __a);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(const_pointer __s, size_type __n);
+    basic_string(const value_type* __s, size_type __n);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string(const_pointer __s, size_type __n, const allocator_type& __a);
+    basic_string(const value_type* __s, size_type __n, const allocator_type& __a);
     _LIBCPP_INLINE_VISIBILITY
     basic_string(size_type __n, value_type __c);
     _LIBCPP_INLINE_VISIBILITY
@@ -1227,32 +1232,40 @@
         _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
                    is_nothrow_move_assignable<allocator_type>::value);
 #endif
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const_pointer __s) {return assign(__s);}
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
     basic_string& operator=(value_type __c);
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     _LIBCPP_INLINE_VISIBILITY
     basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
-#ifndef _LIBCPP_DEBUG
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    iterator begin() _NOEXCEPT
+        {return iterator(this, __get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT
+        {return const_iterator(this, __get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator end() _NOEXCEPT
+        {return iterator(this, __get_pointer() + size());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT
+        {return const_iterator(this, __get_pointer() + size());}
+#else
     _LIBCPP_INLINE_VISIBILITY
     iterator begin() _NOEXCEPT
         {return iterator(__get_pointer());}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator begin() const _NOEXCEPT
-        {return const_iterator(data());}
+        {return const_iterator(__get_pointer());}
     _LIBCPP_INLINE_VISIBILITY
     iterator end() _NOEXCEPT
         {return iterator(__get_pointer() + size());}
     _LIBCPP_INLINE_VISIBILITY
     const_iterator end() const _NOEXCEPT
-        {return const_iterator(data() + size());}
-#else  // _LIBCPP_DEBUG
-    _LIBCPP_INLINE_VISIBILITY iterator       begin()       {return iterator(this, __get_pointer());}
-    _LIBCPP_INLINE_VISIBILITY const_iterator begin() const {return const_iterator(this, data());}
-    _LIBCPP_INLINE_VISIBILITY iterator       end()         {return iterator(this, __get_pointer() + size());}
-    _LIBCPP_INLINE_VISIBILITY const_iterator end() const   {return const_iterator(this, data() + size());}
-#endif  // _LIBCPP_DEBUG
+        {return const_iterator(__get_pointer() + size());}
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_INLINE_VISIBILITY
     reverse_iterator rbegin() _NOEXCEPT
         {return reverse_iterator(end());}
@@ -1303,7 +1316,7 @@
     reference       at(size_type __n);
 
     _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
-    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const_pointer __s)         {return append(__s);}
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s)         {return append(__s);}
     _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c)            {push_back(__c); return *this;}
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
@@ -1312,8 +1325,8 @@
     _LIBCPP_INLINE_VISIBILITY
     basic_string& append(const basic_string& __str);
     basic_string& append(const basic_string& __str, size_type __pos, size_type __n);
-    basic_string& append(const_pointer __s, size_type __n);
-    basic_string& append(const_pointer __s);
+    basic_string& append(const value_type* __s, size_type __n);
+    basic_string& append(const value_type* __s);
     basic_string& append(size_type __n, value_type __c);
     template<class _InputIterator>
         typename enable_if
@@ -1351,8 +1364,8 @@
         {*this = _VSTD::move(str); return *this;}
 #endif
     basic_string& assign(const basic_string& __str, size_type __pos, size_type __n);
-    basic_string& assign(const_pointer __s, size_type __n);
-    basic_string& assign(const_pointer __s);
+    basic_string& assign(const value_type* __s, size_type __n);
+    basic_string& assign(const value_type* __s);
     basic_string& assign(size_type __n, value_type __c);
     template<class _InputIterator>
         typename enable_if
@@ -1377,8 +1390,8 @@
     _LIBCPP_INLINE_VISIBILITY
     basic_string& insert(size_type __pos1, const basic_string& __str);
     basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n);
-    basic_string& insert(size_type __pos, const_pointer __s, size_type __n);
-    basic_string& insert(size_type __pos, const_pointer __s);
+    basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
+    basic_string& insert(size_type __pos, const value_type* __s);
     basic_string& insert(size_type __pos, size_type __n, value_type __c);
     iterator      insert(const_iterator __pos, value_type __c);
     _LIBCPP_INLINE_VISIBILITY
@@ -1413,15 +1426,15 @@
     _LIBCPP_INLINE_VISIBILITY
     basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
     basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2);
-    basic_string& replace(size_type __pos, size_type __n1, const_pointer __s, size_type __n2);
-    basic_string& replace(size_type __pos, size_type __n1, const_pointer __s);
+    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
+    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
     basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
     _LIBCPP_INLINE_VISIBILITY
     basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string& replace(const_iterator __i1, const_iterator __i2, const_pointer __s, size_type __n);
+    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
     _LIBCPP_INLINE_VISIBILITY
-    basic_string& replace(const_iterator __i1, const_iterator __i2, const_pointer __s);
+    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
     _LIBCPP_INLINE_VISIBILITY
     basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
     template<class _InputIterator>
@@ -1437,7 +1450,7 @@
         {return replace(__i1, __i2, __il.begin(), __il.end());}
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
-    size_type copy(pointer __s, size_type __n, size_type __pos = 0) const;
+    size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
     _LIBCPP_INLINE_VISIBILITY
     basic_string substr(size_type __pos = 0, size_type __n = npos) const;
 
@@ -1447,56 +1460,56 @@
                    __is_nothrow_swappable<allocator_type>::value);
 
     _LIBCPP_INLINE_VISIBILITY
-    const_pointer c_str() const _NOEXCEPT {return data();}
+    const value_type* c_str() const _NOEXCEPT {return data();}
     _LIBCPP_INLINE_VISIBILITY
-    const_pointer data() const _NOEXCEPT  {return __get_pointer();}
+    const value_type* data() const _NOEXCEPT  {return _VSTD::__to_raw_pointer(__get_pointer());}
 
     _LIBCPP_INLINE_VISIBILITY
     allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
 
     _LIBCPP_INLINE_VISIBILITY
     size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
-    size_type find(const_pointer __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
-    size_type find(const_pointer __s, size_type __pos = 0) const _NOEXCEPT;
+    size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
     size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
-    size_type rfind(const_pointer __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
-    size_type rfind(const_pointer __s, size_type __pos = npos) const _NOEXCEPT;
+    size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
     size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
-    size_type find_first_of(const_pointer __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
-    size_type find_first_of(const_pointer __s, size_type __pos = 0) const _NOEXCEPT;
+    size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
-    size_type find_last_of(const_pointer __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
-    size_type find_last_of(const_pointer __s, size_type __pos = npos) const _NOEXCEPT;
+    size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
-    size_type find_first_not_of(const_pointer __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
-    size_type find_first_not_of(const_pointer __s, size_type __pos = 0) const _NOEXCEPT;
+    size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
-    size_type find_last_not_of(const_pointer __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
-    size_type find_last_not_of(const_pointer __s, size_type __pos = npos) const _NOEXCEPT;
+    size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
 
@@ -1505,9 +1518,9 @@
     _LIBCPP_INLINE_VISIBILITY
     int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
     int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const;
-    int compare(const_pointer __s) const _NOEXCEPT;
-    int compare(size_type __pos1, size_type __n1, const_pointer __s) const;
-    int compare(size_type __pos1, size_type __n1, const_pointer __s, size_type __n2) const;
+    int compare(const value_type* __s) const _NOEXCEPT;
+    int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
+    int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
 
     _LIBCPP_INLINE_VISIBILITY bool __invariants() const;
 
@@ -1515,6 +1528,15 @@
     bool __is_long() const _NOEXCEPT
         {return bool(__r_.first().__s.__size_ & __short_mask);}
 
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 private:
     _LIBCPP_INLINE_VISIBILITY
     allocator_type& __alloc() _NOEXCEPT
@@ -1589,10 +1611,10 @@
         {return __r_.first().__l.__data_;}
     _LIBCPP_INLINE_VISIBILITY
     pointer __get_short_pointer() _NOEXCEPT
-        {return __r_.first().__s.__data_;}
+        {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
     _LIBCPP_INLINE_VISIBILITY
     const_pointer __get_short_pointer() const _NOEXCEPT
-        {return __r_.first().__s.__data_;}
+        {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
     _LIBCPP_INLINE_VISIBILITY
     pointer __get_pointer() _NOEXCEPT
         {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
@@ -1610,17 +1632,17 @@
 
     template <size_type __a> static
         _LIBCPP_INLINE_VISIBILITY
-        size_type __align(size_type __s) _NOEXCEPT
+        size_type __align_it(size_type __s) _NOEXCEPT
             {return __s + (__a-1) & ~(__a-1);}
     enum {__alignment = 16};
     static _LIBCPP_INLINE_VISIBILITY
     size_type __recommend(size_type __s) _NOEXCEPT
         {return (__s < __min_cap ? __min_cap :
-                 __align<sizeof(value_type) < __alignment ?
+                 __align_it<sizeof(value_type) < __alignment ?
                             __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
 
-    void __init(const_pointer __s, size_type __sz, size_type __reserve);
-    void __init(const_pointer __s, size_type __sz);
+    void __init(const value_type* __s, size_type __sz, size_type __reserve);
+    void __init(const value_type* __s, size_type __sz);
     void __init(size_type __n, value_type __c);
 
     template <class _InputIterator>
@@ -1644,7 +1666,7 @@
                    size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
     void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
                                size_type __n_copy,  size_type __n_del,
-                               size_type __n_add, const_pointer __p_new_stuff);
+                               size_type __n_add, const value_type* __p_new_stuff);
 
     _LIBCPP_INLINE_VISIBILITY
     void __erase_to_end(size_type __pos);
@@ -1727,81 +1749,70 @@
 };
 
 template <class _CharT, class _Traits, class _Allocator>
-#ifndef _LIBCPP_DEBUG
-_LIBCPP_INLINE_VISIBILITY inline
-#endif
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
 {
-#ifdef _LIBCPP_DEBUG
-    iterator::__remove_all(this);
-    const_iterator::__remove_all(this);
-#endif  // _LIBCPP_DEBUG
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__invalidate_all(this);
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-#ifndef _LIBCPP_DEBUG
-_LIBCPP_INLINE_VISIBILITY inline
-#endif
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
-#ifdef _LIBCPP_DEBUG
+#if _LIBCPP_DEBUG_LEVEL >= 2
                                                                         __pos
 #endif
                                                                       )
 {
-#ifdef _LIBCPP_DEBUG
-    const_iterator __beg = begin();
-    if (__iterator_list_.first)
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    if (__c)
     {
-        for (iterator* __p = __iterator_list_.first; __p;)
+        const_pointer __new_last = __get_pointer() + __pos;
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
         {
-            if (*__p - __beg > static_cast<difference_type>(__pos))
+            --__p;
+            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+            if (__i->base() > __new_last)
             {
-                iterator* __n = __p;
-                __p = __p->__next;
-                __n->__remove_owner();
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
             }
-            else
-                __p = __p->__next;
         }
+        __get_db()->unlock();
     }
-    if (__iterator_list_.second)
-    {
-        for (const_iterator* __p = __iterator_list_.second; __p;)
-        {
-            if (*__p - __beg > static_cast<difference_type>(__pos))
-            {
-                const_iterator* __n = __p;
-                __p = __p->__next;
-                __n->__remove_owner();
-            }
-            else
-                __p = __p->__next;
-        }
-    }
-#endif  // _LIBCPP_DEBUG
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string()
     _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __zero();
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
     : __r_(__a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __zero();
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 void
-basic_string<_CharT, _Traits, _Allocator>::__init(const_pointer __s, size_type __sz, size_type __reserve)
+basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve)
 {
     if (__reserve > max_size())
         this->__throw_length_error();
@@ -1819,13 +1830,13 @@
         __set_long_cap(__cap+1);
         __set_long_size(__sz);
     }
-    traits_type::copy(__p, __s, __sz);
+    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
     traits_type::assign(__p[__sz], value_type());
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 void
-basic_string<_CharT, _Traits, _Allocator>::__init(const_pointer __s, size_type __sz)
+basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
 {
     if (__sz > max_size())
         this->__throw_length_error();
@@ -1843,50 +1854,54 @@
         __set_long_cap(__cap+1);
         __set_long_size(__sz);
     }
-    traits_type::copy(__p, __s, __sz);
+    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
     traits_type::assign(__p[__sz], value_type());
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s)
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
     __init(__s, traits_type::length(__s));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s, const allocator_type& __a)
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
     : __r_(__a)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
     __init(__s, traits_type::length(__s));
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s, size_type __n)
-{
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
 #endif
-    __init(__s, __n);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
-basic_string<_CharT, _Traits, _Allocator>::basic_string(const_pointer __s, size_type __n, const allocator_type& __a)
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
+    __init(__s, __n);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
     : __r_(__a)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
     __init(__s, __n);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1896,7 +1911,10 @@
     if (!__str.__is_long())
         __r_.first().__r = __str.__r_.first().__r;
     else
-        __init(__str.__get_long_pointer(), __str.__get_long_size());
+        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1906,35 +1924,42 @@
     if (!__str.__is_long())
         __r_.first().__r = __str.__r_.first().__r;
     else
-        __init(__str.__get_long_pointer(), __str.__get_long_size());
+        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
     : __r_(_VSTD::move(__str.__r_))
 {
     __str.__zero();
-#ifdef _LIBCPP_DEBUG
-    __str.__invalidate_all_iterators();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    if (__is_long())
+        __get_db()->swap(this, &__str);
 #endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
     : __r_(__a)
 {
     if (__a == __str.__alloc() || !__str.__is_long())
         __r_.first().__r = __str.__r_.first().__r;
     else
-        __init(__str.__get_long_pointer(), __str.__get_long_size());
+        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
     __str.__zero();
-#ifdef _LIBCPP_DEBUG
-    __str.__invalidate_all_iterators();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    if (__is_long())
+        __get_db()->swap(this, &__str);
 #endif
 }
 
@@ -1960,23 +1985,29 @@
         __set_long_cap(__cap+1);
         __set_long_size(__n);
     }
-    traits_type::assign(__p, __n, __c);
+    traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c);
     traits_type::assign(__p[__n], value_type());
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
 {
     __init(__n, __c);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
     : __r_(__a)
 {
     __init(__n, __c);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1988,6 +2019,9 @@
     if (__pos > __str_sz)
         this->__throw_out_of_range();
     __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2051,37 +2085,49 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
 {
     __init(__first, __last);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 template<class _InputIterator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
                                                         const allocator_type& __a)
     : __r_(__a)
 {
     __init(__first, __last);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
 {
     __init(__il.begin(), __il.end());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
     : __r_(__a)
 {
     __init(__il.begin(), __il.end());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2089,7 +2135,9 @@
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>::~basic_string()
 {
-    __invalidate_all_iterators();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__erase_c(this);
+#endif
     if (__is_long())
         __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
 }
@@ -2098,7 +2146,7 @@
 void
 basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
     (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
-     size_type __n_copy,  size_type __n_del,     size_type __n_add, const_pointer __p_new_stuff)
+     size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)
 {
     size_type __ms = max_size();
     if (__delta_cap > __ms - __old_cap - 1)
@@ -2110,12 +2158,14 @@
     pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
     __invalidate_all_iterators();
     if (__n_copy != 0)
-        traits_type::copy(__p, __old_p, __n_copy);
+        traits_type::copy(_VSTD::__to_raw_pointer(__p),
+                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
     if (__n_add != 0)
-        traits_type::copy(__p + __n_copy, __p_new_stuff, __n_add);
+        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add);
     size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
     if (__sec_cp_sz != 0)
-        traits_type::copy(__p + __n_copy + __n_add, __old_p + __n_copy + __n_del, __sec_cp_sz);
+        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
+                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz);
     if (__old_cap+1 != __min_cap)
         __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
     __set_long_pointer(__p);
@@ -2131,7 +2181,7 @@
                                                      size_type __n_copy,  size_type __n_del,     size_type __n_add)
 {
     size_type __ms = max_size();
-    if (__delta_cap > __ms - __old_cap - 1)
+    if (__delta_cap > __ms - __old_cap)
         this->__throw_length_error();
     pointer __old_p = __get_pointer();
     size_type __cap = __old_cap < __ms / 2 - __alignment ?
@@ -2140,10 +2190,13 @@
     pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
     __invalidate_all_iterators();
     if (__n_copy != 0)
-        traits_type::copy(__p, __old_p, __n_copy);
+        traits_type::copy(_VSTD::__to_raw_pointer(__p),
+                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
     size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
     if (__sec_cp_sz != 0)
-        traits_type::copy(__p + __n_copy + __n_add, __old_p + __n_copy + __n_del, __sec_cp_sz);
+        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
+                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del,
+                          __sec_cp_sz);
     if (__old_cap+1 != __min_cap)
         __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
     __set_long_pointer(__p);
@@ -2154,15 +2207,13 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::assign(const_pointer __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign recieved nullptr");
     size_type __cap = capacity();
     if (__cap >= __n)
     {
-        pointer __p = __get_pointer();
+        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
         traits_type::move(__p, __s, __n);
         traits_type::assign(__p[__n], value_type());
         __set_size(__n);
@@ -2188,7 +2239,7 @@
     }
     else
         __invalidate_iterators_past(__n);
-    pointer __p = __get_pointer();
+    value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
     traits_type::assign(__p, __n, __c);
     traits_type::assign(__p[__n], value_type());
     __set_size(__n);
@@ -2231,7 +2282,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
 {
@@ -2242,7 +2293,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
     _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
@@ -2255,7 +2306,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
     _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
@@ -2311,7 +2362,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str)
 {
@@ -2330,11 +2381,9 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::assign(const_pointer __s)
+basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::assign recieved nullptr");
     return assign(__s, traits_type::length(__s));
 }
 
@@ -2342,18 +2391,16 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::append(const_pointer __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append recieved nullptr");
     size_type __cap = capacity();
     size_type __sz = size();
     if (__cap - __sz >= __n)
     {
         if (__n)
         {
-            pointer __p = __get_pointer();
+            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
             traits_type::copy(__p + __sz, __s, __n);
             __sz += __n;
             __set_size(__sz);
@@ -2376,7 +2423,7 @@
         if (__cap - __sz < __n)
             __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
         pointer __p = __get_pointer();
-        traits_type::assign(__p + __sz, __n, __c);
+        traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c);
         __sz += __n;
         __set_size(__sz);
         traits_type::assign(__p[__sz], value_type());
@@ -2462,7 +2509,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
 {
@@ -2481,11 +2528,9 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::append(const_pointer __s)
+basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::append recieved nullptr");
     return append(__s, traits_type::length(__s));
 }
 
@@ -2493,11 +2538,9 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const_pointer __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert recieved nullptr");
     size_type __sz = size();
     if (__pos > __sz)
         this->__throw_out_of_range();
@@ -2506,7 +2549,7 @@
     {
         if (__n)
         {
-            pointer __p = __get_pointer();
+            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
             size_type __n_move = __sz - __pos;
             if (__n_move != 0)
             {
@@ -2535,10 +2578,10 @@
     if (__n)
     {
         size_type __cap = capacity();
-        pointer __p;
+        value_type* __p;
         if (__cap - __sz >= __n)
         {
-            __p = __get_pointer();
+            __p = _VSTD::__to_raw_pointer(__get_pointer());
             size_type __n_move = __sz - __pos;
             if (__n_move != 0)
                 traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
@@ -2546,7 +2589,7 @@
         else
         {
             __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
-            __p = __get_long_pointer();
+            __p = _VSTD::__to_raw_pointer(__get_long_pointer());
         }
         traits_type::assign(__p + __pos, __n, __c);
         __sz += __n;
@@ -2566,13 +2609,22 @@
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, range) called with an iterator not"
+        " referring to this string");
+#endif
     size_type __old_sz = size();
     difference_type __ip = __pos - begin();
     for (; __first != __last; ++__first)
         push_back(*__first);
     pointer __p = __get_pointer();
     _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(this, __p + __ip);
+#else
     return iterator(__p + __ip);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2584,16 +2636,21 @@
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, range) called with an iterator not"
+        " referring to this string");
+#endif
     size_type __ip = static_cast<size_type>(__pos - begin());
     size_type __sz = size();
     size_type __cap = capacity();
     size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
     if (__n)
     {
-        pointer __p;
+        value_type* __p;
         if (__cap - __sz >= __n)
         {
-            __p = __get_pointer();
+            __p = _VSTD::__to_raw_pointer(__get_pointer());
             size_type __n_move = __sz - __ip;
             if (__n_move != 0)
                 traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
@@ -2601,7 +2658,7 @@
         else
         {
             __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
-            __p = __get_long_pointer();
+            __p = _VSTD::__to_raw_pointer(__get_long_pointer());
         }
         __sz += __n;
         __set_size(__sz);
@@ -2613,7 +2670,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
 {
@@ -2633,11 +2690,9 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const_pointer __s)
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::insert recieved nullptr");
     return insert(__pos, __s, traits_type::length(__s));
 }
 
@@ -2648,15 +2703,15 @@
     size_type __ip = static_cast<size_type>(__pos - begin());
     size_type __sz = size();
     size_type __cap = capacity();
-    pointer __p;
+    value_type* __p;
     if (__cap == __sz)
     {
         __grow_by(__cap, 1, __sz, __ip, 0, 1);
-        __p = __get_long_pointer();
+        __p = _VSTD::__to_raw_pointer(__get_long_pointer());
     }
     else
     {
-        __p = __get_pointer();
+        __p = _VSTD::__to_raw_pointer(__get_pointer());
         size_type __n_move = __sz - __ip;
         if (__n_move != 0)
             traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
@@ -2668,10 +2723,15 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, n, value) called with an iterator not"
+        " referring to this string");
+#endif
     difference_type __p = __pos - begin();
     insert(static_cast<size_type>(__p), __n, __c);
     return begin() + __p;
@@ -2681,11 +2741,9 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const_pointer __s, size_type __n2)
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace recieved nullptr");
     size_type __sz = size();
     if (__pos > __sz)
         this->__throw_out_of_range();
@@ -2693,7 +2751,7 @@
     size_type __cap = capacity();
     if (__cap - __sz + __n1 >= __n2)
     {
-        pointer __p = __get_pointer();
+        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
         if (__n1 != __n2)
         {
             size_type __n_move = __sz - __pos - __n1;
@@ -2742,10 +2800,10 @@
         this->__throw_out_of_range();
     __n1 = _VSTD::min(__n1, __sz - __pos);
     size_type __cap = capacity();
-    pointer __p;
+    value_type* __p;
     if (__cap - __sz + __n1 >= __n2)
     {
-        __p = __get_pointer();
+        __p = _VSTD::__to_raw_pointer(__get_pointer());
         if (__n1 != __n2)
         {
             size_type __n_move = __sz - __pos - __n1;
@@ -2756,7 +2814,7 @@
     else
     {
         __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
-        __p = __get_long_pointer();
+        __p = _VSTD::__to_raw_pointer(__get_long_pointer());
     }
     traits_type::assign(__p + __pos, __n2, __c);
     __sz += __n2 - __n1;
@@ -2795,7 +2853,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
 {
@@ -2815,16 +2873,14 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const_pointer __s)
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::replace recieved nullptr");
     return replace(__pos, __n1, __s, traits_type::length(__s));
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
 {
@@ -2833,23 +2889,23 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const_pointer __s, size_type __n)
+basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
 {
     return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const_pointer __s)
+basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
 {
     return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
 {
@@ -2867,7 +2923,7 @@
         this->__throw_out_of_range();
     if (__n)
     {
-        pointer __p = __get_pointer();
+        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
         __n = _VSTD::min(__n, __sz - __pos);
         size_type __n_move = __sz - __pos - __n;
         if (__n_move != 0)
@@ -2881,10 +2937,17 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::erase(iterator) called with an iterator not"
+        " referring to this string");
+#endif
+    _LIBCPP_ASSERT(__pos != end(),
+        "string::erase(iterator) called with a non-dereferenceable iterator");
     iterator __b = begin();
     size_type __r = static_cast<size_type>(__pos - __b);
     erase(__r, 1);
@@ -2892,10 +2955,16 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+        "string::erase(iterator,  iterator) called with an iterator not"
+        " referring to this string");
+#endif
+    _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
     iterator __b = begin();
     size_type __r = static_cast<size_type>(__first - __b);
     erase(__r, static_cast<size_type>(__last - __first));
@@ -2903,13 +2972,11 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::pop_back()
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
     size_type __sz;
     if (__is_long())
     {
@@ -2927,7 +2994,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
 {
@@ -2945,7 +3012,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
 {
@@ -2974,15 +3041,15 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
 {
     size_type __m = __alloc_traits::max_size(__alloc());
 #if _LIBCPP_BIG_ENDIAN
-    return (__m <= ~__long_mask ? __m : __m/2) - 1;
+    return (__m <= ~__long_mask ? __m : __m/2) - __alignment;
 #else
-    return __m - 1;
+    return __m - __alignment;
 #endif
 }
 
@@ -3025,7 +3092,7 @@
                     return;
                 }
             #else  // _LIBCPP_NO_EXCEPTIONS
-                if (__new_data == 0)
+                if (__new_data == nullptr)
                     return;
             #endif  // _LIBCPP_NO_EXCEPTIONS
             }
@@ -3033,7 +3100,8 @@
             __was_long = __is_long();
             __p = __get_pointer();
         }
-        traits_type::copy(__new_data, __p, size()+1);
+        traits_type::copy(_VSTD::__to_raw_pointer(__new_data),
+                          _VSTD::__to_raw_pointer(__p), size()+1);
         if (__was_long)
             __alloc_traits::deallocate(__alloc(), __p, __cap+1);
         if (__now_long)
@@ -3049,24 +3117,20 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const
 {
-#ifdef __LIBCPP_DEBUG
-    assert(__pos <= size());
-#endif
+    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
     return *(data() + __pos);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos)
 {
-#ifdef __LIBCPP_DEBUG
-    assert(__pos < size());
-#endif
+    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
     return *(__get_pointer() + __pos);
 }
 
@@ -3089,52 +3153,44 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::front()
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
     return *__get_pointer();
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::front() const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
     return *data();
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::back()
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
     return *(__get_pointer() + size() - 1);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::back() const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
     return *(data() + size() - 1);
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::copy(pointer __s, size_type __n, size_type __pos) const
+basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
 {
     size_type __sz = size();
     if (__pos > __sz)
@@ -3145,7 +3201,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
 {
@@ -3153,18 +3209,21 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
         _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<allocator_type>::value)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    if (!__is_long())
+        __get_db()->__invalidate_all(this);
+    if (!__str.__is_long())
+        __get_db()->__invalidate_all(&__str);
+    __get_db()->swap(this, &__str);
+#endif
     _VSTD::swap(__r_.first(), __str.__r_.first());
     __swap_alloc(__alloc(), __str.__alloc());
-#ifdef _LIBCPP_DEBUG
-    __invalidate_all_iterators();
-    __str.__invalidate_all_iterators();
-#endif  // _LIBCPP_DEBUG
 }
 
 // find
@@ -3180,20 +3239,18 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos,
                                                 size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): recieved nullptr");
     size_type __sz = size();
     if (__pos > __sz || __sz - __pos < __n)
         return npos;
     if (__n == 0)
         return __pos;
-    const_pointer __p = data();
-    const_pointer __r = _VSTD::search(__p + __pos, __p + __sz, __s, __s + __n,
+    const value_type* __p = data();
+    const value_type* __r = _VSTD::search(__p + __pos, __p + __sz, __s, __s + __n,
                                      __traits_eq<traits_type>());
     if (__r == __p + __sz)
         return npos;
@@ -3201,7 +3258,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
                                                 size_type __pos) const _NOEXCEPT
@@ -3210,14 +3267,12 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find(): recieved nullptr");
     return find(__s, __pos, traits_type::length(__s));
 }
 
@@ -3229,8 +3284,8 @@
     size_type __sz = size();
     if (__pos >= __sz)
         return npos;
-    const_pointer __p = data();
-    const_pointer __r = traits_type::find(__p + __pos, __sz - __pos, __c);
+    const value_type* __p = data();
+    const value_type* __r = traits_type::find(__p + __pos, __sz - __pos, __c);
     if (__r == 0)
         return npos;
     return static_cast<size_type>(__r - __p);
@@ -3240,21 +3295,19 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::rfind(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos,
                                                  size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): recieved nullptr");
     size_type __sz = size();
     __pos = _VSTD::min(__pos, __sz);
     if (__n < __sz - __pos)
         __pos += __n;
     else
         __pos = __sz;
-    const_pointer __p = data();
-    const_pointer __r = _VSTD::find_end(__p, __p + __pos, __s, __s + __n,
+    const value_type* __p = data();
+    const value_type* __r = _VSTD::find_end(__p, __p + __pos, __s, __s + __n,
                                        __traits_eq<traits_type>());
     if (__n > 0 && __r == __p + __pos)
         return npos;
@@ -3262,7 +3315,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
                                                  size_type __pos) const _NOEXCEPT
@@ -3271,14 +3324,12 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::rfind(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): recieved nullptr");
     return rfind(__s, __pos, traits_type::length(__s));
 }
 
@@ -3294,8 +3345,8 @@
             ++__pos;
         else
             __pos = __sz;
-        const_pointer __p = data();
-        for (const_pointer __ps = __p + __pos; __ps != __p;)
+        const value_type* __p = data();
+        for (const value_type* __ps = __p + __pos; __ps != __p;)
         {
             if (traits_type::eq(*--__ps, __c))
                 return static_cast<size_type>(__ps - __p);
@@ -3308,18 +3359,16 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_first_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos,
                                                          size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): recieved nullptr");
     size_type __sz = size();
     if (__pos >= __sz || __n == 0)
         return npos;
-    const_pointer __p = data();
-    const_pointer __r = _VSTD::find_first_of(__p + __pos, __p + __sz, __s,
+    const value_type* __p = data();
+    const value_type* __r = _VSTD::find_first_of(__p + __pos, __p + __sz, __s,
                                             __s + __n, __traits_eq<traits_type>());
     if (__r == __p + __sz)
         return npos;
@@ -3327,7 +3376,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
                                                          size_type __pos) const _NOEXCEPT
@@ -3336,19 +3385,17 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_first_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): recieved nullptr");
     return find_first_of(__s, __pos, traits_type::length(__s));
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
                                                          size_type __pos) const _NOEXCEPT
@@ -3360,13 +3407,11 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_last_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos,
                                                         size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): recieved nullptr");
     if (__n != 0)
     {
         size_type __sz = size();
@@ -3374,10 +3419,10 @@
             ++__pos;
         else
             __pos = __sz;
-        const_pointer __p = data();
-        for (const_pointer __ps = __p + __pos; __ps != __p;)
+        const value_type* __p = data();
+        for (const value_type* __ps = __p + __pos; __ps != __p;)
         {
-            const_pointer __r = traits_type::find(__s, __n, *--__ps);
+            const value_type* __r = traits_type::find(__s, __n, *--__ps);
             if (__r)
                 return static_cast<size_type>(__ps - __p);
         }
@@ -3386,7 +3431,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
                                                         size_type __pos) const _NOEXCEPT
@@ -3395,19 +3440,17 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_last_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): recieved nullptr");
     return find_last_of(__s, __pos, traits_type::length(__s));
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
                                                         size_type __pos) const _NOEXCEPT
@@ -3419,19 +3462,17 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos,
                                                              size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): recieved nullptr");
     size_type __sz = size();
     if (__pos < __sz)
     {
-        const_pointer __p = data();
-        const_pointer __pe = __p + __sz;
-        for (const_pointer __ps = __p + __pos; __ps != __pe; ++__ps)
+        const value_type* __p = data();
+        const value_type* __pe = __p + __sz;
+        for (const value_type* __ps = __p + __pos; __ps != __pe; ++__ps)
             if (traits_type::find(__s, __n, *__ps) == 0)
                 return static_cast<size_type>(__ps - __p);
     }
@@ -3439,7 +3480,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
                                                              size_type __pos) const _NOEXCEPT
@@ -3448,19 +3489,17 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): recieved nullptr");
     return find_first_not_of(__s, __pos, traits_type::length(__s));
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
                                                              size_type __pos) const _NOEXCEPT
@@ -3468,9 +3507,9 @@
     size_type __sz = size();
     if (__pos < __sz)
     {
-        const_pointer __p = data();
-        const_pointer __pe = __p + __sz;
-        for (const_pointer __ps = __p + __pos; __ps != __pe; ++__ps)
+        const value_type* __p = data();
+        const value_type* __pe = __p + __sz;
+        for (const value_type* __ps = __p + __pos; __ps != __pe; ++__ps)
             if (!traits_type::eq(*__ps, __c))
                 return static_cast<size_type>(__ps - __p);
     }
@@ -3481,27 +3520,25 @@
 
 template<class _CharT, class _Traits, class _Allocator>
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos,
                                                             size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): recieved nullptr");
     size_type __sz = size();
     if (__pos < __sz)
         ++__pos;
     else
         __pos = __sz;
-    const_pointer __p = data();
-    for (const_pointer __ps = __p + __pos; __ps != __p;)
+    const value_type* __p = data();
+    for (const value_type* __ps = __p + __pos; __ps != __p;)
         if (traits_type::find(__s, __n, *--__ps) == 0)
             return static_cast<size_type>(__ps - __p);
     return npos;
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
                                                             size_type __pos) const _NOEXCEPT
@@ -3510,19 +3547,17 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const_pointer __s,
+basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): recieved nullptr");
     return find_last_not_of(__s, __pos, traits_type::length(__s));
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
                                                             size_type __pos) const _NOEXCEPT
@@ -3532,8 +3567,8 @@
         ++__pos;
     else
         __pos = __sz;
-    const_pointer __p = data();
-    for (const_pointer __ps = __p + __pos; __ps != __p;)
+    const value_type* __p = data();
+    for (const value_type* __ps = __p + __pos; __ps != __p;)
         if (!traits_type::eq(*--__ps, __c))
             return static_cast<size_type>(__ps - __p);
     return npos;
@@ -3542,7 +3577,7 @@
 // compare
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
 {
@@ -3560,7 +3595,7 @@
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
@@ -3586,11 +3621,9 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 int
-basic_string<_CharT, _Traits, _Allocator>::compare(const_pointer __s) const _NOEXCEPT
+basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): recieved nullptr");
     return compare(0, npos, __s, traits_type::length(__s));
 }
 
@@ -3598,11 +3631,9 @@
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
-                                                   const_pointer __s) const
+                                                   const value_type* __s) const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): recieved nullptr");
     return compare(__pos1, __n1, __s, traits_type::length(__s));
 }
 
@@ -3610,12 +3641,10 @@
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
                                                    size_type __n1,
-                                                   const_pointer __s,
+                                                   const value_type* __s,
                                                    size_type __n2) const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): recieved nullptr");
     size_type __sz = size();
     if (__pos1 > __sz || __n2 == npos)
         this->__throw_out_of_range();
@@ -3634,7 +3663,7 @@
 // __invariants
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 basic_string<_CharT, _Traits, _Allocator>::__invariants() const
 {
@@ -3652,7 +3681,7 @@
 // operator==
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3664,7 +3693,7 @@
 }
 
 template<class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
            const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
@@ -3683,7 +3712,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3692,7 +3721,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -3703,7 +3732,7 @@
 // operator!=
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3712,7 +3741,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3721,7 +3750,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -3732,7 +3761,7 @@
 // operator<
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3741,7 +3770,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -3750,7 +3779,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator< (const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3761,7 +3790,7 @@
 // operator>
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3770,7 +3799,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -3779,7 +3808,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator> (const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3790,7 +3819,7 @@
 // operator<=
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3799,7 +3828,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -3808,7 +3837,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator<=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3819,7 +3848,7 @@
 // operator>=
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3828,7 +3857,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
            const _CharT* __rhs) _NOEXCEPT
@@ -3837,7 +3866,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>=(const _CharT* __lhs,
            const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
@@ -3909,7 +3938,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
 {
@@ -3917,7 +3946,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
 {
@@ -3925,7 +3954,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
 {
@@ -3933,7 +3962,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
 {
@@ -3941,7 +3970,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
 {
@@ -3950,7 +3979,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
 {
@@ -3958,7 +3987,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>
 operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
 {
@@ -3971,7 +4000,7 @@
 // swap
 
 template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
      basic_string<_CharT, _Traits, _Allocator>& __rhs)
@@ -3987,45 +4016,45 @@
 
 #endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
 
-int                stoi  (const string& __str, size_t* __idx = 0, int __base = 10);
-long               stol  (const string& __str, size_t* __idx = 0, int __base = 10);
-unsigned long      stoul (const string& __str, size_t* __idx = 0, int __base = 10);
-long long          stoll (const string& __str, size_t* __idx = 0, int __base = 10);
-unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long long          stoll (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);
 
-float       stof (const string& __str, size_t* __idx = 0);
-double      stod (const string& __str, size_t* __idx = 0);
-long double stold(const string& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS float       stof (const string& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0);
 
-string to_string(int __val);
-string to_string(unsigned __val);
-string to_string(long __val);
-string to_string(unsigned long __val);
-string to_string(long long __val);
-string to_string(unsigned long long __val);
-string to_string(float __val);
-string to_string(double __val);
-string to_string(long double __val);
+_LIBCPP_FUNC_VIS string to_string(int __val);
+_LIBCPP_FUNC_VIS string to_string(unsigned __val);
+_LIBCPP_FUNC_VIS string to_string(long __val);
+_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
+_LIBCPP_FUNC_VIS string to_string(long long __val);
+_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
+_LIBCPP_FUNC_VIS string to_string(float __val);
+_LIBCPP_FUNC_VIS string to_string(double __val);
+_LIBCPP_FUNC_VIS string to_string(long double __val);
 
-int                stoi  (const wstring& __str, size_t* __idx = 0, int __base = 10);
-long               stol  (const wstring& __str, size_t* __idx = 0, int __base = 10);
-unsigned long      stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);
-long long          stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);
-unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS int                stoi  (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long               stol  (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long      stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long long          stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);
 
-float       stof (const wstring& __str, size_t* __idx = 0);
-double      stod (const wstring& __str, size_t* __idx = 0);
-long double stold(const wstring& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS float       stof (const wstring& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0);
 
-wstring to_wstring(int __val);
-wstring to_wstring(unsigned __val);
-wstring to_wstring(long __val);
-wstring to_wstring(unsigned long __val);
-wstring to_wstring(long long __val);
-wstring to_wstring(unsigned long long __val);
-wstring to_wstring(float __val);
-wstring to_wstring(double __val);
-wstring to_wstring(long double __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
 
 template<class _CharT, class _Traits, class _Allocator>
     const typename basic_string<_CharT, _Traits, _Allocator>::size_type
@@ -4039,7 +4068,7 @@
 }
 
 template<class _CharT, class _Traits, class _Allocator>
-struct _LIBCPP_TYPE_VIS hash<basic_string<_CharT, _Traits, _Allocator> >
+struct _LIBCPP_TYPE_VIS_ONLY hash<basic_string<_CharT, _Traits, _Allocator> >
     : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
 {
     size_t
@@ -4091,12 +4120,78 @@
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-_LIBCPP_EXTERN_TEMPLATE(class basic_string<char>)
-_LIBCPP_EXTERN_TEMPLATE(class basic_string<wchar_t>)
+#if _LIBCPP_DEBUG_LEVEL >= 2
 
-extern template
-    string
-    operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
+{
+    return this->data() <= _VSTD::__to_raw_pointer(__i->base()) &&
+           _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
+{
+    return this->data() < _VSTD::__to_raw_pointer(__i->base()) &&
+           _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
+    return this->data() <= __p && __p <= this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
+    return this->data() <= __p && __p < this->data() + this->size();
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+#if _LIBCPP_STD_VER > 11 
+// Literal suffixes for basic_string [basic.string.literals]
+inline namespace literals
+{
+  inline namespace string_literals
+  {
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<char> operator "" s( const char *__str, size_t __len )
+    {
+        return basic_string<char> (__str, __len);
+    }
+
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
+    {
+        return basic_string<wchar_t> (__str, __len);
+    }
+
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
+    {
+        return basic_string<char16_t> (__str, __len);
+    }
+
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
+    {
+        return basic_string<char32_t> (__str, __len);
+    }
+  }
+}
+#endif
+
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/support/ibm/limits.h b/include/support/ibm/limits.h
new file mode 100644
index 0000000..efdb359
--- /dev/null
+++ b/include/support/ibm/limits.h
@@ -0,0 +1,99 @@
+// -*- C++ -*-
+//===--------------------- support/ibm/limits.h ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_LIMITS_H
+#define _LIBCPP_SUPPORT_IBM_LIMITS_H
+
+#if !defined(_AIX) // Linux
+#include <math.h> // for HUGE_VAL, HUGE_VALF, HUGE_VALL, and NAN
+
+static const unsigned int _QNAN_F = 0x7fc00000;
+#define NANF (*((float *)(&_QNAN_F)))
+static const unsigned int _QNAN_LDBL128[4] = {0x7ff80000, 0x0, 0x0, 0x0};
+#define NANL (*((long double *)(&_QNAN_LDBL128)))
+static const unsigned int _SNAN_F= 0x7f855555;
+#define NANSF (*((float *)(&_SNAN_F)))
+static const unsigned int _SNAN_D[2] = {0x7ff55555, 0x55555555};
+#define NANS (*((double *)(&_SNAN_D)))
+static const unsigned int _SNAN_LDBL128[4] = {0x7ff55555, 0x55555555, 0x0, 0x0};
+#define NANSL (*((long double *)(&_SNAN_LDBL128)))
+
+#define __builtin_huge_val()     HUGE_VAL
+#define __builtin_huge_valf()    HUGE_VALF
+#define __builtin_huge_vall()    HUGE_VALL
+#define __builtin_nan(__dummy)   NAN
+#define __builtin_nanf(__dummy)  NANF
+#define __builtin_nanl(__dummy)  NANL
+#define __builtin_nans(__dummy)  NANS
+#define __builtin_nansf(__dummy) NANSF
+#define __builtin_nansl(__dummy) NANSL
+
+#else
+
+#include <math.h>
+#include <float.h> // limit constants
+
+#define __builtin_huge_val()     HUGE_VAL  //0x7ff0000000000000
+#define __builtin_huge_valf()    HUGE_VALF //0x7f800000
+#define __builtin_huge_vall()    HUGE_VALL //0x7ff0000000000000
+#define __builtin_nan(__dummy)   nan(__dummy) //0x7ff8000000000000
+#define __builtin_nanf(__dummy)  nanf(__dummy) // 0x7ff80000
+#define __builtin_nanl(__dummy)  nanl(__dummy) //0x7ff8000000000000
+#define __builtin_nans(__dummy)  DBL_SNAN //0x7ff5555555555555
+#define __builtin_nansf(__dummy) FLT_SNAN //0x7f855555
+#define __builtin_nansl(__dummy) DBL_SNAN //0x7ff5555555555555
+
+#define __FLT_MANT_DIG__   FLT_MANT_DIG
+#define __FLT_DIG__        FLT_DIG
+#define __FLT_RADIX__      FLT_RADIX
+#define __FLT_MIN_EXP__    FLT_MIN_EXP
+#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP
+#define __FLT_MAX_EXP__    FLT_MAX_EXP
+#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP
+#define __FLT_MIN__        FLT_MIN
+#define __FLT_MAX__        FLT_MAX
+#define __FLT_EPSILON__    FLT_EPSILON
+// predefined by XLC on LoP
+#define __FLT_DENORM_MIN__ 1.40129846e-45F
+
+#define __DBL_MANT_DIG__   DBL_MANT_DIG
+#define __DBL_DIG__        DBL_DIG
+#define __DBL_MIN_EXP__    DBL_MIN_EXP
+#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP
+#define __DBL_MAX_EXP__    DBL_MAX_EXP
+#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP
+#define __DBL_MIN__        DBL_MIN
+#define __DBL_MAX__        DBL_MAX
+#define __DBL_EPSILON__    DBL_EPSILON
+// predefined by XLC on LoP
+#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+
+#define __LDBL_MANT_DIG__   LDBL_MANT_DIG
+#define __LDBL_DIG__        LDBL_DIG
+#define __LDBL_MIN_EXP__    LDBL_MIN_EXP
+#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP
+#define __LDBL_MAX_EXP__    LDBL_MAX_EXP
+#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP
+#define __LDBL_MIN__        LDBL_MIN
+#define __LDBL_MAX__        LDBL_MAX
+#define __LDBL_EPSILON__    LDBL_EPSILON
+// predefined by XLC on LoP
+#if __LONGDOUBLE128
+#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
+#else
+#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+#endif
+
+// predefined by XLC on LoP
+#define __CHAR_BIT__    8
+
+#endif // _AIX
+
+#endif // _LIBCPP_SUPPORT_IBM_LIMITS_H
diff --git a/include/support/ibm/support.h b/include/support/ibm/support.h
new file mode 100644
index 0000000..3effbae
--- /dev/null
+++ b/include/support/ibm/support.h
@@ -0,0 +1,54 @@
+// -*- C++ -*-
+//===----------------------- support/ibm/support.h ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_SUPPORT_H
+#define _LIBCPP_SUPPORT_IBM_SUPPORT_H
+
+extern "builtin" int __popcnt4(unsigned int);
+extern "builtin" int __popcnt8(unsigned long long);
+extern "builtin" unsigned int __cnttz4(unsigned int);
+extern "builtin" unsigned int __cnttz8(unsigned long long);
+extern "builtin" unsigned int __cntlz4(unsigned long long);
+extern "builtin" unsigned int __cntlz8(unsigned long long);
+
+// Builtin functions for counting population
+#define __builtin_popcount(x) __popcnt4(x)
+#define __builtin_popcountll(x) __popcnt8(x)
+#if defined(__64BIT__)
+#define __builtin_popcountl(x) __builtin_popcountll(x)
+#else
+#define __builtin_popcountl(x) __builtin_popcount(x)
+#endif
+
+// Builtin functions for counting trailing zeros
+#define __builtin_ctz(x) __cnttz4(x)
+#define __builtin_ctzll(x) __cnttz8(x)
+#if defined(__64BIT__)
+#define __builtin_ctzl(x) __builtin_ctzll(x)
+#else
+#define __builtin_ctzl(x) __builtin_ctz(x)
+#endif
+
+// Builtin functions for counting leading zeros
+#define __builtin_clz(x) __cntlz4(x)
+#define __builtin_clzll(x) __cntlz8(x)
+#if defined(__64BIT__)
+#define __builtin_clzl(x) __builtin_clzll(x)
+#else
+#define __builtin_clzl(x) __builtin_clz(x)
+#endif
+
+#if defined(__64BIT__)
+#define __SIZE_WIDTH__ 64
+#else
+#define __SIZE_WIDTH__ 32
+#endif
+
+#endif // _LIBCPP_SUPPORT_IBM_SUPPORT_H
diff --git a/include/support/ibm/xlocale.h b/include/support/ibm/xlocale.h
new file mode 100644
index 0000000..8d99a5c
--- /dev/null
+++ b/include/support/ibm/xlocale.h
@@ -0,0 +1,326 @@
+// -*- C++ -*-
+//===--------------------- support/ibm/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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H
+#define _LIBCPP_SUPPORT_IBM_XLOCALE_H
+
+#if defined(_AIX)
+#include "cstdlib"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_AIX71)
+// AIX 7.1 and higher has these definitions.  Definitions and stubs
+// are provied here as a temporary workaround on AIX 6.1.
+
+#define LC_COLLATE_MASK         1
+#define LC_CTYPE_MASK           2
+#define LC_MESSAGES_MASK        4
+#define LC_MONETARY_MASK        8
+#define LC_NUMERIC_MASK         16
+#define LC_TIME_MASK            32
+#define LC_ALL_MASK             (LC_COLLATE_MASK | LC_CTYPE_MASK | \
+                                 LC_MESSAGES_MASK | LC_MONETARY_MASK |\
+                                 LC_NUMERIC_MASK | LC_TIME_MASK)
+
+typedef void* locale_t;
+
+// The following are stubs.  They are not supported on AIX 6.1.
+static inline
+locale_t newlocale(int category_mask, const char *locale, locale_t base)
+{
+  _LC_locale_t *newloc, *loc;
+  if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL)
+  {
+    errno = EINVAL;
+    return (locale_t)0;
+  }
+  if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL)
+  {
+    errno = ENOMEM;
+    return (locale_t)0;
+  }
+  if (!base)
+    base = (_LC_locale_t *)__xopen_locale("C");
+  memcpy(newloc, base, sizeof (_LC_locale_t));
+  if (category_mask & LC_COLLATE_MASK) 
+    newloc->lc_collate = loc->lc_collate;
+  if (category_mask & LC_CTYPE_MASK)
+    newloc->lc_ctype = loc->lc_ctype;
+  //if (category_mask & LC_MESSAGES_MASK)
+  //  newloc->lc_messages = loc->lc_messages;
+  if (category_mask & LC_MONETARY_MASK)
+    newloc->lc_monetary = loc->lc_monetary;
+  if (category_mask & LC_TIME_MASK)
+    newloc->lc_time = loc->lc_time;
+  if (category_mask & LC_NUMERIC_MASK)
+    newloc->lc_numeric = loc->lc_numeric;
+  return (locale_t)newloc; 
+}
+static inline
+void freelocale(locale_t locobj)
+{
+  free(locobj);
+}
+static inline
+locale_t uselocale(locale_t newloc)
+{
+  return (locale_t)0;
+}
+
+static inline
+int isalnum_l(int c, locale_t locale)
+{
+  return __xisalnum(locale, c);
+}
+static inline
+int isalpha_l(int c, locale_t locale)
+{
+  return __xisalpha(locale, c);
+}
+static inline
+int isblank_l(int c, locale_t locale)
+{
+  return __xisblank(locale, c);
+}
+static inline
+int iscntrl_l(int c, locale_t locale)
+{
+  return __xiscntrl(locale, c);
+}
+static inline
+int isdigit_l(int c, locale_t locale)
+{
+  return __xisdigit(locale, c);
+}
+static inline
+int isgraph_l(int c, locale_t locale)
+{
+  return __xisgraph(locale, c);
+}
+static inline
+int islower_l(int c, locale_t locale)
+{
+  return __xislower(locale, c);
+}
+static inline
+int isprint_l(int c, locale_t locale)
+{
+  return __xisprint(locale, c);
+}
+
+static inline
+int ispunct_l(int c, locale_t locale)
+{
+  return __xispunct(locale, c);
+}
+static inline
+int isspace_l(int c, locale_t locale)
+{
+  return __xisspace(locale, c);
+}
+static inline
+int isupper_l(int c, locale_t locale)
+{
+  return __xisupper(locale, c);
+}
+
+static inline
+int isxdigit_l(int c, locale_t locale)
+{
+  return __xisxdigit(locale, c);
+}
+
+static inline
+int iswalnum_l(wchar_t wc, locale_t locale)
+{
+  return __xiswalnum(locale, wc); 
+}
+
+static inline
+int iswalpha_l(wchar_t wc, locale_t locale)
+{
+  return __xiswalpha(locale, wc);
+}
+
+static inline
+int iswblank_l(wchar_t wc, locale_t locale)
+{
+  return __xiswblank(locale, wc);
+}
+
+static inline
+int iswcntrl_l(wchar_t wc, locale_t locale)
+{
+  return __xiswcntrl(locale, wc);
+}
+
+static inline
+int iswdigit_l(wchar_t wc, locale_t locale)
+{
+  return __xiswdigit(locale, wc);
+}
+
+static inline
+int iswgraph_l(wchar_t wc, locale_t locale)
+{
+  return __xiswgraph(locale, wc);
+}
+
+static inline
+int iswlower_l(wchar_t wc, locale_t locale)
+{
+  return __xiswlower(locale, wc);
+}
+
+static inline
+int iswprint_l(wchar_t wc, locale_t locale)
+{
+  return __xiswprint(locale, wc);
+}
+
+static inline
+int iswpunct_l(wchar_t wc, locale_t locale)
+{
+  return __xiswpunct(locale, wc);
+}
+
+static inline
+int iswspace_l(wchar_t wc, locale_t locale)
+{
+  return __xiswspace(locale, wc);
+}
+
+static inline
+int iswupper_l(wchar_t wc, locale_t locale)
+{
+  return __xiswupper(locale, wc);
+}
+
+static inline
+int iswxdigit_l(wchar_t wc, locale_t locale)
+{
+  return __xiswxdigit(locale, wc);
+}
+
+static inline
+int iswctype_l(wint_t wc, wctype_t desc, locale_t locale)
+{
+  return __xiswctype(locale, wc, desc); 
+}
+
+static inline
+int toupper_l(int c, locale_t locale)
+{
+  return __xtoupper(locale, c);
+}
+static inline
+int tolower_l(int c, locale_t locale)
+{
+  return __xtolower(locale, c);
+}
+static inline
+wint_t towupper_l(wint_t wc, locale_t locale)
+{
+  return __xtowupper(locale, wc);
+}
+static inline
+wint_t towlower_l(wint_t wc, locale_t locale)
+{
+  return __xtowlower(locale, wc);
+}
+
+static inline
+int strcoll_l(const char *__s1, const char *__s2, locale_t locale)
+{
+  return __xstrcoll(locale, __s1, __s2);
+}
+static inline
+int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale)
+{
+  return __xwcscoll(locale, __s1, __s2);
+}
+static inline
+size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale)
+{
+  return __xstrxfrm(locale, __s1, __s2, __n);
+}
+
+static inline
+size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
+    locale_t locale)
+{
+  return __xwcsxfrm(locale, __ws1, __ws2, __n);
+}
+#endif // !defined(_AIX71)
+
+// strftime_l() is defined by POSIX. However, AIX 7.1 does not have it
+// implemented yet.
+static inline
+size_t strftime_l(char *__s, size_t __size, const char *__fmt,
+                  const struct tm *__tm, locale_t locale) {
+  return __xstrftime(locale, __s, __size, __fmt, __tm);
+}
+
+// The following are not POSIX routines.  These are quick-and-dirty hacks
+// to make things pretend to work
+static inline
+long long strtoll_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtoll(__nptr, __endptr, __base);
+}
+static inline
+long strtol_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtol(__nptr, __endptr, __base);
+}
+static inline
+long double strtold_l(const char *__nptr, char **__endptr,
+    locale_t locale) {
+  return strtold(__nptr, __endptr);
+}
+static inline
+unsigned long long strtoull_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtoull(__nptr, __endptr, __base);
+}
+static inline
+unsigned long strtoul_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtoul(__nptr, __endptr, __base);
+}
+
+static inline
+int vasprintf(char **strp, const char *fmt, va_list ap)
+{
+  const size_t buff_size = 256;
+  int str_size;
+  if ((*strp = (char *)malloc(buff_size)) == NULL)
+  {
+    return -1;
+  }
+  if ((str_size = vsnprintf(*strp, buff_size, fmt,  ap)) >= buff_size)
+  {
+    if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL)
+    {
+      return -1;
+    }
+    str_size = vsnprintf(*strp, str_size + 1, fmt,  ap);
+  }
+  return str_size;
+}  
+
+#ifdef __cplusplus
+}
+#endif
+#endif // defined(_AIX)
+#endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H
diff --git a/include/support/win32/limits_win32.h b/include/support/win32/limits_win32.h
index 671631d..406cd30 100644
--- a/include/support/win32/limits_win32.h
+++ b/include/support/win32/limits_win32.h
@@ -11,17 +11,16 @@
 #ifndef _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H
 #define _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H
 
-#if !defined(_MSC_VER)
-#error "This header is MSVC specific, Clang and GCC should not include it"
+#if !defined(_LIBCPP_MSVCRT)
+#error "This header complements the Microsoft C Runtime library, and should not be included otherwise."
 #else
 
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-#include <windows.h> // ymath.h works correctly
-
+#include <limits.h> // CHAR_BIT
 #include <float.h> // limit constants
 
+#if ! defined(__clang__)
+#define __CHAR_BIT__       CHAR_BIT
+
 #define __FLT_MANT_DIG__   FLT_MANT_DIG
 #define __FLT_DIG__        FLT_DIG
 #define __FLT_RADIX__      FLT_RADIX
@@ -73,7 +72,8 @@
 #define __builtin_nans(__dummy)  _Snan._Double
 #define __builtin_nansf(__dummy) _FSnan._Float
 #define __builtin_nansl(__dummy) _LSnan._Long_double
+#endif // ! defined(__clang__)
 
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 
 #endif // _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H
diff --git a/include/support/win32/locale_win32.h b/include/support/win32/locale_win32.h
index 019586c..f728d23 100644
--- a/include/support/win32/locale_win32.h
+++ b/include/support/win32/locale_win32.h
@@ -15,6 +15,7 @@
 extern "C" unsigned short  __declspec(dllimport) _ctype[];
 
 #include "support/win32/support.h"
+#include <stdio.h>
 #include <memory>
 #include <xlocinfo.h> // _locale_t
 #define locale_t _locale_t
@@ -35,23 +36,23 @@
 locale_t newlocale( int mask, const char * locale, locale_t base );
 locale_t uselocale( locale_t newloc );
 lconv *localeconv_l( locale_t loc );
-size_t mbrlen_l( const char *__restrict__ s, size_t n,
-                 mbstate_t *__restrict__ ps, locale_t loc);
-size_t mbsrtowcs_l( wchar_t *__restrict__ dst, const char **__restrict__ src,
-                    size_t len, mbstate_t *__restrict__ ps, locale_t loc );
-size_t wcrtomb_l( char *__restrict__ s, wchar_t wc, mbstate_t *__restrict__ ps,
+size_t mbrlen_l( const char *__restrict s, size_t n,
+                 mbstate_t *__restrict ps, locale_t loc);
+size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                    size_t len, mbstate_t *__restrict ps, locale_t loc );
+size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,
                   locale_t loc);
-size_t mbrtowc_l( wchar_t *__restrict__ pwc, const char *__restrict__ s,
-                  size_t n, mbstate_t *__restrict__ ps, locale_t loc);
-size_t mbsnrtowcs_l( wchar_t *__restrict__ dst, const char **__restrict__ src,
-                     size_t nms, size_t len, mbstate_t *__restrict__ ps, locale_t loc);
-size_t wcsnrtombs_l( char *__restrict__ dst, const wchar_t **__restrict__ src,
-                     size_t nwc, size_t len, mbstate_t *__restrict__ ps, locale_t loc);
+size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,
+                  size_t n, mbstate_t *__restrict ps, locale_t loc);
+size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                     size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc);
+size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
+                     size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc);
 wint_t btowc_l( int c, locale_t loc );
 int wctob_l( wint_t c, locale_t loc );
 typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
 typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
-_LIBCPP_ALWAYS_INLINE inline
+inline _LIBCPP_ALWAYS_INLINE
 decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )
 {
   __locale_raii __current( uselocale(__l), uselocale );
@@ -59,7 +60,6 @@
 }
 
 // the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+
-#include <stdio.h>
 #define mbtowc_l _mbtowc_l
 #define strtoll_l _strtoi64_l
 #define strtoull_l _strtoui64_l
@@ -103,9 +103,9 @@
 #define sscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ )
 #define vsscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ )
 #define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ )
-#define snprintf_l( __s, __n, __l, __f, ... ) _snprintf_l( __s, __n, __f, __l, __VA_ARGS__ )
 #define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ )
 #define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ )
+int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...);
 int asprintf_l( char **ret, locale_t loc, const char *format, ... );
 int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap );
 
@@ -120,10 +120,10 @@
     return ( c == L' ' || c == L'\t' );
 }
 
-#ifdef _MSC_VER
+#if defined(_LIBCPP_MSVCRT)
 inline int isblank( int c, locale_t /*loc*/ )
 { return ( c == ' ' || c == '\t' ); }
 inline int iswblank( wint_t c, locale_t /*loc*/ )
 { return ( c == L' ' || c == L'\t' ); }
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 #endif // _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
diff --git a/include/support/win32/math_win32.h b/include/support/win32/math_win32.h
index 41c50d6..c62c54e 100644
--- a/include/support/win32/math_win32.h
+++ b/include/support/win32/math_win32.h
@@ -11,12 +11,14 @@
 #ifndef _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H
 #define _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H
 
-#if !defined(_MSC_VER)
-#error "This header is MSVC specific, Clang and GCC should not include it"
+#if !defined(_LIBCPP_MSVCRT)
+#error "This header complements Microsoft's C Runtime library, and should not be included otherwise."
 #else
 
 #include <math.h>
+#include <float.h> // _FPCLASS_PN etc.
 
+// Necessary?
 typedef float float_t;
 typedef double double_t;
 
@@ -108,6 +110,6 @@
     return _fpclass(num);
 }
 
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 
 #endif // _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H
diff --git a/include/support/win32/support.h b/include/support/win32/support.h
index 0b8a912..ed1986e 100644
--- a/include/support/win32/support.h
+++ b/include/support/win32/support.h
@@ -15,26 +15,27 @@
    Functions and constants used in libc++ that are missing from the Windows C library.
   */
 
-#include <__config>
 #include <wchar.h>  // mbstate_t
-#include <stdio.h> // _snwprintf
+#include <cstdarg> // va_ macros
 #define swprintf _snwprintf
 #define vswprintf _vsnwprintf
-#define vfscnaf fscanf
 
-int vasprintf( char **sptr, const char *__restrict fmt , va_list ap );
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+extern "C" {
+
+int vasprintf( char **sptr, const char *__restrict fmt, va_list ap );
 int asprintf( char **sptr, const char *__restrict fmt, ...);
-//int vfscanf( FILE *__restrict stream, const char *__restrict format,
-//             va_list arg);
-
 size_t mbsnrtowcs( wchar_t *__restrict dst, const char **__restrict src,
                    size_t nmc, size_t len, mbstate_t *__restrict ps );
 size_t wcsnrtombs( char *__restrict dst, const wchar_t **__restrict src,
                    size_t nwc, size_t len, mbstate_t *__restrict ps );
+}
 
-#if defined(_MSC_VER)
+#if defined(_LIBCPP_MSVCRT)
 #define snprintf _snprintf
-
 #include <xlocinfo.h>
 #define atoll _atoi64
 #define strtoll _strtoi64
@@ -85,9 +86,11 @@
    _BitScanReverse(&r, x);
    return static_cast<int>(r);
 }
+
 // sizeof(long) == sizeof(int) on Windows
 _LIBCPP_ALWAYS_INLINE int __builtin_ctzl( unsigned long x )
 { return __builtin_ctz( static_cast<int>(x) ); }
+
 _LIBCPP_ALWAYS_INLINE int __builtin_ctzll( unsigned long long x )
 {
     DWORD r = 0;
@@ -110,6 +113,6 @@
     return static_cast<int>(r);
 }
 #endif // !__clang__
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVCRT
 
 #endif // _LIBCPP_SUPPORT_WIN32_SUPPORT_H
diff --git a/include/system_error b/include/system_error
index 1c1c7eb..66bf6d6 100644
--- a/include/system_error
+++ b/include/system_error
@@ -22,6 +22,7 @@
 public:
     virtual ~error_category() noexcept;
 
+    constexpr error_category();
     error_category(const error_category&) = delete;
     error_category& operator=(const error_category&) = delete;
 
@@ -232,13 +233,13 @@
 // is_error_code_enum
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_error_code_enum
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum
     : public false_type {};
 
 // is_error_condition_enum
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_error_condition_enum
+struct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum
     : public false_type {};
 
 // Some error codes are not present on all platforms, so we provide equivalents
@@ -345,12 +346,12 @@
 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)
 
 template <>
-struct _LIBCPP_TYPE_VIS is_error_condition_enum<errc>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum<errc>
     : true_type { };
 
 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
 template <>
-struct _LIBCPP_TYPE_VIS is_error_condition_enum<errc::__lx>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum<errc::__lx>
     : true_type { };
 #endif
 
@@ -366,7 +367,12 @@
 public:
     virtual ~error_category() _NOEXCEPT;
 
+#ifdef _LIBCPP_BUILDING_SYSTEM_ERROR
     error_category() _NOEXCEPT;
+#else
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT;
+#endif
 private:
     error_category(const error_category&);// = delete;
     error_category& operator=(const error_category&);// = delete;
@@ -397,8 +403,8 @@
     virtual string message(int ev) const;
 };
 
-const error_category& generic_category() _NOEXCEPT;
-const error_category& system_category() _NOEXCEPT;
+_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;
+_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT;
 
 class _LIBCPP_TYPE_VIS error_condition
 {
@@ -597,7 +603,7 @@
 {return !(__x == __y);}
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<error_code>
+struct _LIBCPP_TYPE_VIS_ONLY hash<error_code>
     : public unary_function<error_code, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -629,7 +635,7 @@
     static string __init(const error_code&, string);
 };
 
-void __throw_system_error(int ev, const char* what_arg);
+_LIBCPP_FUNC_VIS void __throw_system_error(int ev, const char* what_arg);
 
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/include/thread b/include/thread
index f41ea29..1f1e4a2 100644
--- a/include/thread
+++ b/include/thread
@@ -185,10 +185,9 @@
 
 }  // this_thread
 
-class _LIBCPP_TYPE_VIS __thread_id;
-template<> struct _LIBCPP_TYPE_VIS hash<__thread_id>;
+template<> struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>;
 
-class _LIBCPP_TYPE_VIS __thread_id
+class _LIBCPP_TYPE_VIS_ONLY __thread_id
 {
     // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
     // NULL is the no-thread value on Darwin.  Someone needs to check
@@ -231,11 +230,11 @@
 
     friend __thread_id this_thread::get_id() _NOEXCEPT;
     friend class _LIBCPP_TYPE_VIS thread;
-    friend struct _LIBCPP_TYPE_VIS hash<__thread_id>;
+    friend struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>;
 };
 
 template<>
-struct _LIBCPP_TYPE_VIS hash<__thread_id>
+struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>
     : public unary_function<__thread_id, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -307,7 +306,7 @@
 
 class _LIBCPP_HIDDEN __thread_struct_imp;
 
-class __thread_struct
+class _LIBCPP_TYPE_VIS __thread_struct
 {
     __thread_struct_imp* __p_;
 
@@ -321,7 +320,7 @@
     void __make_ready_at_thread_exit(__assoc_sub_state*);
 };
 
-__thread_specific_ptr<__thread_struct>& __thread_local_data();
+_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
@@ -405,7 +404,7 @@
 namespace this_thread
 {
 
-void sleep_for(const chrono::nanoseconds& ns);
+_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& ns);
 
 template <class _Rep, class _Period>
 void
diff --git a/include/tuple b/include/tuple
index 0df315e..a1a7bcf 100644
--- a/include/tuple
+++ b/include/tuple
@@ -21,19 +21,19 @@
 class tuple {
 public:
     constexpr tuple();
-    explicit tuple(const T&...);
+    explicit tuple(const T&...);  // constexpr in C++14
     template <class... U>
-        explicit tuple(U&&...);
+        explicit tuple(U&&...);  // constexpr in C++14
     tuple(const tuple&) = default;
     tuple(tuple&&) = default;
     template <class... U>
-        tuple(const tuple<U...>&);
+        tuple(const tuple<U...>&);  // constexpr in C++14
     template <class... U>
-        tuple(tuple<U...>&&);
+        tuple(tuple<U...>&&);  // constexpr in C++14
     template <class U1, class U2>
-        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2
+        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
     template <class U1, class U2>
-        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2
+        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
 
     // allocator-extended constructors
     template <class Alloc>
@@ -72,10 +72,10 @@
 
 const unspecified ignore;
 
-template <class... T> tuple<V...>  make_tuple(T&&...);
-template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
+template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
+template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
 template <class... T> tuple<T&...> tie(T&...) noexcept;
-template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
+template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
   
 // 20.4.1.4, tuple helper classes:
 template <class T> class tuple_size; // undefined
@@ -86,21 +86,28 @@
 // 20.4.1.5, element access:
 template <intsize_t I, class... T>
     typename tuple_element<I, tuple<T...>>::type&
-    get(tuple<T...>&) noexcept;
+    get(tuple<T...>&) noexcept; // constexpr in C++14
 template <intsize_t I, class... T>
     typename tuple_element<I, tuple<T...>>::type const&
-    get(const tuple<T...>&) noexcept;
+    get(const tuple<T...>&) noexcept; // constexpr in C++14
 template <intsize_t I, class... T>
     typename tuple_element<I, tuple<T...>>::type&&
-    get(tuple<T...>&&) noexcept;
+    get(tuple<T...>&&) noexcept; // constexpr in C++14
+
+template <class T1, class... T>
+    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
+template <class T1, class... T>
+    constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14
+template <class T1, class... T>
+    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
 
 // 20.4.1.6, relational operators:
-template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
-template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);
-template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&);
-template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);
-template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&);
-template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&);
+template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
+template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
+template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
+template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
+template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
+template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
 
 template <class... Types, class Alloc>
   struct uses_allocator<tuple<Types...>, Alloc>;
@@ -126,74 +133,12 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-// allocator_arg_t
-
-struct _LIBCPP_TYPE_VIS allocator_arg_t { };
-
-#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
-extern const allocator_arg_t allocator_arg;
-#else
-constexpr allocator_arg_t allocator_arg = allocator_arg_t();
-#endif
-
-// uses_allocator
-
-template <class _Tp>
-struct __has_allocator_type
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    template <class _Up> static __two __test(...);
-    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
-public:
-    static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
-
-template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
-struct __uses_allocator
-    : public integral_constant<bool,
-        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
-{
-};
-
-template <class _Tp, class _Alloc>
-struct __uses_allocator<_Tp, _Alloc, false>
-    : public false_type
-{
-};
-
-template <class _Tp, class _Alloc>
-struct _LIBCPP_TYPE_VIS uses_allocator
-    : public __uses_allocator<_Tp, _Alloc>
-{
-};
-
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
-// uses-allocator construction
-
-template <class _Tp, class _Alloc, class ..._Args>
-struct __uses_alloc_ctor_imp
-{
-    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
-    static const bool __ic =
-        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
-    static const int value = __ua ? 2 - __ic : 0;
-};
-
-template <class _Tp, class _Alloc, class ..._Args>
-struct __uses_alloc_ctor
-    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
-    {};
-
-#endif  // _LIBCPP_HAS_NO_VARIADICS
-
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
 // tuple_size
 
 template <class ..._Tp>
-class _LIBCPP_TYPE_VIS tuple_size<tuple<_Tp...> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> >
     : public integral_constant<size_t, sizeof...(_Tp)>
 {
 };
@@ -201,7 +146,7 @@
 // tuple_element
 
 template <size_t _Ip, class ..._Tp>
-class _LIBCPP_TYPE_VIS tuple_element<_Ip, tuple<_Tp...> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> >
 {
 public:
     typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
@@ -259,7 +204,7 @@
 
     template <class _Tp,
               class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
             : value(_VSTD::forward<_Tp>(__t))
         {static_assert(!is_reference<_Hp>::value ||
@@ -316,15 +261,17 @@
                                 >::value)),
        "Attempted to construct a reference element in a tuple with an rvalue");}
 
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
     __tuple_leaf(const __tuple_leaf& __t) _NOEXCEPT_(is_nothrow_copy_constructible<_Hp>::value)
         : value(__t.get())
         {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
 
-    template <class _Tp>
-        _LIBCPP_INLINE_VISIBILITY
-        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
-                           _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
-            : value(__t.get()) {}
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    __tuple_leaf(__tuple_leaf&& __t) _NOEXCEPT_(is_nothrow_move_constructible<_Hp>::value)
+        : value(_VSTD::forward<_Hp>(__t.get()))
+        {}
 
     template <class _Tp>
         _LIBCPP_INLINE_VISIBILITY
@@ -342,8 +289,8 @@
         return 0;
     }
 
-    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return value;}
-    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return value;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
 };
 
 template <size_t _Ip, class _Hp>
@@ -372,7 +319,7 @@
 
     template <class _Tp,
               class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
             : _Hp(_VSTD::forward<_Tp>(__t)) {}
 
@@ -393,12 +340,6 @@
 
     template <class _Tp>
         _LIBCPP_INLINE_VISIBILITY
-        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
-            _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
-            : _Hp(__t.get()) {}
-
-    template <class _Tp>
-        _LIBCPP_INLINE_VISIBILITY
         __tuple_leaf&
         operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
         {
@@ -414,8 +355,8 @@
         return 0;
     }
 
-    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
-    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
 };
 
 template <class ..._Tp>
@@ -450,7 +391,7 @@
 
     template <size_t ..._Uf, class ..._Tf,
               size_t ..._Ul, class ..._Tl, class ..._Up>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit
         __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
                      __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
@@ -480,7 +421,7 @@
                          __tuple_constructible<_Tuple, tuple<_Tp...> >::value
                       >::type
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
                                        typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
             : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
@@ -516,13 +457,24 @@
             return *this;
         }
 
-        _LIBCPP_INLINE_VISIBILITY
-        __tuple_impl&
-        operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
-        {
-            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
-            return *this;
-        }
+    __tuple_impl(const __tuple_impl&) = default;
+    __tuple_impl(__tuple_impl&&) = default;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tuple_impl&
+    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
+    {
+        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tuple_impl&
+    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
+    {
+        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
+        return *this;
+    }
 
     _LIBCPP_INLINE_VISIBILITY
     void swap(__tuple_impl& __t)
@@ -533,17 +485,17 @@
 };
 
 template <class ..._Tp>
-class _LIBCPP_TYPE_VIS tuple
+class _LIBCPP_TYPE_VIS_ONLY tuple
 {
     typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
 
     base base_;
 
-    template <size_t _Jp, class ..._Up> friend
+    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
         typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
-    template <size_t _Jp, class ..._Up> friend
+    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
         const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
-    template <size_t _Jp, class ..._Up> friend
+    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
         typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
 public:
 
@@ -551,7 +503,7 @@
     _LIBCPP_CONSTEXPR tuple()
         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
         : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
                 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
@@ -586,7 +538,7 @@
                          bool
                       >::type = false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         tuple(_Up&&... __u)
             _NOEXCEPT_((
                 is_nothrow_constructible<
@@ -626,7 +578,7 @@
                          bool
                       >::type =false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit
         tuple(_Up&&... __u)
             _NOEXCEPT_((
@@ -674,7 +626,7 @@
                          bool
                       >::type = false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
             : base_(_VSTD::forward<_Tuple>(__t)) {}
 
@@ -686,7 +638,7 @@
                          bool
                       >::type = false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit
         tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
             : base_(_VSTD::forward<_Tuple>(__t)) {}
@@ -721,7 +673,7 @@
 };
 
 template <>
-class _LIBCPP_TYPE_VIS tuple<>
+class _LIBCPP_TYPE_VIS_ONLY tuple<>
 {
 public:
     _LIBCPP_INLINE_VISIBILITY
@@ -756,7 +708,7 @@
 // get
 
 template <size_t _Ip, class ..._Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, tuple<_Tp...> >::type&
 get(tuple<_Tp...>& __t) _NOEXCEPT
 {
@@ -765,7 +717,7 @@
 }
 
 template <size_t _Ip, class ..._Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
 get(const tuple<_Tp...>& __t) _NOEXCEPT
 {
@@ -774,7 +726,7 @@
 }
 
 template <size_t _Ip, class ..._Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
 get(tuple<_Tp...>&& __t) _NOEXCEPT
 {
@@ -783,6 +735,64 @@
              static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
 }
 
+#if _LIBCPP_STD_VER > 11
+// get by type
+template <typename _T1, size_t _Idx, typename... _Args>
+struct __find_exactly_one_t_helper;
+
+// -- find exactly one
+template <typename _T1, size_t _Idx, typename... _Args>
+struct __find_exactly_one_t_checker {
+    static constexpr size_t value = _Idx;
+//  Check the rest of the list to make sure there's only one
+    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
+    };
+
+
+template <typename _T1, size_t _Idx>
+struct __find_exactly_one_t_helper <_T1, _Idx> {
+    static constexpr size_t value = -1;
+    };
+
+template <typename _T1, size_t _Idx, typename _Head, typename... _Args>
+struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
+    static constexpr size_t value =
+        std::conditional<
+            std::is_same<_T1, _Head>::value,
+            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
+            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
+        >::type::value;
+    };
+
+template <typename _T1, typename... _Args>
+struct __find_exactly_one_t {
+    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
+    static_assert ( value != -1, "type not found in type list" );
+    };
+
+template <class _T1, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1& get(tuple<_Args...>& __tup) noexcept
+{
+    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
+}
+
+template <class _T1, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
+{
+    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
+}
+
+template <class _T1, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
+{
+    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
+}
+
+#endif
+
 // tie
 
 template <class ..._Tp>
@@ -803,7 +813,7 @@
 
 namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
 
-template <class _Tp> class _LIBCPP_TYPE_VIS reference_wrapper;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
 
 template <class _Tp>
 struct ___make_tuple_return
@@ -824,7 +834,7 @@
 };
 
 template <class... _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 tuple<typename __make_tuple_return<_Tp>::type...>
 make_tuple(_Tp&&... __t)
 {
@@ -832,7 +842,7 @@
 }
 
 template <class... _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 tuple<_Tp&&...>
 forward_as_tuple(_Tp&&... __t) _NOEXCEPT
 {
@@ -843,7 +853,7 @@
 struct __tuple_equal
 {
     template <class _Tp, class _Up>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     bool operator()(const _Tp& __x, const _Up& __y)
     {
         return __tuple_equal<_Ip - 1>()(__x, __y) && get<_Ip-1>(__x) == get<_Ip-1>(__y);
@@ -854,7 +864,7 @@
 struct __tuple_equal<0>
 {
     template <class _Tp, class _Up>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     bool operator()(const _Tp&, const _Up&)
     {
         return true;
@@ -862,7 +872,7 @@
 };
 
 template <class ..._Tp, class ..._Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
 {
@@ -870,7 +880,7 @@
 }
 
 template <class ..._Tp, class ..._Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
 {
@@ -881,7 +891,7 @@
 struct __tuple_less
 {
     template <class _Tp, class _Up>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     bool operator()(const _Tp& __x, const _Up& __y)
     {
         return __tuple_less<_Ip-1>()(__x, __y) ||
@@ -893,7 +903,7 @@
 struct __tuple_less<0>
 {
     template <class _Tp, class _Up>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     bool operator()(const _Tp&, const _Up&)
     {
         return false;
@@ -901,7 +911,7 @@
 };
 
 template <class ..._Tp, class ..._Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
 {
@@ -909,7 +919,7 @@
 }
 
 template <class ..._Tp, class ..._Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
 {
@@ -917,7 +927,7 @@
 }
 
 template <class ..._Tp, class ..._Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
 {
@@ -925,7 +935,7 @@
 }
 
 template <class ..._Tp, class ..._Up>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
 {
@@ -983,7 +993,7 @@
     typedef tuple<> type;
 };
 
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 tuple<>
 tuple_cat()
 {
@@ -1030,16 +1040,16 @@
 struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
 {
     template <class _Tuple0>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
     operator()(tuple<_Types...> __t, _Tuple0&& __t0)
     {
-        return _VSTD::forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))...,
+        return forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))...,
                                       get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
     }
 
     template <class _Tuple0, class _Tuple1, class ..._Tuples>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
     operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
     {
@@ -1049,7 +1059,7 @@
            tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
            typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
-                           (_VSTD::forward_as_tuple(
+                           (forward_as_tuple(
                               _VSTD::forward<_Types>(get<_I0>(__t))...,
                               get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
                             ),
@@ -1059,7 +1069,7 @@
 };
 
 template <class _Tuple0, class... _Tuples>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename __tuple_cat_return<_Tuple0, _Tuples...>::type
 tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
 {
@@ -1071,7 +1081,7 @@
 }
 
 template <class ..._Tp, class _Alloc>
-struct _LIBCPP_TYPE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc>
     : true_type {};
 
 template <class _T1, class _T2>
diff --git a/include/type_traits b/include/type_traits
index ab0e222..c4afe5e 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -28,6 +28,7 @@
 
     // Primary classification traits:
     template <class T> struct is_void;
+    template <class T> struct is_null_pointer;  // C++14
     template <class T> struct is_integral;
     template <class T> struct is_floating_point;
     template <class T> struct is_array;
@@ -137,6 +138,64 @@
     template <class> class result_of; // undefined
     template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>;
 
+    // const-volatile modifications:
+    template <class T>
+      using remove_const_t    = typename remove_const<T>::type;  // C++14
+    template <class T>
+      using remove_volatile_t = typename remove_volatile<T>::type;  // C++14
+    template <class T>
+      using remove_cv_t       = typename remove_cv<T>::type;  // C++14
+    template <class T>
+      using add_const_t       = typename add_const<T>::type;  // C++14
+    template <class T>
+      using add_volatile_t    = typename add_volatile<T>::type;  // C++14
+    template <class T>
+      using add_cv_t          = typename add_cv<T>::type;  // C++14
+  
+    // reference modifications:
+    template <class T>
+      using remove_reference_t     = typename remove_reference<T>::type;  // C++14
+    template <class T>
+      using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;  // C++14
+    template <class T>
+      using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;  // C++14
+  
+    // sign modifications:
+    template <class T>
+      using make_signed_t   = typename make_signed<T>::type;  // C++14
+    template <class T>
+      using make_unsigned_t = typename make_unsigned<T>::type;  // C++14
+  
+    // array modifications:
+    template <class T>
+      using remove_extent_t      = typename remove_extent<T>::type;  // C++14
+    template <class T>
+      using remove_all_extents_t = typename remove_all_extents<T>::type;  // C++14
+
+    // pointer modifications:
+    template <class T>
+      using remove_pointer_t = typename remove_pointer<T>::type;  // C++14
+    template <class T>
+      using add_pointer_t    = typename add_pointer<T>::type;  // C++14
+
+    // other transformations:
+    template <size_t Len, std::size_t Align=default-alignment>
+      using aligned_storage_t = typename aligned_storage<Len,Align>::type;  // C++14
+    template <std::size_t Len, class... Types>
+      using aligned_union_t   = typename aligned_union<Len,Types...>::type;  // C++14
+    template <class T>
+      using decay_t           = typename decay<T>::type;  // C++14
+    template <bool b, class T=void>
+      using enable_if_t       = typename enable_if<b,T>::type;  // C++14
+    template <bool b, class T, class F>
+      using conditional_t     = typename conditional<b,T,F>::type;  // C++14
+    template <class... T>
+      using common_type_t     = typename common_type<T...>::type;  // C++14
+    template <class T>
+      using underlying_type_t = typename underlying_type<T>::type;  // C++14
+    template <class F, class... ArgTypes>
+      using result_of_t       = typename result_of<F(ArgTypes...)>::type;  // C++14
+
 }  // std
 
 */
@@ -150,25 +209,38 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <bool _Bp, class _If, class _Then>
-    struct _LIBCPP_TYPE_VIS conditional {typedef _If type;};
+    struct _LIBCPP_TYPE_VIS_ONLY conditional {typedef _If type;};
 template <class _If, class _Then>
-    struct _LIBCPP_TYPE_VIS conditional<false, _If, _Then> {typedef _Then type;};
+    struct _LIBCPP_TYPE_VIS_ONLY conditional<false, _If, _Then> {typedef _Then type;};
 
-template <bool, class _Tp = void> struct _LIBCPP_TYPE_VIS enable_if {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS enable_if<true, _Tp> {typedef _Tp type;};
+#if _LIBCPP_STD_VER > 11
+template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
+#endif
+
+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;};
+
+#if _LIBCPP_STD_VER > 11
+template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
+#endif
+
 
 struct __two {char __lx[2];};
 
 // helper class:
 
 template <class _Tp, _Tp __v>
-struct _LIBCPP_TYPE_VIS integral_constant
+struct _LIBCPP_TYPE_VIS_ONLY integral_constant
 {
     static _LIBCPP_CONSTEXPR const _Tp      value = __v;
     typedef _Tp               value_type;
     typedef integral_constant type;
     _LIBCPP_INLINE_VISIBILITY
         _LIBCPP_CONSTEXPR operator value_type() const {return value;}
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY
+         constexpr value_type operator ()() const {return value;}
+#endif
 };
 
 template <class _Tp, _Tp __v>
@@ -179,35 +251,44 @@
 
 // is_const
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_const            : public false_type {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_const<_Tp const> : public true_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const            : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const<_Tp const> : public true_type {};
 
 // is_volatile
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_volatile               : public false_type {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_volatile<_Tp volatile> : public true_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile               : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile<_Tp volatile> : public true_type {};
 
 // remove_const
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_const            {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_const<const _Tp> {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const            {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const<const _Tp> {typedef _Tp type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;
+#endif
 
 // remove_volatile
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_volatile               {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile               {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile<volatile _Tp> {typedef _Tp type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;
+#endif
 
 // remove_cv
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_cv
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_cv
 {typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;
+#endif
 
 // is_void
 
 template <class _Tp> struct __is_void       : public false_type {};
 template <>          struct __is_void<void> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_void
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void
     : public __is_void<typename remove_cv<_Tp>::type> {};
 
 // __is_nullptr_t
@@ -215,9 +296,14 @@
 template <class _Tp> struct ____is_nullptr_t       : public false_type {};
 template <>          struct ____is_nullptr_t<nullptr_t> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS __is_nullptr_t
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __is_nullptr_t
     : public ____is_nullptr_t<typename remove_cv<_Tp>::type> {};
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_null_pointer
+    : public ____is_nullptr_t<typename remove_cv<_Tp>::type> {};
+#endif
+
 // is_integral
 
 template <class _Tp> struct __is_integral                     : public false_type {};
@@ -239,7 +325,7 @@
 template <>          struct __is_integral<long long>          : public true_type {};
 template <>          struct __is_integral<unsigned long long> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_integral
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_integral
     : public __is_integral<typename remove_cv<_Tp>::type> {};
 
 // is_floating_point
@@ -249,16 +335,16 @@
 template <>          struct __is_floating_point<double>      : public true_type {};
 template <>          struct __is_floating_point<long double> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_floating_point
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_floating_point
     : public __is_floating_point<typename remove_cv<_Tp>::type> {};
 
 // is_array
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_array
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array
     : public false_type {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_array<_Tp[]>
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[]>
     : public true_type {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS is_array<_Tp[_Np]>
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[_Np]>
     : public true_type {};
 
 // is_pointer
@@ -266,23 +352,23 @@
 template <class _Tp> struct __is_pointer       : public false_type {};
 template <class _Tp> struct __is_pointer<_Tp*> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_pointer
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pointer
     : public __is_pointer<typename remove_cv<_Tp>::type> {};
 
 // is_reference
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_lvalue_reference       : public false_type {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_lvalue_reference<_Tp&> : public true_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference       : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference<_Tp&> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_rvalue_reference        : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference        : public false_type {};
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_rvalue_reference<_Tp&&> : public true_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference<_Tp&&> : public true_type {};
 #endif
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_reference        : public false_type {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_reference<_Tp&>  : public true_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference        : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&>  : public true_type {};
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_reference<_Tp&&> : public true_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&&> : public true_type {};
 #endif
 
 #if defined(__clang__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
@@ -293,13 +379,13 @@
 
 #if __has_feature(is_union) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_union
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union
     : public integral_constant<bool, __is_union(_Tp)> {};
 
 #else
 
 template <class _Tp> struct __libcpp_union : public false_type {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_union
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union
     : public __libcpp_union<typename remove_cv<_Tp>::type> {};
 
 #endif
@@ -308,7 +394,7 @@
 
 #if __has_feature(is_class) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_class
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class
     : public integral_constant<bool, __is_class(_Tp)> {};
 
 #else
@@ -319,15 +405,15 @@
 template <class _Tp> __two __test(...);
 }
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_class
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class
     : public integral_constant<bool, sizeof(__is_class_imp::__test<_Tp>(0)) == 1 && !is_union<_Tp>::value> {};
 
 #endif
 
 // is_same
 
-template <class _Tp, class _Up> struct _LIBCPP_TYPE_VIS is_same           : public false_type {};
-template <class _Tp>            struct _LIBCPP_TYPE_VIS is_same<_Tp, _Tp> : public true_type {};
+template <class _Tp, class _Up> struct _LIBCPP_TYPE_VIS_ONLY is_same           : public false_type {};
+template <class _Tp>            struct _LIBCPP_TYPE_VIS_ONLY is_same<_Tp, _Tp> : public true_type {};
 
 // is_function
 
@@ -342,13 +428,13 @@
                             is_union<_Tp>::value ||
                             is_void<_Tp>::value  ||
                             is_reference<_Tp>::value ||
-                            is_same<_Tp, nullptr_t>::value >
+                            __is_nullptr_t<_Tp>::value >
 struct __is_function
     : public integral_constant<bool, sizeof(__is_function_imp::__test<_Tp>(__is_function_imp::__source<_Tp>())) == 1>
     {};
 template <class _Tp> struct __is_function<_Tp, true> : public false_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_function
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_function
     : public __is_function<_Tp> {};
 
 // is_member_function_pointer
@@ -356,7 +442,7 @@
 template <class _Tp> struct            __is_member_function_pointer             : public false_type {};
 template <class _Tp, class _Up> struct __is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_member_function_pointer
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_function_pointer
     : public __is_member_function_pointer<typename remove_cv<_Tp>::type> {};
 
 // is_member_pointer
@@ -364,12 +450,12 @@
 template <class _Tp>            struct __is_member_pointer             : public false_type {};
 template <class _Tp, class _Up> struct __is_member_pointer<_Tp _Up::*> : public true_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_member_pointer
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_pointer
     : public __is_member_pointer<typename remove_cv<_Tp>::type> {};
 
 // is_member_object_pointer
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_member_object_pointer
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_object_pointer
     : public integral_constant<bool, is_member_pointer<_Tp>::value &&
                                     !is_member_function_pointer<_Tp>::value> {};
 
@@ -377,12 +463,12 @@
 
 #if __has_feature(is_enum) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_enum
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum
     : public integral_constant<bool, __is_enum(_Tp)> {};
 
 #else
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_enum
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum
     : public integral_constant<bool, !is_void<_Tp>::value             &&
                                      !is_integral<_Tp>::value         &&
                                      !is_floating_point<_Tp>::value   &&
@@ -398,31 +484,31 @@
 
 // is_arithmetic
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_arithmetic
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_arithmetic
     : public integral_constant<bool, is_integral<_Tp>::value      ||
                                      is_floating_point<_Tp>::value> {};
 
 // is_fundamental
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_fundamental
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_fundamental
     : public integral_constant<bool, is_void<_Tp>::value        ||
                                      __is_nullptr_t<_Tp>::value ||
                                      is_arithmetic<_Tp>::value> {};
 
 // is_scalar
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_scalar
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_scalar
     : public integral_constant<bool, is_arithmetic<_Tp>::value     ||
                                      is_member_pointer<_Tp>::value ||
                                      is_pointer<_Tp>::value        ||
                                      __is_nullptr_t<_Tp>::value    ||
                                      is_enum<_Tp>::value           > {};
 
-template <> struct _LIBCPP_TYPE_VIS is_scalar<nullptr_t> : public true_type {};
+template <> struct _LIBCPP_TYPE_VIS_ONLY is_scalar<nullptr_t> : public true_type {};
 
 // is_object
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_object
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_object
     : public integral_constant<bool, is_scalar<_Tp>::value ||
                                      is_array<_Tp>::value  ||
                                      is_union<_Tp>::value  ||
@@ -430,7 +516,7 @@
 
 // is_compound
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_compound
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_compound
     : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
 
 // add_const
@@ -443,9 +529,13 @@
 template <class _Tp>
 struct __add_const<_Tp, false> {typedef const _Tp type;};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS add_const
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_const
     {typedef typename __add_const<_Tp>::type type;};
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
+#endif
+
 // add_volatile
 
 template <class _Tp, bool = is_reference<_Tp>::value ||
@@ -456,38 +546,58 @@
 template <class _Tp>
 struct __add_volatile<_Tp, false> {typedef volatile _Tp type;};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS add_volatile
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_volatile
     {typedef typename __add_volatile<_Tp>::type type;};
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
+#endif
+
 // add_cv
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS add_cv
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_cv
     {typedef typename add_const<typename add_volatile<_Tp>::type>::type type;};
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
+#endif
+
 // remove_reference
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_reference        {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_reference<_Tp&>  {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference        {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&>  {typedef _Tp type;};
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_reference<_Tp&&> {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&&> {typedef _Tp type;};
+#endif
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;
 #endif
 
 // add_lvalue_reference
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS add_lvalue_reference                      {typedef _Tp& type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS add_lvalue_reference<_Tp&>                {typedef _Tp& type;};  // for older compiler
-template <>          struct _LIBCPP_TYPE_VIS add_lvalue_reference<void>                {typedef void type;};
-template <>          struct _LIBCPP_TYPE_VIS add_lvalue_reference<const void>          {typedef const void type;};
-template <>          struct _LIBCPP_TYPE_VIS add_lvalue_reference<volatile void>       {typedef volatile void type;};
-template <>          struct _LIBCPP_TYPE_VIS add_lvalue_reference<const volatile void> {typedef const volatile void type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference                      {typedef _Tp& type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<_Tp&>                {typedef _Tp& type;};  // for older compiler
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<void>                {typedef void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const void>          {typedef const void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<volatile void>       {typedef volatile void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const volatile void> {typedef const volatile void type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
+#endif
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS  add_rvalue_reference                     {typedef _Tp&& type;};
-template <>          struct _LIBCPP_TYPE_VIS add_rvalue_reference<void>                {typedef void type;};
-template <>          struct _LIBCPP_TYPE_VIS add_rvalue_reference<const void>          {typedef const void type;};
-template <>          struct _LIBCPP_TYPE_VIS add_rvalue_reference<volatile void>       {typedef volatile void type;};
-template <>          struct _LIBCPP_TYPE_VIS add_rvalue_reference<const volatile void> {typedef const volatile void type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY  add_rvalue_reference                     {typedef _Tp&& type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<void>                {typedef void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const void>          {typedef const void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<volatile void>       {typedef volatile void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const volatile void> {typedef const volatile void type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
+#endif
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
@@ -512,17 +622,25 @@
 
 // remove_pointer
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_pointer                      {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_pointer<_Tp*>                {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_pointer<_Tp* const>          {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_pointer<_Tp* volatile>       {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_pointer<_Tp* const volatile> {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer                      {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp*>                {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const>          {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* volatile>       {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const volatile> {typedef _Tp type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type;
+#endif
 
 // add_pointer
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS add_pointer
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer
     {typedef typename remove_reference<_Tp>::type* type;};
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type;
+#endif
+
 // is_signed
 
 template <class _Tp, bool = is_integral<_Tp>::value>
@@ -536,7 +654,7 @@
 
 template <class _Tp> struct __is_signed<_Tp, false> : public false_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_signed : public __is_signed<_Tp> {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_signed : public __is_signed<_Tp> {};
 
 // is_unsigned
 
@@ -551,48 +669,81 @@
 
 template <class _Tp> struct __is_unsigned<_Tp, false> : public false_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_unsigned : public __is_unsigned<_Tp> {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_unsigned : public __is_unsigned<_Tp> {};
 
 // rank
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS rank
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank
     : public integral_constant<size_t, 0> {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS rank<_Tp[]>
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[]>
     : public integral_constant<size_t, rank<_Tp>::value + 1> {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS rank<_Tp[_Np]>
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[_Np]>
     : public integral_constant<size_t, rank<_Tp>::value + 1> {};
 
 // extent
 
-template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TYPE_VIS extent
+template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TYPE_VIS_ONLY extent
     : public integral_constant<size_t, 0> {};
-template <class _Tp> struct _LIBCPP_TYPE_VIS extent<_Tp[], 0>
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], 0>
     : public integral_constant<size_t, 0> {};
-template <class _Tp, unsigned _Ip> struct _LIBCPP_TYPE_VIS extent<_Tp[], _Ip>
+template <class _Tp, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], _Ip>
     : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
-template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS extent<_Tp[_Np], 0>
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], 0>
     : public integral_constant<size_t, _Np> {};
-template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TYPE_VIS extent<_Tp[_Np], _Ip>
+template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], _Ip>
     : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
 
 // remove_extent
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_extent
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent
     {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_extent<_Tp[]>
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[]>
     {typedef _Tp type;};
-template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS remove_extent<_Tp[_Np]>
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[_Np]>
     {typedef _Tp type;};
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_extent_t = typename remove_extent<_Tp>::type;
+#endif
+
 // remove_all_extents
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_all_extents
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents
     {typedef _Tp type;};
-template <class _Tp> struct _LIBCPP_TYPE_VIS remove_all_extents<_Tp[]>
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[]>
     {typedef typename remove_all_extents<_Tp>::type type;};
-template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS remove_all_extents<_Tp[_Np]>
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[_Np]>
     {typedef typename remove_all_extents<_Tp>::type type;};
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
+#endif
+
+// decay
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY decay
+{
+private:
+    typedef typename remove_reference<_Tp>::type _Up;
+public:
+    typedef typename conditional
+                     <
+                         is_array<_Up>::value,
+                         typename remove_extent<_Up>::type*,
+                         typename conditional
+                         <
+                              is_function<_Up>::value,
+                              typename add_pointer<_Up>::type,
+                              typename remove_cv<_Up>::type
+                         >::type
+                     >::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using decay_t = typename decay<_Tp>::type;
+#endif
+
 // is_abstract
 
 namespace __is_abstract_imp
@@ -606,14 +757,14 @@
 
 template <class _Tp> struct __libcpp_abstract<_Tp, false> : public false_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_abstract : public __libcpp_abstract<_Tp> {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_abstract : public __libcpp_abstract<_Tp> {};
 
 // is_base_of
 
-#ifdef _LIBCP_HAS_IS_BASE_OF
+#ifdef _LIBCPP_HAS_IS_BASE_OF
 
 template <class _Bp, class _Dp>
-struct _LIBCPP_TYPE_VIS is_base_of
+struct _LIBCPP_TYPE_VIS_ONLY is_base_of
     : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
 
 #else  // __has_feature(is_base_of)
@@ -637,7 +788,7 @@
 }
 
 template <class _Bp, class _Dp>
-struct _LIBCPP_TYPE_VIS is_base_of
+struct _LIBCPP_TYPE_VIS_ONLY is_base_of
     : public integral_constant<bool, is_class<_Bp>::value &&
                                      sizeof(__is_base_of_imp::__test<_Bp, _Dp>(0)) == 2> {};
 
@@ -647,7 +798,7 @@
 
 #if __has_feature(is_convertible_to)
 
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS is_convertible
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible
     : public integral_constant<bool, __is_convertible_to(_T1, _T2) &&
                                      !is_abstract<_T2>::value> {};
 
@@ -753,7 +904,7 @@
 template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};
 template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {};
 
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS is_convertible
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible
     : public __is_convertible<_T1, _T2>
 {
     static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
@@ -767,7 +918,7 @@
 #if __has_feature(is_empty)
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_empty
+struct _LIBCPP_TYPE_VIS_ONLY is_empty
     : public integral_constant<bool, __is_empty(_Tp)> {};
 
 #else  // __has_feature(is_empty)
@@ -789,7 +940,7 @@
 
 template <class _Tp> struct __libcpp_empty<_Tp, false> : public false_type {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_empty : public __libcpp_empty<_Tp> {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_empty : public __libcpp_empty<_Tp> {};
 
 #endif  // __has_feature(is_empty)
 
@@ -798,7 +949,7 @@
 #if __has_feature(is_polymorphic)
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_polymorphic
+struct _LIBCPP_TYPE_VIS_ONLY is_polymorphic
     : public integral_constant<bool, __is_polymorphic(_Tp)> {};
 
 #else
@@ -808,7 +959,7 @@
                        int>::type);
 template<typename _Tp> __two &__is_polymorphic_impl(...);
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_polymorphic
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_polymorphic
     : public integral_constant<bool, sizeof(__is_polymorphic_impl<_Tp>(0)) == 1> {};
 
 #endif // __has_feature(is_polymorphic)
@@ -817,19 +968,19 @@
 
 #if __has_feature(has_virtual_destructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS has_virtual_destructor
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor
     : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
 
 #else  // _LIBCPP_HAS_TYPE_TRAITS
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS has_virtual_destructor
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor
     : public false_type {};
 
 #endif  // _LIBCPP_HAS_TYPE_TRAITS
 
 // alignment_of
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS alignment_of
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY alignment_of
     : public integral_constant<size_t, __alignof__(_Tp)> {};
 
 // aligned_storage
@@ -916,8 +1067,8 @@
 struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
     : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
 
-template <size_t _Len, const size_t _Align = __find_max_align<__all_types, _Len>::value>
-struct _LIBCPP_TYPE_VIS aligned_storage
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+struct _LIBCPP_TYPE_VIS_ONLY aligned_storage
 {
     typedef typename __find_pod<__all_types, _Align>::type _Aligner;
     static_assert(!is_void<_Aligner>::value, "");
@@ -928,9 +1079,14 @@
     };
 };
 
+#if _LIBCPP_STD_VER > 11
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+    using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
+#endif
+
 #define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
 template <size_t _Len>\
-struct _LIBCPP_TYPE_VIS aligned_storage<_Len, n>\
+struct _LIBCPP_TYPE_VIS_ONLY aligned_storage<_Len, n>\
 {\
     struct _ALIGNAS(n) type\
     {\
@@ -953,9 +1109,9 @@
 _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000);
 _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000);
 // MSDN says that MSVC does not support alignment beyond 8192 (=0x2000)
-#if !defined(_MSC_VER)
+#if !defined(_LIBCPP_MSVC)
 _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000);
-#endif // !_MSC_VER
+#endif // !_LIBCPP_MSVC
 
 #undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION
 
@@ -989,6 +1145,10 @@
     typedef typename aligned_storage<__len, alignment_value>::type type;
 };
 
+#if _LIBCPP_STD_VER > 11
+template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
+#endif
+
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
 // __promote
@@ -1145,11 +1305,15 @@
 template <> struct __make_signed<unsigned long long, true> {typedef long long type;};
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS make_signed
+struct _LIBCPP_TYPE_VIS_ONLY make_signed
 {
     typedef typename __apply_cv<_Tp, typename __make_signed<typename remove_cv<_Tp>::type>::type>::type type;
 };
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using make_signed_t = typename make_signed<_Tp>::type;
+#endif
+
 template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
 struct __make_unsigned {};
 
@@ -1170,29 +1334,33 @@
 template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;};
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS make_unsigned
+struct _LIBCPP_TYPE_VIS_ONLY make_unsigned
 {
     typedef typename __apply_cv<_Tp, typename __make_unsigned<typename remove_cv<_Tp>::type>::type>::type type;
 };
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;
+#endif
+
 #ifdef _LIBCPP_HAS_NO_VARIADICS
 
 template <class _Tp, class _Up = void, class V = void>
-struct _LIBCPP_TYPE_VIS common_type
+struct _LIBCPP_TYPE_VIS_ONLY common_type
 {
 public:
     typedef typename common_type<typename common_type<_Tp, _Up>::type, V>::type type;
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS common_type<_Tp, void, void>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, void, void>
 {
 public:
     typedef _Tp type;
 };
 
 template <class _Tp, class _Up>
-struct _LIBCPP_TYPE_VIS common_type<_Tp, _Up, void>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, void>
 {
 private:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1211,34 +1379,40 @@
 template <class ..._Tp> struct common_type;
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS common_type<_Tp>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp>
 {
-    typedef _Tp type;
+    typedef typename decay<_Tp>::type type;
 };
 
 template <class _Tp, class _Up>
-struct _LIBCPP_TYPE_VIS common_type<_Tp, _Up>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up>
 {
 private:
     static _Tp&& __t();
     static _Up&& __u();
     static bool __f();
 public:
-    typedef typename remove_reference<decltype(__f() ? __t() : __u())>::type type;
+    typedef typename decay<decltype(__f() ? __t() : __u())>::type type;
 };
 
 template <class _Tp, class _Up, class ..._Vp>
-struct _LIBCPP_TYPE_VIS common_type<_Tp, _Up, _Vp...>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, _Vp...>
 {
     typedef typename common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
 };
 
+#if _LIBCPP_STD_VER > 11
+template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
+#endif
+
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
 // is_assignable
 
+template<typename, typename T> struct __select_2nd { typedef T type; };
+
 template <class _Tp, class _Arg>
-decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>(), true_type()))
+typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 __is_assignable_test(_Tp&&, _Arg&&);
 #else
@@ -1272,13 +1446,13 @@
 
 // is_copy_assignable
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_copy_assignable
+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> {};
 
 // is_move_assignable
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_move_assignable
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_move_assignable
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     : public is_assignable<typename add_lvalue_reference<_Tp>::type,
                      const typename add_rvalue_reference<_Tp>::type> {};
@@ -1305,7 +1479,8 @@
 false_type
 __is_destructible_test(__any);
 
-template <class _Tp, bool = is_void<_Tp>::value || is_abstract<_Tp>::value>
+template <class _Tp, bool = is_void<_Tp>::value || is_abstract<_Tp>::value
+                                                || is_function<_Tp>::value>
 struct __destructible_imp
     : public common_type
         <
@@ -1320,12 +1495,16 @@
 struct is_destructible
     : public __destructible_imp<_Tp> {};
 
+template <class _Tp>
+struct is_destructible<_Tp[]>
+    : public false_type {};
+
 // move
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename remove_reference<_Tp>::type&&
 move(_Tp&& __t) _NOEXCEPT
 {
@@ -1334,7 +1513,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&&
 forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT
 {
@@ -1342,7 +1521,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp&&
 forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT
 {
@@ -1392,25 +1571,6 @@
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-template <class _Tp>
-struct _LIBCPP_TYPE_VIS decay
-{
-private:
-    typedef typename remove_reference<_Tp>::type _Up;
-public:
-    typedef typename conditional
-                     <
-                         is_array<_Up>::value,
-                         typename remove_extent<_Up>::type*,
-                         typename conditional
-                         <
-                              is_function<_Up>::value,
-                              typename add_pointer<_Up>::type,
-                              typename remove_cv<_Up>::type
-                         >::type
-                     >::type type;
-};
-
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
@@ -1653,7 +1813,7 @@
 
 template <class _MP>
 struct __member_pointer_traits
-    : public __member_pointer_traits_imp<_MP,
+    : public __member_pointer_traits_imp<typename remove_cv<_MP>::type,
                     is_member_function_pointer<_MP>::value,
                     is_member_object_pointer<_MP>::value>
 {
@@ -1772,7 +1932,7 @@
 // result_of
 
 template <class _Fn>
-class _LIBCPP_TYPE_VIS result_of<_Fn()>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn()>
     : public __result_of<_Fn(),
                          is_class<typename remove_reference<_Fn>::type>::value ||
                          is_function<typename remove_reference<_Fn>::type>::value,
@@ -1782,7 +1942,7 @@
 };
 
 template <class _Fn, class _A0>
-class _LIBCPP_TYPE_VIS result_of<_Fn(_A0)>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0)>
     : public __result_of<_Fn(_A0),
                          is_class<typename remove_reference<_Fn>::type>::value ||
                          is_function<typename remove_reference<_Fn>::type>::value,
@@ -1792,7 +1952,7 @@
 };
 
 template <class _Fn, class _A0, class _A1>
-class _LIBCPP_TYPE_VIS result_of<_Fn(_A0, _A1)>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1)>
     : public __result_of<_Fn(_A0, _A1),
                          is_class<typename remove_reference<_Fn>::type>::value ||
                          is_function<typename remove_reference<_Fn>::type>::value,
@@ -1802,7 +1962,7 @@
 };
 
 template <class _Fn, class _A0, class _A1, class _A2>
-class _LIBCPP_TYPE_VIS result_of<_Fn(_A0, _A1, _A2)>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1, _A2)>
     : public __result_of<_Fn(_A0, _A1, _A2),
                          is_class<typename remove_reference<_Fn>::type>::value ||
                          is_function<typename remove_reference<_Fn>::type>::value,
@@ -1819,8 +1979,6 @@
 
 //      main is_constructible test
 
-template<typename, typename T> struct __select_2nd { typedef T type; };
-
 template <class _Tp, class ..._Args>
 typename __select_2nd<decltype(_VSTD::move(_Tp(_VSTD::declval<_Args>()...))), true_type>::type
 __is_constructible_test(_Tp&&, _Args&& ...);
@@ -1907,7 +2065,7 @@
 //      is_constructible entry point
 
 template <class _Tp, class... _Args>
-struct _LIBCPP_TYPE_VIS is_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible
     : public __is_constructible_void_check<__contains_void<_Tp, _Args...>::value
                                         || is_abstract<_Tp>::value,
                                            _Tp, _Args...>
@@ -2055,7 +2213,7 @@
 
 template <class _Tp, class _A0 = __is_construct::__nat,
                      class _A1 = __is_construct::__nat>
-struct _LIBCPP_TYPE_VIS is_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible
     : public __is_constructible2_void_check<is_void<_Tp>::value
                                         || is_abstract<_Tp>::value
                                         || is_function<_Tp>::value
@@ -2065,7 +2223,7 @@
     {};
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_constructible<_Tp, __is_construct::__nat, __is_construct::__nat>
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, __is_construct::__nat, __is_construct::__nat>
     : public __is_constructible0_void_check<is_void<_Tp>::value
                                         || is_abstract<_Tp>::value
                                         || is_function<_Tp>::value,
@@ -2073,7 +2231,7 @@
     {};
 
 template <class _Tp, class _A0>
-struct _LIBCPP_TYPE_VIS is_constructible<_Tp, _A0, __is_construct::__nat>
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, _A0, __is_construct::__nat>
     : public __is_constructible1_void_check<is_void<_Tp>::value
                                         || is_abstract<_Tp>::value
                                         || is_function<_Tp>::value
@@ -2121,21 +2279,21 @@
 // is_default_constructible
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_default_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_default_constructible
     : public is_constructible<_Tp>
     {};
 
 // is_copy_constructible
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_copy_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_copy_constructible
     : public is_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
     {};
 
 // is_move_constructible
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_move_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_move_constructible
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
 #else
@@ -2150,7 +2308,7 @@
 #if __has_feature(is_trivially_constructible)
 
 template <class _Tp, class... _Args>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible
     : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>
 {
 };
@@ -2158,13 +2316,13 @@
 #else  // !__has_feature(is_trivially_constructible)
 
 template <class _Tp, class... _Args>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible
     : false_type
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp>
 #if __has_feature(has_trivial_constructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_trivial_constructor(_Tp)>
 #else
@@ -2175,22 +2333,22 @@
 
 template <class _Tp>
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, _Tp&&>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&&>
 #else
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp>
 #endif
     : integral_constant<bool, is_scalar<_Tp>::value>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, const _Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&>
     : integral_constant<bool, is_scalar<_Tp>::value>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, _Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&>
     : integral_constant<bool, is_scalar<_Tp>::value>
 {
 };
@@ -2201,7 +2359,7 @@
 
 template <class _Tp, class _A0 = __is_construct::__nat,
                      class _A1 = __is_construct::__nat>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible
     : false_type
 {
 };
@@ -2209,28 +2367,28 @@
 #if __has_feature(is_trivially_constructible)
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, __is_construct::__nat,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat,
                                                        __is_construct::__nat>
     : integral_constant<bool, __is_trivially_constructible(_Tp)>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, _Tp,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp,
                                                        __is_construct::__nat>
     : integral_constant<bool, __is_trivially_constructible(_Tp, _Tp)>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, const _Tp&,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&,
                                                        __is_construct::__nat>
     : integral_constant<bool, __is_trivially_constructible(_Tp, const _Tp&)>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, _Tp&,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&,
                                                        __is_construct::__nat>
     : integral_constant<bool, __is_trivially_constructible(_Tp, _Tp&)>
 {
@@ -2239,28 +2397,28 @@
 #else  // !__has_feature(is_trivially_constructible)
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, __is_construct::__nat,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat,
                                                        __is_construct::__nat>
     : integral_constant<bool, is_scalar<_Tp>::value>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, _Tp,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp,
                                                        __is_construct::__nat>
     : integral_constant<bool, is_scalar<_Tp>::value>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, const _Tp&,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&,
                                                        __is_construct::__nat>
     : integral_constant<bool, is_scalar<_Tp>::value>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_trivially_constructible<_Tp, _Tp&,
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&,
                                                        __is_construct::__nat>
     : integral_constant<bool, is_scalar<_Tp>::value>
 {
@@ -2272,19 +2430,19 @@
 
 // is_trivially_default_constructible
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_default_constructible
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_default_constructible
     : public is_trivially_constructible<_Tp>
     {};
 
 // is_trivially_copy_constructible
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_copy_constructible
-    : public is_trivially_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_constructible
+    : public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type>
     {};
 
 // is_trivially_move_constructible
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_move_constructible
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_constructible
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
 #else
@@ -2332,14 +2490,14 @@
 
 // is_trivially_copy_assignable
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_copy_assignable
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_assignable
     : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
                                const typename add_lvalue_reference<_Tp>::type>
     {};
 
 // is_trivially_move_assignable
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_move_assignable
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_assignable
     : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
                                      typename add_rvalue_reference<_Tp>::type>
@@ -2352,7 +2510,7 @@
 
 #if __has_feature(has_trivial_destructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_destructible
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible
     : public integral_constant<bool, __has_trivial_destructor(_Tp)> {};
 
 #else  // _LIBCPP_HAS_TYPE_TRAITS
@@ -2361,7 +2519,7 @@
     : public integral_constant<bool, is_scalar<_Tp>::value ||
                                      is_reference<_Tp>::value> {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_destructible
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible
     : public __libcpp_trivial_destructor<typename remove_all_extents<_Tp>::type> {};
 
 #endif  // _LIBCPP_HAS_TYPE_TRAITS
@@ -2387,13 +2545,13 @@
 };
 
 template <class _Tp, class... _Args>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
     : __is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, _Tp, _Args...>
 {
 };
 
 template <class _Tp, size_t _Ns>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp[_Ns]>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]>
     : __is_nothrow_constructible<is_constructible<_Tp>::value, _Tp>
 {
 };
@@ -2401,13 +2559,13 @@
 #else  // __has_feature(cxx_noexcept)
 
 template <class _Tp, class... _Args>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
     : false_type
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp>
 #if __has_feature(has_nothrow_constructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_constructor(_Tp)>
 #else
@@ -2418,9 +2576,9 @@
 
 template <class _Tp>
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, _Tp&&>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&&>
 #else
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp>
 #endif
 #if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_copy(_Tp)>
@@ -2431,7 +2589,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, const _Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&>
 #if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_copy(_Tp)>
 #else
@@ -2441,7 +2599,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, _Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&>
 #if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_copy(_Tp)>
 #else
@@ -2456,13 +2614,13 @@
 
 template <class _Tp, class _A0 = __is_construct::__nat,
                      class _A1 = __is_construct::__nat>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
     : false_type
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, __is_construct::__nat,
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, __is_construct::__nat,
                                                        __is_construct::__nat>
 #if __has_feature(has_nothrow_constructor) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_constructor(_Tp)>
@@ -2473,7 +2631,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, _Tp,
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp,
                                                        __is_construct::__nat>
 #if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_copy(_Tp)>
@@ -2484,7 +2642,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, const _Tp&,
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&,
                                                        __is_construct::__nat>
 #if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_copy(_Tp)>
@@ -2495,7 +2653,7 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_constructible<_Tp, _Tp&,
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&,
                                                        __is_construct::__nat>
 #if __has_feature(has_nothrow_copy) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_copy(_Tp)>
@@ -2509,19 +2667,19 @@
 
 // is_nothrow_default_constructible
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_nothrow_default_constructible
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_default_constructible
     : public is_nothrow_constructible<_Tp>
     {};
 
 // is_nothrow_copy_constructible
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS 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>
     {};
 
 // is_nothrow_move_constructible
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_nothrow_move_constructible
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_constructible
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
 #else
@@ -2548,7 +2706,7 @@
 };
 
 template <class _Tp, class _Arg>
-struct _LIBCPP_TYPE_VIS is_nothrow_assignable
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable
     : public __is_nothrow_assignable<is_assignable<_Tp, _Arg>::value, _Tp, _Arg>
 {
 };
@@ -2556,11 +2714,11 @@
 #else  // __has_feature(cxx_noexcept)
 
 template <class _Tp, class _Arg>
-struct _LIBCPP_TYPE_VIS is_nothrow_assignable
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable
     : public false_type {};
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_assignable<_Tp&, _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp>
 #if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_assign(_Tp)> {};
 #else
@@ -2568,7 +2726,7 @@
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_assignable<_Tp&, _Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp&>
 #if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_assign(_Tp)> {};
 #else
@@ -2576,7 +2734,7 @@
 #endif
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_assignable<_Tp&, const _Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, const _Tp&>
 #if __has_feature(has_nothrow_assign) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
     : integral_constant<bool, __has_nothrow_assign(_Tp)> {};
 #else
@@ -2599,14 +2757,14 @@
 
 // is_nothrow_copy_assignable
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_nothrow_copy_assignable
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_assignable
     : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
                                const typename add_lvalue_reference<_Tp>::type>
     {};
 
 // is_nothrow_move_assignable
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_nothrow_move_assignable
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_assignable
     : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
                                      typename add_rvalue_reference<_Tp>::type>
@@ -2634,19 +2792,19 @@
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_destructible
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible
     : public __is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>
 {
 };
 
 template <class _Tp, size_t _Ns>
-struct _LIBCPP_TYPE_VIS is_nothrow_destructible<_Tp[_Ns]>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp[_Ns]>
     : public is_nothrow_destructible<_Tp>
 {
 };
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_destructible<_Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&>
     : public true_type
 {
 };
@@ -2654,7 +2812,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp>
-struct _LIBCPP_TYPE_VIS is_nothrow_destructible<_Tp&&>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&&>
     : public true_type
 {
 };
@@ -2667,7 +2825,7 @@
     : public integral_constant<bool, is_scalar<_Tp>::value ||
                                      is_reference<_Tp>::value> {};
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_nothrow_destructible
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible
     : public __libcpp_nothrow_destructor<typename remove_all_extents<_Tp>::type> {};
 
 #endif
@@ -2676,12 +2834,12 @@
 
 #if __has_feature(is_pod) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_pod
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod
     : public integral_constant<bool, __is_pod(_Tp)> {};
 
 #else  // _LIBCPP_HAS_TYPE_TRAITS
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_pod
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod
     : public integral_constant<bool, is_trivially_default_constructible<_Tp>::value   &&
                                      is_trivially_copy_constructible<_Tp>::value      &&
                                      is_trivially_copy_assignable<_Tp>::value    &&
@@ -2691,7 +2849,7 @@
 
 // is_literal_type;
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_literal_type
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_literal_type
 #if __has_feature(is_literal)
     : public integral_constant<bool, __is_literal(_Tp)>
 #else
@@ -2702,7 +2860,7 @@
     
 // is_standard_layout;
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_standard_layout
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_standard_layout
 #if __has_feature(is_standard_layout)
     : public integral_constant<bool, __is_standard_layout(_Tp)>
 #else
@@ -2712,7 +2870,7 @@
     
 // is_trivially_copyable;
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivially_copyable
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copyable
 #if __has_feature(is_trivially_copyable)
     : public integral_constant<bool, __is_trivially_copyable(_Tp)>
 #else
@@ -2722,7 +2880,7 @@
     
 // is_trivial;
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS is_trivial
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivial
 #if __has_feature(is_trivial)
     : public integral_constant<bool, __is_trivial(_Tp)>
 #else
@@ -2779,12 +2937,22 @@
 {
 };
 
+template <class ..._Param>
+struct __check_complete<void (*)(_Param...)>
+{
+};
+
 template <class _Rp, class ..._Param>
 struct __check_complete<_Rp (_Param...)>
     : private __check_complete<_Rp>
 {
 };
 
+template <class ..._Param>
+struct __check_complete<void (_Param...)>
+{
+};
+
 template <class _Rp, class _Class, class ..._Param>
 struct __check_complete<_Rp (_Class::*)(_Param...)>
     : private __check_complete<_Class>
@@ -2878,13 +3046,27 @@
 
 // bullets 1 and 2
 
-template <class _Fp, class _A0, class ..._Args>
+template <class _Fp, class _A0, class ..._Args,
+            class = typename enable_if
+            <
+                is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
+                is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
 _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
     -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...));
 
-template <class _Fp, class _A0, class ..._Args>
+template <class _Fp, class _A0, class ..._Args,
+            class = typename enable_if
+            <
+                is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
+                !is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
 _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
@@ -2892,13 +3074,27 @@
 
 // bullets 3 and 4
 
-template <class _Fp, class _A0>
+template <class _Fp, class _A0,
+            class = typename enable_if
+            <
+                is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&
+                is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
 _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0)
     -> decltype(_VSTD::forward<_A0>(__a0).*__f);
 
-template <class _Fp, class _A0>
+template <class _Fp, class _A0,
+            class = typename enable_if
+            <
+                is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&
+                !is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
 _LIBCPP_INLINE_VISIBILITY
 auto
 __invoke(_Fp&& __f, _A0&& __a0)
@@ -2951,11 +3147,15 @@
 };
 
 template <class _Fp, class ..._Args>
-class _LIBCPP_TYPE_VIS result_of<_Fp(_Args...)>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)>
     : public __invoke_of<_Fp, _Args...>
 {
 };
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using result_of_t = typename result_of<_Tp>::type;
+#endif
+
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
 template <class _Tp>
@@ -3050,6 +3250,10 @@
     typedef _LIBCXX_UNDERLYING_TYPE(_Tp) type;
 };
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
+#endif
+
 #else  // _LIBCXX_UNDERLYING_TYPE
 
 template <class _Tp, bool _Support = false>
@@ -3062,6 +3266,27 @@
 
 #endif // _LIBCXX_UNDERLYING_TYPE
 
+#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+template <class _Tp>
+struct __has_operator_addressof_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 const bool value = decltype(__test<_Tp>(nullptr))::value;
+};
+
+template <class _Tp>
+struct __has_operator_addressof
+    : public integral_constant<bool, __has_operator_addressof_imp<_Tp>::value>
+{};
+
+#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_TYPE_TRAITS
diff --git a/include/typeindex b/include/typeindex
index 67462b7..d4d6ca9 100644
--- a/include/typeindex
+++ b/include/typeindex
@@ -55,7 +55,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-class _LIBCPP_TYPE_VIS type_index
+class _LIBCPP_TYPE_VIS_ONLY type_index
 {
     const type_info* __t_;
 public:
@@ -87,10 +87,10 @@
     const char* name() const _NOEXCEPT {return __t_->name();}
 };
 
-template <class _Tp> struct _LIBCPP_TYPE_VIS hash;
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;
 
 template <>
-struct _LIBCPP_TYPE_VIS hash<type_index>
+struct _LIBCPP_TYPE_VIS_ONLY hash<type_index>
     : public unary_function<type_index, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
diff --git a/include/unordered_map b/include/unordered_map
index 235b2ea..78fee48 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -69,6 +69,22 @@
     unordered_map(initializer_list<value_type>, size_type n = 0,
                   const hasher& hf = hasher(), const key_equal& eql = key_equal(),
                   const allocator_type& a = allocator_type());
+    unordered_map(size_type n, const allocator_type& a)
+      : unordered_map(n, hasher(), key_equal(), a) {}  // C++14
+    unordered_map(size_type n, const hasher& hf, const allocator_type& a)
+      : unordered_map(n, hf, key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
+      : unordered_map(f, l, n, hasher(), key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
+        const allocator_type& a)
+      : unordered_map(f, l, n, hf, key_equal(), a) {}  // C++14
+    unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
+      : unordered_map(il, n, hasher(), key_equal(), a) {}  // C++14
+    unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, 
+      const allocator_type& a)
+      : unordered_map(il, n, hf, key_equal(), a) {}  // C++14
     ~unordered_map();
     unordered_map& operator=(const unordered_map&);
     unordered_map& operator=(unordered_map&&)
@@ -217,6 +233,22 @@
     unordered_multimap(initializer_list<value_type>, size_type n = 0,
                   const hasher& hf = hasher(), const key_equal& eql = key_equal(),
                   const allocator_type& a = allocator_type());
+    unordered_multimap(size_type n, const allocator_type& a)
+      : unordered_multimap(n, hasher(), key_equal(), a) {}  // C++14
+    unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
+      : unordered_multimap(n, hf, key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
+      : unordered_multimap(f, l, n, hasher(), key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
+        const allocator_type& a)
+      : unordered_multimap(f, l, n, hf, key_equal(), a) {}  // C++14
+    unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
+      : unordered_multimap(il, n, hasher(), key_equal(), a) {}  // C++14
+    unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, 
+      const allocator_type& a)
+      : unordered_multimap(il, n, hf, key_equal(), a) {}  // C++14
     ~unordered_multimap();
     unordered_multimap& operator=(const unordered_multimap&);
     unordered_multimap& operator=(unordered_multimap&&)
@@ -325,7 +357,7 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Key, class _Tp, class _Hash, bool = is_empty<_Hash>::value
+template <class _Key, class _Cp, class _Hash, bool = is_empty<_Hash>::value
 #if __has_feature(is_final)
                                          && !__is_final(_Hash)
 #endif
@@ -333,8 +365,6 @@
 class __unordered_map_hasher
     : private _Hash
 {
-    typedef pair<typename remove_const<_Key>::type, _Tp> _Pp;
-    typedef pair<const _Key, _Tp> _Cp;
 public:
     _LIBCPP_INLINE_VISIBILITY
     __unordered_map_hasher()
@@ -347,23 +377,18 @@
     _LIBCPP_INLINE_VISIBILITY
     const _Hash& hash_function() const _NOEXCEPT {return *this;}
     _LIBCPP_INLINE_VISIBILITY
-    size_t operator()(const _Pp& __x) const
-        {return static_cast<const _Hash&>(*this)(__x.first);}
-    _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _Cp& __x) const
-        {return static_cast<const _Hash&>(*this)(__x.first);}
+        {return static_cast<const _Hash&>(*this)(__x.__cc.first);}
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _Key& __x) const
         {return static_cast<const _Hash&>(*this)(__x);}
 };
 
-template <class _Key, class _Tp, class _Hash>
-class __unordered_map_hasher<_Key, _Tp, _Hash, false>
+template <class _Key, class _Cp, class _Hash>
+class __unordered_map_hasher<_Key, _Cp, _Hash, false>
 {
     _Hash __hash_;
 
-    typedef pair<typename remove_const<_Key>::type, _Tp> _Pp;
-    typedef pair<const _Key, _Tp> _Cp;
 public:
     _LIBCPP_INLINE_VISIBILITY
     __unordered_map_hasher()
@@ -376,17 +401,14 @@
     _LIBCPP_INLINE_VISIBILITY
     const _Hash& hash_function() const _NOEXCEPT {return __hash_;}
     _LIBCPP_INLINE_VISIBILITY
-    size_t operator()(const _Pp& __x) const
-        {return __hash_(__x.first);}
-    _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _Cp& __x) const
-        {return __hash_(__x.first);}
+        {return __hash_(__x.__cc.first);}
     _LIBCPP_INLINE_VISIBILITY
     size_t operator()(const _Key& __x) const
         {return __hash_(__x);}
 };
 
-template <class _Key, class _Tp, class _Pred, bool = is_empty<_Pred>::value
+template <class _Key, class _Cp, class _Pred, bool = is_empty<_Pred>::value
 #if __has_feature(is_final)
                                          && !__is_final(_Pred)
 #endif
@@ -394,8 +416,6 @@
 class __unordered_map_equal
     : private _Pred
 {
-    typedef pair<typename remove_const<_Key>::type, _Tp> _Pp;
-    typedef pair<const _Key, _Tp> _Cp;
 public:
     _LIBCPP_INLINE_VISIBILITY
     __unordered_map_equal()
@@ -408,41 +428,21 @@
     _LIBCPP_INLINE_VISIBILITY
     const _Pred& key_eq() const _NOEXCEPT {return *this;}
     _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Pp& __y) const
-        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Cp& __y) const
-        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Key& __y) const
-        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Cp& __x, const _Pp& __y) const
-        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Cp& __x, const _Cp& __y) const
-        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
+        {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y.__cc.first);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Cp& __x, const _Key& __y) const
-        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Pp& __y) const
-        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
+        {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Key& __x, const _Cp& __y) const
-        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Key& __y) const
-        {return static_cast<const _Pred&>(*this)(__x, __y);}
+        {return static_cast<const _Pred&>(*this)(__x, __y.__cc.first);}
 };
 
-template <class _Key, class _Tp, class _Pred>
-class __unordered_map_equal<_Key, _Tp, _Pred, false>
+template <class _Key, class _Cp, class _Pred>
+class __unordered_map_equal<_Key, _Cp, _Pred, false>
 {
     _Pred __pred_;
 
-    typedef pair<typename remove_const<_Key>::type, _Tp> _Pp;
-    typedef pair<const _Key, _Tp> _Cp;
 public:
     _LIBCPP_INLINE_VISIBILITY
     __unordered_map_equal()
@@ -455,32 +455,14 @@
     _LIBCPP_INLINE_VISIBILITY
     const _Pred& key_eq() const _NOEXCEPT {return __pred_;}
     _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Pp& __y) const
-        {return __pred_(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Cp& __y) const
-        {return __pred_(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Pp& __x, const _Key& __y) const
-        {return __pred_(__x.first, __y);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Cp& __x, const _Pp& __y) const
-        {return __pred_(__x.first, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Cp& __x, const _Cp& __y) const
-        {return __pred_(__x.first, __y.first);}
+        {return __pred_(__x.__cc.first, __y.__cc.first);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Cp& __x, const _Key& __y) const
-        {return __pred_(__x.first, __y);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Pp& __y) const
-        {return __pred_(__x, __y.first);}
+        {return __pred_(__x.__cc.first, __y);}
     _LIBCPP_INLINE_VISIBILITY
     bool operator()(const _Key& __x, const _Cp& __y) const
-        {return __pred_(__x, __y.first);}
-    _LIBCPP_INLINE_VISIBILITY
-    bool operator()(const _Key& __x, const _Key& __y) const
-        {return __pred_(__x, __y);}
+        {return __pred_(__x, __y.__cc.first);}
 };
 
 template <class _Alloc>
@@ -492,8 +474,8 @@
 public:
     typedef typename __alloc_traits::pointer    pointer;
 private:
-    typedef typename value_type::first_type     first_type;
-    typedef typename value_type::second_type    second_type;
+    typedef typename value_type::value_type::first_type     first_type;
+    typedef typename value_type::value_type::second_type    second_type;
 
     allocator_type& __na_;
 
@@ -535,22 +517,87 @@
     void operator()(pointer __p) _NOEXCEPT
     {
         if (__second_constructed)
-            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
         if (__first_constructed)
-            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
         if (__p)
             __alloc_traits::deallocate(__na_, __p, 1);
     }
 };
 
+#if __cplusplus >= 201103L
+
+template <class _Key, class _Tp>
+union __hash_value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+
+    value_type __cc;
+    __nc_value_type __nc;
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(_Args&& ...__args)
+        : __cc(std::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const __hash_value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(__hash_value_type&& __v)
+        : __nc(std::move(__v.__nc)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type& operator=(const __hash_value_type& __v)
+        {__nc = __v.__cc; return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type& operator=(__hash_value_type&& __v)
+        {__nc = std::move(__v.__nc); return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__hash_value_type() {__cc.~value_type();}
+};
+
+#else
+
+template <class _Key, class _Tp>
+struct __hash_value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+
+    value_type __cc;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type() {}
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const _A0& __a0)
+        : __cc(__a0) {}
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const _A0& __a0, const _A1& __a1)
+        : __cc(__a0, __a1) {}
+};
+
+#endif
+
 template <class _HashIterator>
-class _LIBCPP_TYPE_VIS __hash_map_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator
 {
     _HashIterator __i_;
 
     typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
-    typedef const typename _HashIterator::value_type::first_type key_type;
-    typedef typename _HashIterator::value_type::second_type      mapped_type;
+    typedef const typename _HashIterator::value_type::value_type::first_type key_type;
+    typedef typename _HashIterator::value_type::value_type::second_type      mapped_type;
 public:
     typedef forward_iterator_tag                                 iterator_category;
     typedef pair<key_type, mapped_type>                          value_type;
@@ -571,9 +618,9 @@
     __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}
 
     _LIBCPP_INLINE_VISIBILITY
-    reference operator*() const {return *operator->();}
+    reference operator*() const {return __i_->__cc;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return (pointer)__i_.operator->();}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_map_iterator& operator++() {++__i_; return *this;}
@@ -592,21 +639,21 @@
         bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
         {return __x.__i_ != __y.__i_;}
 
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_multimap;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_local_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_map_const_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
 };
 
 template <class _HashIterator>
-class _LIBCPP_TYPE_VIS __hash_map_const_iterator
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator
 {
     _HashIterator __i_;
 
     typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
-    typedef const typename _HashIterator::value_type::first_type key_type;
-    typedef typename _HashIterator::value_type::second_type      mapped_type;
+    typedef const typename _HashIterator::value_type::value_type::first_type key_type;
+    typedef typename _HashIterator::value_type::value_type::second_type      mapped_type;
 public:
     typedef forward_iterator_tag                                 iterator_category;
     typedef pair<key_type, mapped_type>                          value_type;
@@ -632,9 +679,9 @@
                 : __i_(__i.__i_) {}
 
     _LIBCPP_INLINE_VISIBILITY
-    reference operator*() const {return *operator->();}
+    reference operator*() const {return __i_->__cc;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return (pointer)__i_.operator->();}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
 
     _LIBCPP_INLINE_VISIBILITY
     __hash_map_const_iterator& operator++() {++__i_; return *this;}
@@ -653,15 +700,15 @@
         bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
         {return __x.__i_ != __y.__i_;}
 
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_map;
-    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS unordered_multimap;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS __hash_const_local_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
 };
 
 template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
           class _Alloc = allocator<pair<const _Key, _Tp> > >
-class _LIBCPP_TYPE_VIS unordered_map
+class _LIBCPP_TYPE_VIS_ONLY unordered_map
 {
 public:
     // types
@@ -671,13 +718,16 @@
     typedef _Pred                                          key_equal;
     typedef _Alloc                                         allocator_type;
     typedef pair<const key_type, mapped_type>              value_type;
+    typedef pair<key_type, mapped_type>                    __nc_value_type;
     typedef value_type&                                    reference;
     typedef const value_type&                              const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
 
 private:
-    typedef pair<key_type, mapped_type>                    __value_type;
-    typedef __unordered_map_hasher<key_type, mapped_type, hasher>   __hasher;
-    typedef __unordered_map_equal<key_type, mapped_type, key_equal> __key_equal;
+    typedef __hash_value_type<key_type, mapped_type>                 __value_type;
+    typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;
+    typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
     typedef typename allocator_traits<allocator_type>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
             rebind_alloc<__value_type>
@@ -713,7 +763,11 @@
     _LIBCPP_INLINE_VISIBILITY
     unordered_map()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
-        {} // = default;
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
     explicit unordered_map(size_type __n, const hasher& __hf = hasher(),
                            const key_equal& __eql = key_equal());
     unordered_map(size_type __n, const hasher& __hf,
@@ -746,11 +800,44 @@
                   const hasher& __hf, const key_equal& __eql,
                   const allocator_type& __a);
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(size_type __n, const allocator_type& __a)
+      : unordered_map(__n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a)
+      : unordered_map(__n, __hf, key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)
+      : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, 
+        const allocator_type& __a)
+      : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
+      : unordered_map(__il, __n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(initializer_list<value_type> __il, size_type __n, const hasher& __hf, 
+      const allocator_type& __a)
+      : unordered_map(__il, __n, __hf, key_equal(), __a) {}
+#endif
     // ~unordered_map() = default;
     _LIBCPP_INLINE_VISIBILITY
     unordered_map& operator=(const unordered_map& __u)
     {
+#if __cplusplus >= 201103L
         __table_ = __u.__table_;
+#else
+        __table_.clear();
+        __table_.hash_function() = __u.__table_.hash_function();
+        __table_.key_eq() = __u.__table_.key_eq();
+        __table_.max_load_factor() = __u.__table_.max_load_factor();
+        __table_.__copy_assign_alloc(__u.__table_);
+        insert(__u.begin(), __u.end());
+#endif
         return *this;
     }
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -793,8 +880,18 @@
 
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator emplace_hint(const_iterator __p, _Args&&... __args)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not"
+                " referring to this unordered_map");
+            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
+        }
+#else
         iterator emplace_hint(const_iterator, _Args&&... __args)
             {return emplace(_VSTD::forward<_Args>(__args)...).first;}
+#endif
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
@@ -808,14 +905,34 @@
             {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));}
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    iterator insert(const_iterator __p, const value_type& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
+                " referring to this unordered_map");
+            return insert(__x).first;
+        }
+#else
     iterator insert(const_iterator, const value_type& __x)
         {return insert(__x).first;}
+#endif
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template <class _Pp,
               class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
         _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator insert(const_iterator __p, _Pp&& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_map::insert(const_iterator, value_type&&) called with an iterator not"
+                " referring to this unordered_map");
+            return insert(_VSTD::forward<_Pp>(__x)).first;
+        }
+#else
         iterator insert(const_iterator, _Pp&& __x)
             {return insert(_VSTD::forward<_Pp>(__x)).first;}
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template <class _InputIterator>
         void insert(_InputIterator __first, _InputIterator __last);
@@ -903,30 +1020,32 @@
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.reserve(__n);}
 
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(&__i->__i_);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(&__i->__i_);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 private:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     __node_holder __construct_node();
     template <class _A0>
-        typename enable_if
-        <
-            is_constructible<value_type, _A0>::value,
-            __node_holder
-        >::type
+        __node_holder
          __construct_node(_A0&& __a0);
-    template <class _A0>
-        typename enable_if
-        <
-            is_constructible<key_type, _A0>::value,
-            __node_holder
-        >::type
-         __construct_node(_A0&& __a0);
+    __node_holder __construct_node_with_key(key_type&& __k);
 #ifndef _LIBCPP_HAS_NO_VARIADICS
     template <class _A0, class _A1, class ..._Args>
         __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
 #endif  // _LIBCPP_HAS_NO_VARIADICS
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    __node_holder __construct_node(const key_type& __k);
-#endif
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __node_holder __construct_node_with_key(const key_type& __k);
 };
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -934,6 +1053,9 @@
         size_type __n, const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -943,6 +1065,9 @@
         const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -952,6 +1077,9 @@
         const allocator_type& __a)
     : __table_(__a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -959,6 +1087,9 @@
 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         _InputIterator __first, _InputIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__first, __last);
 }
 
@@ -969,6 +1100,9 @@
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -980,6 +1114,9 @@
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -989,6 +1126,9 @@
         const unordered_map& __u)
     : __table_(__u.__table_)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -998,6 +1138,9 @@
         const unordered_map& __u, const allocator_type& __a)
     : __table_(__u.__table_, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1011,6 +1154,10 @@
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1018,6 +1165,9 @@
         unordered_map&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
@@ -1026,6 +1176,10 @@
                 _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_)
                                     );
     }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1036,6 +1190,9 @@
 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
         initializer_list<value_type> __il)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__il.begin(), __il.end());
 }
 
@@ -1045,6 +1202,9 @@
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1055,6 +1215,9 @@
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1105,11 +1268,7 @@
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 template <class _A0>
-typename enable_if
-<
-    is_constructible<pair<const _Key, _Tp>, _A0>::value,
-    typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
->::type
+typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
 {
     __node_allocator& __na = __table_.__node_alloc();
@@ -1122,20 +1281,14 @@
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
-template <class _A0>
-typename enable_if
-<
-    is_constructible<_Key, _A0>::value,
-    typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
->::type
-unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
+typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(key_type&& __k)
 {
     __node_allocator& __na = __table_.__node_alloc();
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first),
-                             _VSTD::forward<_A0>(__a0));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));
     __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
     return __h;
 }
@@ -1172,23 +1325,21 @@
 }
 
 #endif  // _LIBCPP_HAS_NO_VARIADICS
-#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
-unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k)
 {
     __node_allocator& __na = __table_.__node_alloc();
     __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
     __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
     __h.get_deleter().__second_constructed = true;
-    return _VSTD::move(__h);
+    return _VSTD::move(__h);  // explicitly moved for C++03
 }
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 template <class _InputIterator>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -1207,7 +1358,7 @@
     iterator __i = find(__k);
     if (__i != end())
         return __i->second;
-    __node_holder __h = __construct_node(__k);
+    __node_holder __h = __construct_node_with_key(__k);
     pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
     __h.release();
     return __r.first->second;
@@ -1222,7 +1373,7 @@
     iterator __i = find(__k);
     if (__i != end())
         return __i->second;
-    __node_holder __h = __construct_node(_VSTD::move(__k));
+    __node_holder __h = __construct_node_with_key(_VSTD::move(__k));
     pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
     __h.release();
     return __r.first->second;
@@ -1294,7 +1445,7 @@
 
 template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
           class _Alloc = allocator<pair<const _Key, _Tp> > >
-class _LIBCPP_TYPE_VIS unordered_multimap
+class _LIBCPP_TYPE_VIS_ONLY unordered_multimap
 {
 public:
     // types
@@ -1304,13 +1455,16 @@
     typedef _Pred                                          key_equal;
     typedef _Alloc                                         allocator_type;
     typedef pair<const key_type, mapped_type>              value_type;
+    typedef pair<key_type, mapped_type>                    __nc_value_type;
     typedef value_type&                                    reference;
     typedef const value_type&                              const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
 
 private:
-    typedef pair<key_type, mapped_type>                    __value_type;
-    typedef __unordered_map_hasher<key_type, mapped_type, hasher>   __hasher;
-    typedef __unordered_map_equal<key_type, mapped_type, key_equal> __key_equal;
+    typedef __hash_value_type<key_type, mapped_type>                 __value_type;
+    typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;
+    typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
     typedef typename allocator_traits<allocator_type>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
             rebind_alloc<__value_type>
@@ -1344,7 +1498,11 @@
     _LIBCPP_INLINE_VISIBILITY
     unordered_multimap()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
-        {} // = default;
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
     explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(),
                                 const key_equal& __eql = key_equal());
     unordered_multimap(size_type __n, const hasher& __hf,
@@ -1378,11 +1536,44 @@
                        const hasher& __hf, const key_equal& __eql,
                        const allocator_type& __a);
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(size_type __n, const allocator_type& __a)
+      : unordered_multimap(__n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a)
+      : unordered_multimap(__n, __hf, key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)
+      : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, 
+        const allocator_type& __a)
+      : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
+      : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(initializer_list<value_type> __il, size_type __n, const hasher& __hf, 
+      const allocator_type& __a)
+      : unordered_multimap(__il, __n, __hf, key_equal(), __a) {}
+#endif
     // ~unordered_multimap() = default;
     _LIBCPP_INLINE_VISIBILITY
     unordered_multimap& operator=(const unordered_multimap& __u)
     {
+#if __cplusplus >= 201103L
         __table_ = __u.__table_;
+#else
+        __table_.clear();
+        __table_.hash_function() = __u.__table_.hash_function();
+        __table_.key_eq() = __u.__table_.key_eq();
+        __table_.max_load_factor() = __u.__table_.max_load_factor();
+        __table_.__copy_assign_alloc(__u.__table_);
+        insert(__u.begin(), __u.end());
+#endif
         return *this;
     }
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1525,22 +1716,24 @@
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.reserve(__n);}
 
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(&__i->__i_);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(&__i->__i_);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 private:
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     __node_holder __construct_node();
     template <class _A0>
-        typename enable_if
-        <
-            is_constructible<value_type, _A0>::value,
-            __node_holder
-        >::type
-         __construct_node(_A0&& __a0);
-    template <class _A0>
-        typename enable_if
-        <
-            is_constructible<key_type, _A0>::value,
-            __node_holder
-        >::type
+        __node_holder
          __construct_node(_A0&& __a0);
 #ifndef _LIBCPP_HAS_NO_VARIADICS
     template <class _A0, class _A1, class ..._Args>
@@ -1554,6 +1747,9 @@
         size_type __n, const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -1563,6 +1759,9 @@
         const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -1571,6 +1770,9 @@
 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         _InputIterator __first, _InputIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__first, __last);
 }
 
@@ -1581,6 +1783,9 @@
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -1592,6 +1797,9 @@
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -1602,6 +1810,9 @@
         const allocator_type& __a)
     : __table_(__a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1609,6 +1820,9 @@
         const unordered_multimap& __u)
     : __table_(__u.__table_)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1618,6 +1832,9 @@
         const unordered_multimap& __u, const allocator_type& __a)
     : __table_(__u.__table_, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1631,6 +1848,10 @@
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
 }
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1638,16 +1859,23 @@
         unordered_multimap&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
         while (__u.size() != 0)
-{
+        {
             __table_.__insert_multi(
                 _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_)
                                    );
-}
+        }
     }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1658,6 +1886,9 @@
 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
         initializer_list<value_type> __il)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__il.begin(), __il.end());
 }
 
@@ -1667,6 +1898,9 @@
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1677,6 +1911,9 @@
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1727,11 +1964,7 @@
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
 template <class _A0>
-typename enable_if
-<
-    is_constructible<pair<const _Key, _Tp>, _A0>::value,
-    typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
->::type
+typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
 {
     __node_allocator& __na = __table_.__node_alloc();
@@ -1743,25 +1976,6 @@
     return __h;
 }
 
-template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
-template <class _A0>
-typename enable_if
-<
-    is_constructible<_Key, _A0>::value,
-    typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
->::type
-unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
-{
-    __node_allocator& __na = __table_.__node_alloc();
-    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first),
-                             _VSTD::forward<_A0>(__a0));
-    __h.get_deleter().__first_constructed = true;
-    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
-    __h.get_deleter().__second_constructed = true;
-    return __h;
-}
-
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
 template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
diff --git a/include/unordered_set b/include/unordered_set
index 119251d..fd378fa 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -68,6 +68,16 @@
     unordered_set(initializer_list<value_type>, size_type n = 0,
                   const hasher& hf = hasher(), const key_equal& eql = key_equal(),
                   const allocator_type& a = allocator_type());
+    unordered_set(size_type n, const allocator_type& a); // C++14
+    unordered_set(size_type n, const hasher& hf, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_set(InputIterator f, InputIterator l, size_type n, 
+                    const hasher& hf,  const allocator_type& a); // C++14
+    unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
+    unordered_set(initializer_list<value_type> il, size_type n,
+                  const hasher& hf,  const allocator_type& a); // C++14
     ~unordered_set();
     unordered_set& operator=(const unordered_set&);
     unordered_set& operator=(unordered_set&&)
@@ -207,6 +217,16 @@
     unordered_multiset(initializer_list<value_type>, size_type n = /see below/,
                   const hasher& hf = hasher(), const key_equal& eql = key_equal(),
                   const allocator_type& a = allocator_type());
+    unordered_multiset(size_type n, const allocator_type& a); // C++14
+    unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_multiset(InputIterator f, InputIterator l, size_type n,
+                         const hasher& hf, const allocator_type& a); // C++14
+    unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
+    unordered_multiset(initializer_list<value_type> il, size_type n, 
+                       const hasher& hf,  const allocator_type& a); // C++14
     ~unordered_multiset();
     unordered_multiset& operator=(const unordered_multiset&);
     unordered_multiset& operator=(unordered_multiset&&)
@@ -313,7 +333,7 @@
 
 template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
           class _Alloc = allocator<_Value> >
-class _LIBCPP_TYPE_VIS unordered_set
+class _LIBCPP_TYPE_VIS_ONLY unordered_set
 {
 public:
     // types
@@ -324,6 +344,8 @@
     typedef _Alloc                                                     allocator_type;
     typedef value_type&                                                reference;
     typedef const value_type&                                          const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
 
 private:
     typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
@@ -344,9 +366,21 @@
     _LIBCPP_INLINE_VISIBILITY
     unordered_set()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
-        {} // = default;
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
     explicit unordered_set(size_type __n, const hasher& __hf = hasher(),
                            const key_equal& __eql = key_equal());
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(size_type __n, const allocator_type& __a)
+        : unordered_set(__n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_set(__n, __hf, key_equal(), __a) {}
+#endif
     unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
                   const allocator_type& __a);
     template <class _InputIterator>
@@ -359,6 +393,17 @@
         unordered_set(_InputIterator __first, _InputIterator __last,
                       size_type __n, const hasher& __hf, const key_equal& __eql,
                       const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    inline _LIBCPP_INLINE_VISIBILITY
+        unordered_set(_InputIterator __first, _InputIterator __last, 
+                    size_type __n, const allocator_type& __a)
+            : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+        unordered_set(_InputIterator __first, _InputIterator __last, 
+                      size_type __n, const hasher& __hf, const allocator_type& __a)
+            : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {}
+#endif
     explicit unordered_set(const allocator_type& __a);
     unordered_set(const unordered_set& __u);
     unordered_set(const unordered_set& __u, const allocator_type& __a);
@@ -375,6 +420,16 @@
     unordered_set(initializer_list<value_type> __il, size_type __n,
                   const hasher& __hf, const key_equal& __eql,
                   const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(initializer_list<value_type> __il, size_type __n,
+                                                      const allocator_type& __a)
+        : unordered_set(__il, __n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(initializer_list<value_type> __il, size_type __n, 
+                                  const hasher& __hf, const allocator_type& __a)
+        : unordered_set(__il, __n, __hf, key_equal(), __a) {}
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     // ~unordered_set() = default;
     _LIBCPP_INLINE_VISIBILITY
@@ -422,8 +477,18 @@
             {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator emplace_hint(const_iterator __p, _Args&&... __args)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
+                " referring to this unordered_set");
+            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
+        }
+#else
         iterator emplace_hint(const_iterator, _Args&&... __args)
             {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;}
+#endif
 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, bool> insert(const value_type& __x)
@@ -434,12 +499,32 @@
         {return __table_.__insert_unique(_VSTD::move(__x));}
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    iterator insert(const_iterator __p, const value_type& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
+                " referring to this unordered_set");
+            return insert(__x).first;
+        }
+#else
     iterator insert(const_iterator, const value_type& __x)
         {return insert(__x).first;}
+#endif
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    iterator insert(const_iterator __p, value_type&& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
+                " referring to this unordered_set");
+            return insert(_VSTD::move(__x)).first;
+        }
+#else
     iterator insert(const_iterator, value_type&& __x)
         {return insert(_VSTD::move(__x)).first;}
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     template <class _InputIterator>
         void insert(_InputIterator __first, _InputIterator __last);
@@ -515,6 +600,20 @@
     void rehash(size_type __n) {__table_.rehash(__n);}
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.reserve(__n);}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(__i);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(__i);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 };
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -522,6 +621,9 @@
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -530,6 +632,9 @@
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -538,6 +643,9 @@
 unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         _InputIterator __first, _InputIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__first, __last);
 }
 
@@ -548,6 +656,9 @@
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -559,6 +670,9 @@
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -569,6 +683,9 @@
         const allocator_type& __a)
     : __table_(__a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -576,6 +693,9 @@
         const unordered_set& __u)
     : __table_(__u.__table_)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -585,6 +705,9 @@
         const unordered_set& __u, const allocator_type& __a)
     : __table_(__u.__table_, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -598,6 +721,10 @@
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -605,12 +732,19 @@
         unordered_set&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
         while (__u.size() != 0)
             __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));
     }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -621,6 +755,9 @@
 unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
         initializer_list<value_type> __il)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__il.begin(), __il.end());
 }
 
@@ -630,6 +767,9 @@
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
@@ -640,6 +780,9 @@
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
@@ -725,7 +868,7 @@
 
 template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
           class _Alloc = allocator<_Value> >
-class _LIBCPP_TYPE_VIS unordered_multiset
+class _LIBCPP_TYPE_VIS_ONLY unordered_multiset
 {
 public:
     // types
@@ -736,6 +879,8 @@
     typedef _Alloc                                                     allocator_type;
     typedef value_type&                                                reference;
     typedef const value_type&                                          const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
 
 private:
     typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
@@ -756,11 +901,23 @@
     _LIBCPP_INLINE_VISIBILITY
     unordered_multiset()
         _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
-        {} // = default
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
     explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),
                                 const key_equal& __eql = key_equal());
     unordered_multiset(size_type __n, const hasher& __hf,
                        const key_equal& __eql, const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(size_type __n, const allocator_type& __a)
+        : unordered_multiset(__n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_multiset(__n, __hf, key_equal(), __a) {}
+#endif
     template <class _InputIterator>
         unordered_multiset(_InputIterator __first, _InputIterator __last);
     template <class _InputIterator>
@@ -771,6 +928,18 @@
         unordered_multiset(_InputIterator __first, _InputIterator __last,
                       size_type __n , const hasher& __hf,
                       const key_equal& __eql, const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(_InputIterator __first, _InputIterator __last, 
+                       size_type __n, const allocator_type& __a)
+        : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(_InputIterator __first, _InputIterator __last,
+                       size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {}
+#endif
     explicit unordered_multiset(const allocator_type& __a);
     unordered_multiset(const unordered_multiset& __u);
     unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
@@ -787,6 +956,14 @@
     unordered_multiset(initializer_list<value_type> __il, size_type __n,
                        const hasher& __hf, const key_equal& __eql,
                        const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
+      : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const allocator_type& __a)
+      : unordered_multiset(__il, __n, __hf, key_equal(), __a) {}
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
     // ~unordered_multiset() = default;
     _LIBCPP_INLINE_VISIBILITY
@@ -925,6 +1102,20 @@
     void rehash(size_type __n) {__table_.rehash(__n);}
     _LIBCPP_INLINE_VISIBILITY
     void reserve(size_type __n) {__table_.reserve(__n);}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(__i);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(__i);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 };
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -932,6 +1123,9 @@
         size_type __n, const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -941,6 +1135,9 @@
         const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
 }
 
@@ -949,6 +1146,9 @@
 unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         _InputIterator __first, _InputIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__first, __last);
 }
 
@@ -959,6 +1159,9 @@
         const hasher& __hf, const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -970,6 +1173,9 @@
         const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__first, __last);
 }
@@ -980,6 +1186,9 @@
         const allocator_type& __a)
     : __table_(__a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -987,6 +1196,9 @@
         const unordered_multiset& __u)
     : __table_(__u.__table_)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -996,6 +1208,9 @@
         const unordered_multiset& __u, const allocator_type& __a)
     : __table_(__u.__table_, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__u.bucket_count());
     insert(__u.begin(), __u.end());
 }
@@ -1009,6 +1224,10 @@
     _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
     : __table_(_VSTD::move(__u.__table_))
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
 }
 
 template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1016,12 +1235,19 @@
         unordered_multiset&& __u, const allocator_type& __a)
     : __table_(_VSTD::move(__u.__table_), __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     if (__a != __u.get_allocator())
     {
         iterator __i = __u.begin();
         while (__u.size() != 0)
             __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));
     }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1032,6 +1258,9 @@
 unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
         initializer_list<value_type> __il)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     insert(__il.begin(), __il.end());
 }
 
@@ -1041,6 +1270,9 @@
         const key_equal& __eql)
     : __table_(__hf, __eql)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
@@ -1051,6 +1283,9 @@
         const key_equal& __eql, const allocator_type& __a)
     : __table_(__hf, __eql, __a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __table_.rehash(__n);
     insert(__il.begin(), __il.end());
 }
diff --git a/include/utility b/include/utility
index 2df4b36..2c1f62c 100644
--- a/include/utility
+++ b/include/utility
@@ -38,10 +38,10 @@
 void
 swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
 
-template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;
-template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept;
+template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;  // constexpr in C++14
+template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept; // constexpr in C++14
 
-template <class T> typename remove_reference<T>::type&& move(T&&) noexcept;
+template <class T> typename remove_reference<T>::type&& move(T&&) noexcept;      // constexpr in C++14
 
 template <class T>
     typename conditional
@@ -50,7 +50,7 @@
         const T&,
         T&&
     >::type
-    move_if_noexcept(T& x) noexcept;
+    move_if_noexcept(T& x) noexcept; // constexpr in C++14
 
 template <class T> typename add_rvalue_reference<T>::type declval() noexcept;
 
@@ -66,10 +66,10 @@
     pair(const pair&) = default;
     pair(pair&&) = default;
     constexpr pair();
-    pair(const T1& x, const T2& y);
-    template <class U, class V> pair(U&& x, V&& y);
-    template <class U, class V> pair(const pair<U, V>& p);
-    template <class U, class V> pair(pair<U, V>&& p);
+    pair(const T1& x, const T2& y);                          // constexpr in C++14
+    template <class U, class V> pair(U&& x, V&& y);          // constexpr in C++14
+    template <class U, class V> pair(const pair<U, V>& p);   // constexpr in C++14
+    template <class U, class V> pair(pair<U, V>&& p);        // constexpr in C++14
     template <class... Args1, class... Args2>
         pair(piecewise_construct_t, tuple<Args1...> first_args,
              tuple<Args2...> second_args);
@@ -83,14 +83,14 @@
                                 noexcept(swap(second, p.second)));
 };
 
-template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&);
-template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&);
-template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&);
-template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&);
-template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&);
-template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&);
+template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
 
-template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&);
+template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&);   // constexpr in C++14
 template <class T1, class T2>
 void
 swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
@@ -107,16 +107,48 @@
 
 template<size_t I, class T1, class T2>
     typename tuple_element<I, std::pair<T1, T2> >::type&
-    get(std::pair<T1, T2>&) noexcept;
+    get(std::pair<T1, T2>&) noexcept; // constexpr in C++14
 
 template<size_t I, class T1, class T2>
     const typename const tuple_element<I, std::pair<T1, T2> >::type&
-    get(const std::pair<T1, T2>&) noexcept;
+    get(const std::pair<T1, T2>&) noexcept; // constexpr in C++14
 
 template<size_t I, class T1, class T2>
     typename tuple_element<I, std::pair<T1, T2> >::type&&
-    get(std::pair<T1, T2>&&) noexcept;
+    get(std::pair<T1, T2>&&) noexcept; // constexpr in C++14
 
+template<class T1, class T2>
+    constexpr T1& get(std::pair<T1, T2>&) noexcept; // C++14
+
+template<size_t I, class T1, class T2>
+    constexpr T1 const& get(std::pair<T1, T2> const &) noexcept; // C++14
+
+template<size_t I, class T1, class T2>
+    constexpr T1&& get(std::pair<T1, T2>&&) noexcept; // C++14
+
+// C++14
+
+template<class T, T... I>
+struct integer_sequence
+{
+    typedef T value_type;
+
+    static constexpr size_t size() noexcept;
+};
+
+template<size_t... I>
+  using index_sequence = integer_sequence<size_t, I...>;
+
+template<class T, T N>
+  using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;
+template<size_t N>
+  using make_index_sequence = make_integer_sequence<size_t, N>;
+
+template<class... T>
+  using index_sequence_for = make_index_sequence<sizeof...(T)>;
+
+template<class T, class U=T> 
+    T exchange(T& obj, U&& new_value);
 }  // std
 
 */
@@ -189,7 +221,7 @@
 }
 
 template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 typename conditional
 <
@@ -205,7 +237,7 @@
     return _VSTD::move(__x);
 }
 
-struct _LIBCPP_TYPE_VIS piecewise_construct_t { };
+struct _LIBCPP_TYPE_VIS_ONLY piecewise_construct_t { };
 #if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_UTILITY)
 extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
 #else
@@ -213,7 +245,7 @@
 #endif
 
 template <class _T1, class _T2>
-struct _LIBCPP_TYPE_VIS pair
+struct _LIBCPP_TYPE_VIS_ONLY pair
 {
     typedef _T1 first_type;
     typedef _T2 second_type;
@@ -226,11 +258,12 @@
 
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() : first(), second() {}
 
-    _LIBCPP_INLINE_VISIBILITY pair(const _T1& __x, const _T2& __y)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    pair(const _T1& __x, const _T2& __y)
         : first(__x), second(__y) {}
 
     template<class _U1, class _U2>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         pair(const pair<_U1, _U2>& __p
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
                  ,typename enable_if<is_convertible<const _U1&, _T1>::value &&
@@ -239,6 +272,10 @@
                                       )
             : first(__p.first), second(__p.second) {}
 
+#if !defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
+    _LIBCPP_INLINE_VISIBILITY
+    pair(const pair& __p) = default;
+#elif !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) || !_LIBCPP_TRIVIAL_PAIR_COPY_CTOR
     _LIBCPP_INLINE_VISIBILITY
     pair(const pair& __p)
         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
@@ -247,6 +284,7 @@
           second(__p.second)
     {
     }
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     pair& operator=(const pair& __p)
@@ -263,20 +301,24 @@
     template <class _U1, class _U2,
               class = typename enable_if<is_convertible<_U1, first_type>::value &&
                                          is_convertible<_U2, second_type>::value>::type>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         pair(_U1&& __u1, _U2&& __u2)
             : first(_VSTD::forward<_U1>(__u1)),
               second(_VSTD::forward<_U2>(__u2))
             {}
 
     template<class _U1, class _U2>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         pair(pair<_U1, _U2>&& __p,
                  typename enable_if<is_convertible<_U1, _T1>::value &&
                                     is_convertible<_U2, _T2>::value>::type* = 0)
             : first(_VSTD::forward<_U1>(__p.first)),
               second(_VSTD::forward<_U2>(__p.second)) {}
 
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    _LIBCPP_INLINE_VISIBILITY
+    pair(pair&& __p) = default;
+#else
     _LIBCPP_INLINE_VISIBILITY
     pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value &&
                                 is_nothrow_move_constructible<second_type>::value)
@@ -284,6 +326,7 @@
           second(_VSTD::forward<second_type>(__p.second))
     {
     }
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     pair&
@@ -299,7 +342,7 @@
 
     template<class _Tuple,
              class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         pair(_Tuple&& __p)
             : first(_VSTD::forward<typename tuple_element<0,
                                   typename __make_tuple_types<_Tuple>::type>::type>(get<0>(__p))),
@@ -355,7 +398,7 @@
 };
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
 {
@@ -363,7 +406,7 @@
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
 {
@@ -371,7 +414,7 @@
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
 {
@@ -379,7 +422,7 @@
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
 {
@@ -387,7 +430,7 @@
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
 {
@@ -395,7 +438,7 @@
 }
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 bool
 operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
 {
@@ -419,7 +462,7 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-template <class _Tp> class _LIBCPP_TYPE_VIS reference_wrapper;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
 
 template <class _Tp>
 struct ___make_pair_return
@@ -440,7 +483,7 @@
 };
 
 template <class _T1, class _T2>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>
 make_pair(_T1&& __t1, _T2&& __t2)
 {
@@ -461,36 +504,36 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _T1, class _T2>
-  class _LIBCPP_TYPE_VIS tuple_size<pair<_T1, _T2> >
+  class _LIBCPP_TYPE_VIS_ONLY tuple_size<pair<_T1, _T2> >
     : public integral_constant<size_t, 2> {};
 
 template <class _T1, class _T2>
-  class _LIBCPP_TYPE_VIS tuple_size<const pair<_T1, _T2> >
+  class _LIBCPP_TYPE_VIS_ONLY tuple_size<const pair<_T1, _T2> >
     : public integral_constant<size_t, 2> {};
 
 template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS tuple_element<0, pair<_T1, _T2> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, pair<_T1, _T2> >
 {
 public:
     typedef _T1 type;
 };
 
 template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS tuple_element<1, pair<_T1, _T2> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<1, pair<_T1, _T2> >
 {
 public:
     typedef _T2 type;
 };
 
 template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS tuple_element<0, const pair<_T1, _T2> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, const pair<_T1, _T2> >
 {
 public:
     typedef const _T1 type;
 };
 
 template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS tuple_element<1, const pair<_T1, _T2> >
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<1, const pair<_T1, _T2> >
 {
 public:
     typedef const _T2 type;
@@ -503,13 +546,13 @@
 {
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     _T1&
     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     const _T1&
     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
 
@@ -517,7 +560,7 @@
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     _T1&&
     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
 
@@ -529,13 +572,13 @@
 {
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     _T2&
     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     const _T2&
     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
 
@@ -543,7 +586,7 @@
 
     template <class _T1, class _T2>
     static
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     _T2&&
     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
 
@@ -551,7 +594,7 @@
 };
 
 template <size_t _Ip, class _T1, class _T2>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
 get(pair<_T1, _T2>& __p) _NOEXCEPT
 {
@@ -559,7 +602,7 @@
 }
 
 template <size_t _Ip, class _T1, class _T2>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
 get(const pair<_T1, _T2>& __p) _NOEXCEPT
 {
@@ -569,7 +612,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <size_t _Ip, class _T1, class _T2>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
 get(pair<_T1, _T2>&& __p) _NOEXCEPT
 {
@@ -578,6 +621,148 @@
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
+#if _LIBCPP_STD_VER > 11
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(_VSTD::move(__p));
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(_VSTD::move(__p));
+}
+
+#endif
+
+#if _LIBCPP_STD_VER > 11
+
+template<class _Tp, _Tp... _Ip>
+struct _LIBCPP_TYPE_VIS_ONLY integer_sequence
+{
+    typedef _Tp value_type;
+    static_assert( is_integral<_Tp>::value,
+                  "std::integer_sequence can only be instantiated with an integral type" );
+    static
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    size_t
+    size() noexcept { return sizeof...(_Ip); }
+};
+
+template<size_t... _Ip>
+    using index_sequence = integer_sequence<size_t, _Ip...>;
+
+namespace __detail {
+
+template<typename _Tp, size_t ..._Extra> struct __repeat;
+template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<integer_sequence<_Tp, _Np...>, _Extra...> {
+  typedef integer_sequence<_Tp,
+                           _Np...,
+                           sizeof...(_Np) + _Np...,
+                           2 * sizeof...(_Np) + _Np...,
+                           3 * sizeof...(_Np) + _Np...,
+                           4 * sizeof...(_Np) + _Np...,
+                           5 * sizeof...(_Np) + _Np...,
+                           6 * sizeof...(_Np) + _Np...,
+                           7 * sizeof...(_Np) + _Np...,
+                           _Extra...> type;
+};
+
+template<size_t _Np> struct __parity;
+template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {};
+
+template<> struct __make<0> { typedef integer_sequence<size_t> type; };
+template<> struct __make<1> { typedef integer_sequence<size_t, 0> type; };
+template<> struct __make<2> { typedef integer_sequence<size_t, 0, 1> type; };
+template<> struct __make<3> { typedef integer_sequence<size_t, 0, 1, 2> type; };
+template<> struct __make<4> { typedef integer_sequence<size_t, 0, 1, 2, 3> type; };
+template<> struct __make<5> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4> type; };
+template<> struct __make<6> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; };
+template<> struct __make<7> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; };
+
+template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };
+template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };
+template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+
+template<typename _Tp, typename _Up> struct __convert {
+  template<typename> struct __result;
+  template<_Tp ..._Np> struct __result<integer_sequence<_Tp, _Np...> > { typedef integer_sequence<_Up, _Np...> type; };
+};
+template<typename _Tp> struct __convert<_Tp, _Tp> { template<typename _Up> struct __result { typedef _Up type; }; };
+
+}
+
+template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked =
+  typename __detail::__convert<size_t, _Tp>::template __result<typename __detail::__make<_Np>::type>::type;
+
+template <class _Tp, _Tp _Ep>
+struct __make_integer_sequence
+{
+    static_assert(is_integral<_Tp>::value,
+                  "std::make_integer_sequence can only be instantiated with an integral type" );
+    static_assert(0 <= _Ep, "std::make_integer_sequence input shall not be negative");
+    typedef __make_integer_sequence_unchecked<_Tp, _Ep> type;
+};
+
+template<class _Tp, _Tp _Np>
+    using make_integer_sequence = typename __make_integer_sequence<_Tp, _Np>::type;
+
+template<size_t _Np>
+    using make_index_sequence = make_integer_sequence<size_t, _Np>;
+
+template<class... _Tp>
+    using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
+  
+#endif  // _LIBCPP_STD_VER > 11
+
+#if _LIBCPP_STD_VER > 11
+template<class _T1, class _T2 = _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+_T1 exchange(_T1& __obj, _T2 && __new_value)
+{
+    _T1 __old_value = _VSTD::move(__obj);
+    __obj = _VSTD::forward<_T2>(__new_value);
+    return __old_value;
+}    
+#endif  // _LIBCPP_STD_VER > 11
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_UTILITY
diff --git a/include/valarray b/include/valarray
index 71c8a74..5113516 100644
--- a/include/valarray
+++ b/include/valarray
@@ -354,9 +354,9 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template<class _Tp> class _LIBCPP_TYPE_VIS valarray;
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY valarray;
 
-class _LIBCPP_TYPE_VIS slice
+class _LIBCPP_TYPE_VIS_ONLY slice
 {
     size_t __start_;
     size_t __size_;
@@ -381,11 +381,11 @@
     _LIBCPP_INLINE_VISIBILITY size_t stride() const {return __stride_;}
 };
 
-template <class _Tp> class _LIBCPP_TYPE_VIS slice_array;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY slice_array;
 class _LIBCPP_TYPE_VIS gslice;
-template <class _Tp> class _LIBCPP_TYPE_VIS gslice_array;
-template <class _Tp> class _LIBCPP_TYPE_VIS mask_array;
-template <class _Tp> class _LIBCPP_TYPE_VIS indirect_array;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY gslice_array;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY mask_array;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY indirect_array;
 
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY
@@ -671,7 +671,7 @@
     _LIBCPP_INLINE_VISIBILITY
     size_t size() const {return __size_;}
 
-    template <class> friend class _LIBCPP_TYPE_VIS valarray;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;
 };
 
 template <class _ValExpr>
@@ -786,7 +786,7 @@
 struct __is_val_expr<valarray<_Tp> > : true_type {};
 
 template<class _Tp>
-class _LIBCPP_TYPE_VIS valarray
+class _LIBCPP_TYPE_VIS_ONLY valarray
 {
 public:
     typedef _Tp value_type;
@@ -976,12 +976,12 @@
     void     resize(size_t __n, value_type __x = value_type());
 
 private:
-    template <class> friend class _LIBCPP_TYPE_VIS valarray;
-    template <class> friend class _LIBCPP_TYPE_VIS slice_array;
-    template <class> friend class _LIBCPP_TYPE_VIS gslice_array;
-    template <class> friend class _LIBCPP_TYPE_VIS mask_array;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY slice_array;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY gslice_array;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY mask_array;
     template <class> friend class __mask_expr;
-    template <class> friend class _LIBCPP_TYPE_VIS indirect_array;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY indirect_array;
     template <class> friend class __indirect_expr;
     template <class> friend class __val_expr;
 
@@ -1006,6 +1006,10 @@
     end(const valarray<_Up>& __v);
 };
 
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::~valarray())
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t))
+
 template <class _Op, class _Tp>
 struct _UnaryOp<_Op, valarray<_Tp> >
 {
@@ -1091,7 +1095,7 @@
 // slice_array
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS slice_array
+class _LIBCPP_TYPE_VIS_ONLY slice_array
 {
 public:
     typedef _Tp value_type;
@@ -1461,7 +1465,7 @@
 // gslice_array
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS gslice_array
+class _LIBCPP_TYPE_VIS_ONLY gslice_array
 {
 public:
     typedef _Tp value_type;
@@ -1790,7 +1794,7 @@
 // mask_array
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS mask_array
+class _LIBCPP_TYPE_VIS_ONLY mask_array
 {
 public:
     typedef _Tp value_type;
@@ -2134,7 +2138,7 @@
 // indirect_array
 
 template <class _Tp>
-class _LIBCPP_TYPE_VIS indirect_array
+class _LIBCPP_TYPE_VIS_ONLY indirect_array
 {
 public:
     typedef _Tp value_type;
@@ -2485,7 +2489,7 @@
     _LIBCPP_INLINE_VISIBILITY
     size_t size() const {return __1d_.size();}
 
-    template <class> friend class _LIBCPP_TYPE_VIS valarray;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;
 };
 
 template<class _ValExpr>
@@ -2624,7 +2628,7 @@
 };
 
 template<class _ValExpr>
-__val_expr<_ValExpr>::operator valarray<result_type>() const
+__val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const
 {
     valarray<result_type> __r;
     size_t __n = __expr_.size();
@@ -4770,10 +4774,6 @@
     return __v.__end_;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(valarray<size_t>::valarray(size_t))
-_LIBCPP_EXTERN_TEMPLATE(valarray<size_t>::~valarray())
-_LIBCPP_EXTERN_TEMPLATE(void valarray<size_t>::resize(size_t, size_t))
-
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_VALARRAY
diff --git a/include/vector b/include/vector
index e04c267..6ac78d5 100644
--- a/include/vector
+++ b/include/vector
@@ -38,6 +38,7 @@
         noexcept(is_nothrow_default_constructible<allocator_type>::value);
     explicit vector(const allocator_type&);
     explicit vector(size_type n);
+    explicit vector(size_type n, const allocator_type&); // C++14
     vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
     template <class InputIterator>
         vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
@@ -161,7 +162,8 @@
     vector()
         noexcept(is_nothrow_default_constructible<allocator_type>::value);
     explicit vector(const allocator_type&);
-    explicit vector(size_type n, const value_type& value = value_type(), const allocator_type& = allocator_type());
+    explicit vector(size_type n, const allocator_type& a = allocator_type()); // C++14
+    vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
     template <class InputIterator>
         vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
     vector(const vector& x);
@@ -216,8 +218,10 @@
     const_reference back() const;
 
     void push_back(const value_type& x);
+    template <class... Args> void emplace_back(Args&&... args);  // C++14
     void pop_back();
 
+    template <class... Args> iterator emplace(const_iterator position, Args&&... args);  // C++14
     iterator insert(const_iterator position, const value_type& x);
     iterator insert(const_iterator position, size_type n, const value_type& x);
     template <class InputIterator>
@@ -272,6 +276,12 @@
 
 #include <__undef_min_max>
 
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -309,14 +319,14 @@
 #endif
 }
 
-#ifdef _MSC_VER
+#ifdef _LIBCPP_MSVC
 #pragma warning( push )
 #pragma warning( disable: 4231 )
-#endif // _MSC_VER
-_LIBCPP_EXTERN_TEMPLATE(class __vector_base_common<true>)
-#ifdef _MSC_VER
+#endif // _LIBCPP_MSVC
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __vector_base_common<true>)
+#ifdef _LIBCPP_MSVC
 #pragma warning( pop )
-#endif // _MSC_VER
+#endif // _LIBCPP_MSVC
 
 template <class _Tp, class _Allocator>
 class __vector_base
@@ -365,12 +375,7 @@
         {return static_cast<size_type>(__end_cap() - __begin_);}
 
     _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last) _NOEXCEPT
-        {__destruct_at_end(__new_last, false_type());}
-    _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT;
+    void __destruct_at_end(pointer __new_last) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const __vector_base& __c)
@@ -435,45 +440,37 @@
 };
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
-__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT
+__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
 {
     while (__new_last != __end_)
-        __alloc_traits::destroy(__alloc(), const_cast<pointer>(--__end_));
+        __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__end_));
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
-void
-__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT
-{
-    __end_ = const_cast<pointer>(__new_last);
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 __vector_base<_Tp, _Allocator>::__vector_base()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-    : __begin_(0),
-      __end_(0),
-      __end_cap_(0)
+    : __begin_(nullptr),
+      __end_(nullptr),
+      __end_cap_(nullptr)
 {
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 __vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)
-    : __begin_(0),
-      __end_(0),
-      __end_cap_(0, __a)
+    : __begin_(nullptr),
+      __end_(nullptr),
+      __end_cap_(nullptr, __a)
 {
 }
 
 template <class _Tp, class _Allocator>
 __vector_base<_Tp, _Allocator>::~__vector_base()
 {
-    if (__begin_ != 0)
+    if (__begin_ != nullptr)
     {
         clear();
         __alloc_traits::deallocate(__alloc(), __begin_, capacity());
@@ -481,7 +478,7 @@
 }
 
 template <class _Tp, class _Allocator = allocator<_Tp> >
-class _LIBCPP_TYPE_VIS vector
+class _LIBCPP_TYPE_VIS_ONLY vector
     : private __vector_base<_Tp, _Allocator>
 {
 private:
@@ -521,15 +518,19 @@
 #endif
     }
     explicit vector(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit vector(size_type __n, const allocator_type& __a);
+#endif
     vector(size_type __n, const_reference __x);
     vector(size_type __n, const_reference __x, const allocator_type& __a);
     template <class _InputIterator>
-        vector(_InputIterator __first, _InputIterator __last,
+        vector(_InputIterator __first,
                typename enable_if<__is_input_iterator  <_InputIterator>::value &&
                                  !__is_forward_iterator<_InputIterator>::value &&
                                  is_constructible<
                                     value_type,
-                                    typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
+                                    typename iterator_traits<_InputIterator>::reference>::value,
+                                 _InputIterator>::type __last);
     template <class _InputIterator>
         vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
                typename enable_if<__is_input_iterator  <_InputIterator>::value &&
@@ -538,11 +539,12 @@
                                     value_type,
                                     typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
     template <class _ForwardIterator>
-        vector(_ForwardIterator __first, _ForwardIterator __last,
+        vector(_ForwardIterator __first,
                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
                                  is_constructible<
                                     value_type,
-                                    typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);
+                                    typename iterator_traits<_ForwardIterator>::reference>::value,
+                                 _ForwardIterator>::type __last);
     template <class _ForwardIterator>
         vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
@@ -797,7 +799,7 @@
         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
     void __move_assign(vector& __c, false_type);
     _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last) _NOEXCEPT
+    void __destruct_at_end(pointer __new_last) _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __c_node* __c = __get_db()->__find_c_and_lock(this);
@@ -878,11 +880,11 @@
 void
 vector<_Tp, _Allocator>::deallocate() _NOEXCEPT
 {
-    if (this->__begin_ != 0)
+    if (this->__begin_ != nullptr)
     {
         clear();
         __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
-        this->__begin_ = this->__end_ = this->__end_cap() = 0;
+        this->__begin_ = this->__end_ = this->__end_cap() = nullptr;
     }
 }
 
@@ -895,7 +897,7 @@
 
 //  Precondition:  __new_size > capacity()
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::size_type
 vector<_Tp, _Allocator>::__recommend(size_type __new_size) const
 {
@@ -933,7 +935,7 @@
 //  Postcondition:  size() == old size() + __n
 //  Postcondition:  [i] == __x for all i in [size() - __n, __n)
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
 {
@@ -1027,6 +1029,22 @@
     }
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n);
+    }
+}
+#endif
+
 template <class _Tp, class _Allocator>
 vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x)
 {
@@ -1056,12 +1074,13 @@
 
 template <class _Tp, class _Allocator>
 template <class _InputIterator>
-vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
+vector<_Tp, _Allocator>::vector(_InputIterator __first,
        typename enable_if<__is_input_iterator  <_InputIterator>::value &&
                          !__is_forward_iterator<_InputIterator>::value &&
                          is_constructible<
                             value_type,
-                            typename iterator_traits<_InputIterator>::reference>::value>::type*)
+                            typename iterator_traits<_InputIterator>::reference>::value,
+                          _InputIterator>::type __last)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __get_db()->__insert_c(this);
@@ -1089,11 +1108,12 @@
 
 template <class _Tp, class _Allocator>
 template <class _ForwardIterator>
-vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
+vector<_Tp, _Allocator>::vector(_ForwardIterator __first,
                                 typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
                                 is_constructible<
                                    value_type,
-                                   typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
+                                   typename iterator_traits<_ForwardIterator>::reference>::value,
+                                                   _ForwardIterator>::type __last)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __get_db()->__insert_c(this);
@@ -1159,7 +1179,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<_Tp, _Allocator>::vector(vector&& __x)
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
     : __base(_VSTD::move(__x.__alloc()))
@@ -1171,11 +1191,11 @@
     this->__begin_ = __x.__begin_;
     this->__end_ = __x.__end_;
     this->__end_cap() = __x.__end_cap();
-    __x.__begin_ = __x.__end_ = __x.__end_cap() = 0;
+    __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a)
     : __base(__a)
 {
@@ -1202,7 +1222,7 @@
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1216,7 +1236,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
     : __base(__a)
 {
@@ -1233,7 +1253,7 @@
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<_Tp, _Allocator>&
 vector<_Tp, _Allocator>::operator=(vector&& __x)
         _NOEXCEPT_(
@@ -1277,7 +1297,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<_Tp, _Allocator>&
 vector<_Tp, _Allocator>::operator=(const vector& __x)
 {
@@ -1366,7 +1386,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT
 {
@@ -1378,7 +1398,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::const_iterator
 vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT
 {
@@ -1390,7 +1410,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::begin() _NOEXCEPT
 {
@@ -1398,7 +1418,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::const_iterator
 vector<_Tp, _Allocator>::begin() const _NOEXCEPT
 {
@@ -1406,7 +1426,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::end() _NOEXCEPT
 {
@@ -1414,7 +1434,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::const_iterator
 vector<_Tp, _Allocator>::end() const _NOEXCEPT
 {
@@ -1422,7 +1442,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::reference
 vector<_Tp, _Allocator>::operator[](size_type __n)
 {
@@ -1431,7 +1451,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::const_reference
 vector<_Tp, _Allocator>::operator[](size_type __n) const
 {
@@ -1509,7 +1529,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<_Tp, _Allocator>::push_back(const_reference __x)
 {
@@ -1526,7 +1546,7 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<_Tp, _Allocator>::push_back(value_type&& __x)
 {
@@ -1558,7 +1578,7 @@
 
 template <class _Tp, class _Allocator>
 template <class... _Args>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
 {
@@ -1577,7 +1597,7 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<_Tp, _Allocator>::pop_back()
 {
@@ -1586,7 +1606,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __position)
 {
@@ -1597,7 +1617,8 @@
 #endif
     _LIBCPP_ASSERT(__position != end(),
         "vector::erase(iterator) called with a non-dereferenceable iterator");
-    pointer __p = const_cast<pointer>(&*__position);
+    difference_type __ps = __position - cbegin();
+    pointer __p = this->__begin_ + __ps;
     iterator __r = __make_iter(__p);
     this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
     return __r;
@@ -1943,9 +1964,9 @@
 bool
 vector<_Tp, _Allocator>::__invariants() const
 {
-    if (this->__begin_ == 0)
+    if (this->__begin_ == nullptr)
     {
-        if (this->__end_ != 0 || this->__end_cap() != 0)
+        if (this->__end_ != nullptr || this->__end_cap() != nullptr)
             return false;
     }
     else
@@ -1995,7 +2016,7 @@
 #endif  // _LIBCPP_DEBUG_LEVEL >= 2
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<_Tp, _Allocator>::__invalidate_all_iterators()
 {
@@ -2017,7 +2038,7 @@
 };
 
 template <class _Allocator>
-class _LIBCPP_TYPE_VIS vector<bool, _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY vector<bool, _Allocator>
     : private __vector_base_common<true>
 {
 public:
@@ -2030,21 +2051,8 @@
     typedef size_type __storage_type;
     typedef __bit_iterator<vector, false>            pointer;
     typedef __bit_iterator<vector, true>             const_pointer;
-#ifdef _LIBCPP_DEBUG
-    typedef __debug_iter<vector, pointer>            iterator;
-    typedef __debug_iter<vector, const_pointer>      const_iterator;
-
-    friend class __debug_iter<vector, pointer>;
-    friend class __debug_iter<vector, const_pointer>;
-
-    pair<iterator*, const_iterator*> __iterator_list_;
-
-    _LIBCPP_INLINE_VISIBILITY iterator*&       __get_iterator_list(iterator*)       {return __iterator_list_.first;}
-    _LIBCPP_INLINE_VISIBILITY const_iterator*& __get_iterator_list(const_iterator*) {return __iterator_list_.second;}
-#else  // _LIBCPP_DEBUG
     typedef pointer                                  iterator;
     typedef const_pointer                            const_iterator;
-#endif  // _LIBCPP_DEBUG
     typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;
 
@@ -2096,6 +2104,9 @@
     _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a);
     ~vector();
     explicit vector(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit vector(size_type __n, const allocator_type& __a);
+#endif
     vector(size_type __n, const value_type& __v);
     vector(size_type __n, const value_type& __v, const allocator_type& __a);
     template <class _InputIterator>
@@ -2227,8 +2238,20 @@
     _LIBCPP_INLINE_VISIBILITY const_reference back()  const {return __make_ref(__size_ - 1);}
 
     void push_back(const value_type& __x);
+#if _LIBCPP_STD_VER > 11
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY void emplace_back(_Args&&... __args)
+        { push_back ( value_type ( _VSTD::forward<_Args>(__args)... )); }
+#endif
+
     _LIBCPP_INLINE_VISIBILITY void pop_back() {--__size_;}
 
+#if _LIBCPP_STD_VER > 11
+    template <class... _Args>
+   _LIBCPP_INLINE_VISIBILITY iterator emplace(const_iterator position, _Args&&... __args)
+        { return insert ( position, value_type ( _VSTD::forward<_Args>(__args)... )); }
+#endif
+
     iterator insert(const_iterator __position, const value_type& __x);
     iterator insert(const_iterator __position, size_type __n, const value_type& __x);
     iterator insert(const_iterator __position, size_type __n, const_reference __x);
@@ -2273,7 +2296,7 @@
     void allocate(size_type __n);
     void deallocate() _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
-    static size_type __align(size_type __new_size) _NOEXCEPT
+    static size_type __align_it(size_type __new_size) _NOEXCEPT
         {return __new_size + (__bits_per_word-1) & ~(__bits_per_word-1);};
     _LIBCPP_INLINE_VISIBILITY  size_type __recommend(size_type __new_size) const;
     _LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x);
@@ -2291,14 +2314,6 @@
     _LIBCPP_INLINE_VISIBILITY
     const_reference __make_ref(size_type __pos) const _NOEXCEPT
         {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
-#ifdef _LIBCPP_DEBUG
-    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_type __pos)
-        {return iterator(this, pointer(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word)));}
-    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_type __pos) const
-        {return const_iterator(this, const_pointer(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word)));}
-    _LIBCPP_INLINE_VISIBILITY iterator __const_iterator_cast(const_iterator __p)
-        {return iterator(this, pointer(const_cast<__storage_pointer>(__p.base().__seg_), __p.base().__ctz_));}
-#else  // _LIBCPP_DEBUG
     _LIBCPP_INLINE_VISIBILITY
     iterator __make_iter(size_type __pos) _NOEXCEPT
         {return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
@@ -2307,8 +2322,7 @@
         {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
     _LIBCPP_INLINE_VISIBILITY
     iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT
-        {return iterator(const_cast<__storage_pointer>(__p.__seg_), __p.__ctz_);}
-#endif  // _LIBCPP_DEBUG
+        {return begin() + (__p - cbegin());}
 
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const vector& __v)
@@ -2375,20 +2389,14 @@
     friend class __bit_iterator<vector, false>;
     friend class __bit_iterator<vector, true>;
     friend struct __bit_array<vector>;
-    friend struct _LIBCPP_TYPE_VIS hash<vector>;
+    friend struct _LIBCPP_TYPE_VIS_ONLY hash<vector>;
 };
 
 template <class _Allocator>
-#ifndef _LIBCPP_DEBUG
-_LIBCPP_INLINE_VISIBILITY inline
-#endif
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<bool, _Allocator>::__invalidate_all_iterators()
 {
-#ifdef _LIBCPP_DEBUG
-    iterator::__remove_all(this);
-    const_iterator::__remove_all(this);
-#endif  // _LIBCPP_DEBUG
 }
 
 //  Allocate space for __n objects
@@ -2414,11 +2422,11 @@
 void
 vector<bool, _Allocator>::deallocate() _NOEXCEPT
 {
-    if (this->__begin_ != 0)
+    if (this->__begin_ != nullptr)
     {
         __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());
         __invalidate_all_iterators();
-        this->__begin_ = 0;
+        this->__begin_ = nullptr;
         this->__size_ = this->__cap() = 0;
     }
 }
@@ -2436,7 +2444,7 @@
 
 //  Precondition:  __new_size > capacity()
 template <class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<bool, _Allocator>::size_type
 vector<bool, _Allocator>::__recommend(size_type __new_size) const
 {
@@ -2446,7 +2454,7 @@
     const size_type __cap = capacity();
     if (__cap >= __ms / 2)
         return __ms;
-    return _VSTD::max(2*__cap, __align(__new_size));
+    return _VSTD::max(2*__cap, __align_it(__new_size));
 }
 
 //  Default constructs __n objects starting at __end_
@@ -2454,7 +2462,7 @@
 //  Precondition:  size() + __n <= capacity()
 //  Postcondition:  size() == size() + __n
 template <class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x)
 {
@@ -2478,19 +2486,19 @@
 }
 
 template <class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<bool, _Allocator>::vector()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
 }
 
 template <class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<bool, _Allocator>::vector(const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2498,7 +2506,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(size_type __n)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2509,9 +2517,24 @@
     }
 }
 
+#if _LIBCPP_STD_VER > 11
+template <class _Allocator>
+vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a))
+{
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n, false);
+    }
+}
+#endif
+
 template <class _Allocator>
 vector<bool, _Allocator>::vector(size_type __n, const value_type& __x)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2524,7 +2547,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2540,7 +2563,7 @@
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
        typename enable_if<__is_input_iterator  <_InputIterator>::value &&
                          !__is_forward_iterator<_InputIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2554,7 +2577,7 @@
     }
     catch (...)
     {
-        if (__begin_ != 0)
+        if (__begin_ != nullptr)
             __storage_traits::deallocate(__alloc(), __begin_, __cap());
         __invalidate_all_iterators();
         throw;
@@ -2567,7 +2590,7 @@
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
        typename enable_if<__is_input_iterator  <_InputIterator>::value &&
                          !__is_forward_iterator<_InputIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2581,7 +2604,7 @@
     }
     catch (...)
     {
-        if (__begin_ != 0)
+        if (__begin_ != nullptr)
             __storage_traits::deallocate(__alloc(), __begin_, __cap());
         __invalidate_all_iterators();
         throw;
@@ -2593,7 +2616,7 @@
 template <class _ForwardIterator>
 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
                                 typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2609,7 +2632,7 @@
 template <class _ForwardIterator>
 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
                                 typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2625,7 +2648,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2639,7 +2662,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2656,16 +2679,14 @@
 template <class _Allocator>
 vector<bool, _Allocator>::~vector()
 {
-    if (__begin_ != 0)
+    if (__begin_ != nullptr)
         __storage_traits::deallocate(__alloc(), __begin_, __cap());
-#ifdef _LIBCPP_DEBUG
     __invalidate_all_iterators();
-#endif
 }
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(const vector& __v)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __storage_traits::select_on_container_copy_construction(__v.__alloc()))
 {
@@ -2678,7 +2699,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __a)
 {
@@ -2713,21 +2734,21 @@
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 template <class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<bool, _Allocator>::vector(vector&& __v)
         _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
     : __begin_(__v.__begin_),
       __size_(__v.__size_),
       __cap_alloc_(__v.__cap_alloc_)
 {
-    __v.__begin_ = 0;
+    __v.__begin_ = nullptr;
     __v.__size_ = 0;
     __v.__cap() = 0;
 }
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __a)
 {
@@ -2747,7 +2768,7 @@
 }
 
 template <class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 vector<bool, _Allocator>&
 vector<bool, _Allocator>::operator=(vector&& __v)
         _NOEXCEPT_(
@@ -3034,7 +3055,7 @@
 }
 
 template <class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 typename vector<bool, _Allocator>::iterator
 vector<bool, _Allocator>::erase(const_iterator __position)
 {
@@ -3065,10 +3086,6 @@
     _VSTD::swap(this->__size_, __x.__size_);
     _VSTD::swap(this->__cap(), __x.__cap());
     __swap_alloc(this->__alloc(), __x.__alloc());
-#ifdef _LIBCPP_DEBUG
-    iterator::swap(this, &__x);
-    const_iterator::swap(this, &__x);
-#endif  // _LIBCPP_DEBUG
 }
 
 template <class _Allocator>
@@ -3123,7 +3140,7 @@
 bool
 vector<bool, _Allocator>::__invariants() const
 {
-    if (this->__begin_ == 0)
+    if (this->__begin_ == nullptr)
     {
         if (this->__size_ != 0 || this->__cap() != 0)
             return false;
@@ -3158,7 +3175,7 @@
 }
 
 template <class _Allocator>
-struct _LIBCPP_TYPE_VIS hash<vector<bool, _Allocator> >
+struct _LIBCPP_TYPE_VIS_ONLY hash<vector<bool, _Allocator> >
     : public unary_function<vector<bool, _Allocator>, size_t>
 {
     _LIBCPP_INLINE_VISIBILITY
@@ -3167,7 +3184,7 @@
 };
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
 {
@@ -3176,7 +3193,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
 {
@@ -3184,7 +3201,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
 {
@@ -3192,7 +3209,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
 {
@@ -3200,7 +3217,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
 {
@@ -3208,7 +3225,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
 {
@@ -3216,7 +3233,7 @@
 }
 
 template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
+inline _LIBCPP_INLINE_VISIBILITY
 void
 swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 1d3bce6..35076a1 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -55,6 +55,43 @@
 append_if(compile_flags LIBCXX_HAS_FPIC_FLAG -fPIC)
 append_if(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
+      "-compatibility_version 1"
+      "-current_version ${LIBCXX_VERSION}"
+      "-install_name /usr/lib/libc++.1.dylib"
+      "-Wl,-reexport_library,/usr/lib/libc++abi.dylib"
+      "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
+      "/usr/lib/libSystem.B.dylib")
+  else()
+    if ( ${CMAKE_OSX_SYSROOT} )
+      list(FIND ${CMAKE_OSX_ARCHITECTURES} "armv7" OSX_HAS_ARMV7)
+      if (OSX_HAS_ARMV7)
+        set(OSX_RE_EXPORT_LINE
+          "${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib"
+          "-Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++sjlj-abi.exp")
+      else()
+        set(OSX_RE_EXPORT_LINE
+          "-Wl,-reexport_library,${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib")
+      endif()
+    else()
+      set (OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
+    endif()
+
+    list(APPEND link_flags
+      "-compatibility_version 1"
+      "-install_name /usr/lib/libc++.1.dylib"
+      "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
+      "${OSX_RE_EXPORT_LINE}"
+      "-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/notweak.exp"
+      "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/weak.exp")
+  endif()
+endif()
+
+string(REPLACE ";" " " link_flags "${link_flags}")
+
 set_target_properties(cxx
   PROPERTIES
     COMPILE_FLAGS "${compile_flags}"
@@ -68,10 +105,3 @@
   LIBRARY DESTINATION lib
   ARCHIVE DESTINATION lib
   )
-
-install(DIRECTORY ../include/
-  DESTINATION include/c++/v1
-  FILES_MATCHING
-  PATTERN "*"
-  PATTERN ".svn" EXCLUDE
-  )
diff --git a/lib/buildit b/lib/buildit
index 1f77dbb..af6b466 100755
--- a/lib/buildit
+++ b/lib/buildit
@@ -22,22 +22,21 @@
     CC=clang
 fi
 
-if [ -z $MACOSX_DEPLOYMENT_TARGET ]
+if [ -z "$MACOSX_DEPLOYMENT_TARGET" ]
 then
-    if [ -z $IPHONEOS_DEPLOYMENT_TARGET ]
+    if [ -z "$IPHONEOS_DEPLOYMENT_TARGET" ]
     then
         MACOSX_DEPLOYMENT_TARGET=10.7
     fi
 fi
 
-if [ -z $RC_ProjectSourceVersion ]
+if [ -z "$RC_ProjectSourceVersion" ]
 then
   RC_ProjectSourceVersion=1
 fi
 
-EXTRA_FLAGS="-std=c++0x -fstrict-aliasing -Wall -Wextra -Wshadow -Wconversion \
-             -Wnewline-eof -Wpadded -Wmissing-prototypes -Wstrict-aliasing=2 \
-             -Wstrict-overflow=4 "
+EXTRA_FLAGS="-nostdinc++ -std=c++11 -fstrict-aliasing -Wall -Wextra -Wshadow -Wconversion \
+             -Wpadded -Wstrict-aliasing=2 -Wstrict-overflow=4 "
 
 case $TRIPLE in
   *-apple-*)
@@ -48,7 +47,7 @@
     SOEXT=dylib
     if [ "$MACOSX_DEPLOYMENT_TARGET" == "10.6" ]
     then
-        EXTRA_FLAGS="-std=c++0x -U__STRICT_ANSI__"
+        EXTRA_FLAGS="-nostdinc++ -std=c++11 -U__STRICT_ANSI__"
         LDSHARED_FLAGS="-o libc++.1.dylib \
             -dynamiclib -nodefaultlibs -current_version 1 \
             -compatibility_version 1 \
@@ -59,7 +58,7 @@
     else
         if [ -n "$SDKROOT" ]
         then
-            EXTRA_FLAGS+="-isysroot ${SDKROOT}"
+            EXTRA_FLAGS+="-nostdinc++ -isysroot ${SDKROOT}"
             if echo "${RC_ARCHS}" | grep -q "armv7"  
             then
                 RE_EXPORT_LINE="${SDKROOT}/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,libc++sjlj-abi.exp"
@@ -97,6 +96,23 @@
         -shared -nodefaultlibs -Wl,--export-all-symbols -Wl,--allow-multiple-definition -Wl,--out-implib,libc++.dll.a \
         -lsupc++ -lpthread -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt"
     ;;
+  *-ibm-*)
+    hostOS=`uname`
+    hostOS=`echo $hostOS | sed -e "s/\s+$//"`
+    hostOS=`echo $hostOS | tr '[A-Z]' '[a-z]'`
+
+    if [ $hostOS == "linux" ]
+    then
+      LDSHARED_FLAGS="-o libc++.so.1 \
+        -qmkshrobj -Wl,-soname,libc++.so.1 \
+        -lpthread -lrt -lc -lstdc++"
+      EXTRA_FLAGS="-qlanglvl=extended0x -D__GLIBCXX__=1"
+    else
+      LDSHARED_FLAGS="-o shr.o -qmkshrobj -lpthread -bnoquiet"
+      EXTRA_FLAGS="-qlanglvl=extended0x"
+    fi
+    RC_CFLAGS="-qpic=large"
+    ;;
   *)
     RC_CFLAGS="-fPIC"
     SOEXT=so
@@ -106,7 +122,7 @@
     ;;
 esac
 
-if [ -z $RC_XBS ]
+if [ -z "$RC_XBS" ]
 then
     rm -f libc++.1.$SOEXT*
 fi
@@ -114,12 +130,12 @@
 set -x
 
 for FILE in ../src/*.cpp; do
-    $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -nostdinc++ -I../include $FILE
+    $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $FILE
 done
 case $TRIPLE in
   *-*-mingw*)
   for FILE in ../src/support/win32/*.cpp; do
-    $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -nostdinc++ -I../include $FILE
+    $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $FILE
   done
   ;;
 esac
@@ -136,13 +152,23 @@
         ;;
     *-*-mingw*)
         ;;
+    *-ibm-*)
+        if [ $hostOS == "linux" ]
+        then
+           rm -f libc++.so
+           ln -s libc++.so.1 libc++.so
+        else #AIX
+           rm -f libc++.a
+           ar r libc++.a shr.o
+        fi
+        ;;
     *)
         rm -f libc++.so
         ln -s libc++.so.1 libc++.so
         ;;
 esac
 
-if [ -z $RC_XBS ]
+if [ -z "$RC_XBS" ]
 then
     rm *.o
 fi
diff --git a/src/algorithm.cpp b/src/algorithm.cpp
index 6d5cf7c..10c4c33 100644
--- a/src/algorithm.cpp
+++ b/src/algorithm.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
 #include "algorithm"
 #include "random"
 #include "mutex"
diff --git a/src/debug.cpp b/src/debug.cpp
index 04d570e..d0e8679 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define _LIBCPP_DEBUG2 1
+#define _LIBCPP_DEBUG 1
 #include "__config"
 #include "__debug"
 #include "functional"
@@ -118,20 +118,19 @@
 __libcpp_db::__insert_ic(void* __i, const void* __c)
 {
     WLock _(mut());
-    __i_node* i = __insert_iterator(__i);
-    const char* errmsg =
-        "Container constructed in a translation unit with debug mode disabled."
-        " But it is being used in a translation unit with debug mode enabled."
-        " Enable it in the other translation unit with #define _LIBCPP_DEBUG2 1";
-    _LIBCPP_ASSERT(__cbeg_ != __cend_, errmsg);
+    if (__cbeg_ == __cend_)
+        return;
     size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
     __c_node* c = __cbeg_[hc];
-    _LIBCPP_ASSERT(c != nullptr, errmsg);
+    if (c == nullptr)
+        return;
     while (c->__c_ != __c)
     {
         c = c->__next_;
-        _LIBCPP_ASSERT(c != nullptr, errmsg);
+        if (c == nullptr)
+            return;
     }
+    __i_node* i = __insert_iterator(__i);
     c->__add(i);
     i->__c_ = c;
 }
@@ -217,18 +216,23 @@
 __libcpp_db::__invalidate_all(void* __c)
 {
     WLock _(mut());
-    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p = __cbeg_[hc];
-    _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all A");
-    while (p->__c_ != __c)
+    if (__cend_ != __cbeg_)
     {
-        p = p->__next_;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all B");
-    }
-    while (p->end_ != p->beg_)
-    {
-        --p->end_;
-        (*p->end_)->__c_ = nullptr;
+        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
+        __c_node* p = __cbeg_[hc];
+        if (p == nullptr)
+            return;
+        while (p->__c_ != __c)
+        {
+            p = p->__next_;
+            if (p == nullptr)
+                return;
+        }
+        while (p->end_ != p->beg_)
+        {
+            --p->end_;
+            (*p->end_)->__c_ = nullptr;
+        }
     }
 }
 
@@ -236,13 +240,26 @@
 __libcpp_db::__find_c_and_lock(void* __c) const
 {
     mut().lock();
+    if (__cend_ == __cbeg_)
+    {
+        mut().unlock();
+        return nullptr;
+    }
     size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
     __c_node* p = __cbeg_[hc];
-    _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock A");
+    if (p == nullptr)
+    {
+        mut().unlock();
+        return nullptr;
+    }
     while (p->__c_ != __c)
     {
         p = p->__next_;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock B");
+        if (p == nullptr)
+        {
+            mut().unlock();
+            return nullptr;
+        }
     }
     return p;
 }
@@ -271,28 +288,35 @@
 __libcpp_db::__erase_c(void* __c)
 {
     WLock _(mut());
-    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p = __cbeg_[hc];
-    __c_node* q = nullptr;
-    _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
-    while (p->__c_ != __c)
+    if (__cend_ != __cbeg_)
     {
-        q = p;
-        p = p->__next_;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
+        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
+        __c_node* p = __cbeg_[hc];
+        if (p == nullptr)
+            return;
+        __c_node* q = nullptr;
+        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
+        while (p->__c_ != __c)
+        {
+            q = p;
+            p = p->__next_;
+            if (p == nullptr)
+                return;
+            _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
+        }
+        if (q == nullptr)
+            __cbeg_[hc] = p->__next_;
+        else
+            q->__next_ = p->__next_;
+        while (p->end_ != p->beg_)
+        {
+            --p->end_;
+            (*p->end_)->__c_ = nullptr;
+        }
+        free(p->beg_);
+        free(p);
+        --__csz_;
     }
-    if (q == nullptr)
-        __cbeg_[hc] = p->__next_;
-    else
-        q->__next_ = p->__next_;
-    while (p->end_ != p->beg_)
-    {
-        --p->end_;
-        (*p->end_)->__c_ = nullptr;
-    }
-    free(p->beg_);
-    free(p);
-    --__csz_;
 }
 
 void
@@ -354,7 +378,7 @@
 }
 
 bool
-__libcpp_db::__comparable(const void* __i, const void* __j) const
+__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
 {
     RLock _(mut());
     __i_node* i = __find_iterator(__i);
diff --git a/src/exception.cpp b/src/exception.cpp
index 1d2f6b2..572d977 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -7,8 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "exception"
+#include "new"
 
 #ifndef __has_include
 #define __has_include(inc) 0
@@ -22,7 +24,7 @@
   #ifndef _LIBCPPABI_VERSION
     using namespace __cxxabiapple;
     // On Darwin, there are two STL shared libraries and a lower level ABI
-    // shared libray.  The globals holding the current terminate handler and
+    // shared library.  The globals holding the current terminate handler and
     // current unexpected handler are in the ABI library.
     #define __terminate_handler  __cxxabiapple::__cxa_terminate_handler
     #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
@@ -88,13 +90,15 @@
 #endif  // _LIBCPP_NO_EXCEPTIONS
         (*get_terminate())();
         // handler should not return
-        ::abort ();
+        printf("terminate_handler unexpectedly returned\n");
+        ::abort();
 #ifndef _LIBCPP_NO_EXCEPTIONS
     }
     catch (...)
     {
         // handler should not throw exception
-        ::abort ();
+        printf("terminate_handler unexpectedly threw an exception\n");
+        ::abort();
     }
 #endif  // _LIBCPP_NO_EXCEPTIONS
 }
@@ -108,11 +112,17 @@
     // on Darwin, there is a helper function so __cxa_get_globals is private
     return __cxa_uncaught_exception();
 #else  // __APPLE__
-    #warning uncaught_exception not yet implemented
+#   if defined(_MSC_VER) && ! defined(__clang__)
+        _LIBCPP_WARNING("uncaught_exception not yet implemented")
+#   else
+#       warning uncaught_exception not yet implemented
+#   endif
+    printf("uncaught_exception not yet implemented\n");
     ::abort();
 #endif  // __APPLE__
 }
 
+
 #ifndef _LIBCPPABI_VERSION
 
 exception::~exception() _NOEXCEPT
@@ -139,15 +149,50 @@
 
 #endif
 
+#if defined(__GLIBCXX__)
+
+// libsupc++ does not implement the dependent EH ABI and the functionality
+// it uses to implement std::exception_ptr (which it declares as an alias of
+// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
+// we have little choice but to hijack std::__exception_ptr::exception_ptr's
+// (which fortunately has the same layout as our std::exception_ptr) copy
+// constructor, assignment operator and destructor (which are part of its
+// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
+// function.
+
+namespace __exception_ptr
+{
+
+struct exception_ptr
+{
+    void* __ptr_;
+
+    exception_ptr(const exception_ptr&) _NOEXCEPT;
+    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+    ~exception_ptr() _NOEXCEPT;
+};
+
+}
+
+_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
+
+#endif
 
 exception_ptr::~exception_ptr() _NOEXCEPT
 {
 #if HAVE_DEPENDENT_EH_ABI
     __cxa_decrement_exception_refcount(__ptr_);
+#elif defined(__GLIBCXX__)
+    reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
 #else
-    #warning exception_ptr not yet implemented
+#   if defined(_MSC_VER) && ! defined(__clang__)
+        _LIBCPP_WARNING("exception_ptr not yet implemented")
+#   else
+#       warning exception_ptr not yet implemented
+#   endif
+    printf("exception_ptr not yet implemented\n");
     ::abort();
-#endif  // __APPLE__
+#endif
 }
 
 exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
@@ -155,10 +200,18 @@
 {
 #if HAVE_DEPENDENT_EH_ABI
     __cxa_increment_exception_refcount(__ptr_);
+#elif defined(__GLIBCXX__)
+    new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
+        reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
 #else
-    #warning exception_ptr not yet implemented
+#   if defined(_MSC_VER) && ! defined(__clang__)
+        _LIBCPP_WARNING("exception_ptr not yet implemented")
+#   else
+#       warning exception_ptr not yet implemented
+#   endif
+    printf("exception_ptr not yet implemented\n");
     ::abort();
-#endif  // __APPLE__
+#endif
 }
 
 exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
@@ -171,10 +224,19 @@
         __ptr_ = other.__ptr_;
     }
     return *this;
-#else  // __APPLE__
-    #warning exception_ptr not yet implemented
+#elif defined(__GLIBCXX__)
+    *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
+        reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
+    return *this;
+#else
+#   if defined(_MSC_VER) && ! defined(__clang__)
+        _LIBCPP_WARNING("exception_ptr not yet implemented")
+#   else
+#       warning exception_ptr not yet implemented
+#   endif
+    printf("exception_ptr not yet implemented\n");
     ::abort();
-#endif  // __APPLE__
+#endif
 }
 
 nested_exception::nested_exception() _NOEXCEPT
@@ -182,10 +244,14 @@
 {
 }
 
+#if !defined(__GLIBCXX__)
+
 nested_exception::~nested_exception() _NOEXCEPT
 {
 }
 
+#endif
+
 _LIBCPP_NORETURN
 void
 nested_exception::rethrow_nested() const
@@ -195,6 +261,7 @@
     rethrow_exception(__ptr_);
 }
 
+#if !defined(__GLIBCXX__)
 
 exception_ptr current_exception() _NOEXCEPT
 {
@@ -205,12 +272,19 @@
     exception_ptr ptr;
     ptr.__ptr_ = __cxa_current_primary_exception();
     return ptr;
-#else  // __APPLE__
-    #warning exception_ptr not yet implemented
+#else
+#   if defined(_MSC_VER) && ! defined(__clang__)
+        _LIBCPP_WARNING( "exception_ptr not yet implemented" )
+#   else
+#       warning exception_ptr not yet implemented
+#   endif
+    printf("exception_ptr not yet implemented\n");
     ::abort();
-#endif  // __APPLE__
+#endif
 }
 
+#endif  // !__GLIBCXX__
+
 _LIBCPP_NORETURN
 void rethrow_exception(exception_ptr p)
 {
@@ -218,9 +292,16 @@
     __cxa_rethrow_primary_exception(p.__ptr_);
     // if p.__ptr_ is NULL, above returns so we terminate
     terminate();
-#else  // __APPLE__
-    #warning exception_ptr not yet implemented
+#elif defined(__GLIBCXX__)
+    rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
+#else
+#   if defined(_MSC_VER) && ! defined(__clang__)
+        _LIBCPP_WARNING("exception_ptr not yet implemented")
+#   else
+#       warning exception_ptr not yet implemented
+#   endif
+    printf("exception_ptr not yet implemented\n");
     ::abort();
-#endif  // __APPLE__
+#endif
 }
 } // std
diff --git a/src/future.cpp b/src/future.cpp
index 7d9a5b5..70919ab 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -26,11 +26,15 @@
     return "future";
 }
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch"
+
 string
 __future_error_category::message(int ev) const
 {
     switch (static_cast<future_errc>(ev))
     {
+    case future_errc(0):  // For backwards compatibility with C++11 (LWG 2056)
     case future_errc::broken_promise:
         return string("The associated promise has been destructed prior "
                       "to the associated state becoming ready.");
@@ -46,6 +50,8 @@
     return string("unspecified future_errc value\n");
 }
 
+#pragma clang diagnostic pop
+
 const error_category&
 future_category() _NOEXCEPT
 {
diff --git a/src/ios.cpp b/src/ios.cpp
index 732a61b..bbe3c07 100644
--- a/src/ios.cpp
+++ b/src/ios.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+
 #include "ios"
 #include "streambuf"
 #include "istream"
@@ -61,7 +63,7 @@
 }
 
 const error_category&
-iostream_category()
+iostream_category() _NOEXCEPT
 {
     static __iostream_category s;
     return s;
@@ -147,8 +149,11 @@
 }
 
 // xalloc
-
+#if __has_feature(cxx_atomic)
+atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0);
+#else
 int ios_base::__xindex_ = 0;
+#endif
 
 int
 ios_base::xalloc()
diff --git a/src/iostream.cpp b/src/iostream.cpp
index f413681..7102e43 100644
--- a/src/iostream.cpp
+++ b/src/iostream.cpp
@@ -22,14 +22,14 @@
 _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
 _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
 
-_ALIGNAS_TYPE (istream) char cin [sizeof(istream)];
-_ALIGNAS_TYPE (ostream) char cout[sizeof(ostream)];
-_ALIGNAS_TYPE (ostream) char cerr[sizeof(ostream)];
-_ALIGNAS_TYPE (ostream) char clog[sizeof(ostream)];
-_ALIGNAS_TYPE (wistream) char wcin [sizeof(wistream)];
-_ALIGNAS_TYPE (wostream) char wcout[sizeof(wostream)];
-_ALIGNAS_TYPE (wostream) char wcerr[sizeof(wostream)];
-_ALIGNAS_TYPE (wostream) char wclog[sizeof(wostream)];
+_ALIGNAS_TYPE (istream)  _LIBCPP_FUNC_VIS char cin [sizeof(istream)];
+_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char cout[sizeof(ostream)];
+_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)];
+_ALIGNAS_TYPE (ostream)  _LIBCPP_FUNC_VIS char clog[sizeof(ostream)];
+_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin [sizeof(wistream)];
+_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)];
+_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)];
+_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)];
 
 ios_base::Init __start_std_streams;
 
diff --git a/src/locale.cpp b/src/locale.cpp
index d6ea3ae..79195a4 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#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__
@@ -18,23 +20,27 @@
 #include "codecvt"
 #include "vector"
 #include "algorithm"
-#include "algorithm"
 #include "typeinfo"
-#include "type_traits"
+#ifndef _LIBCPP_NO_EXCEPTIONS
+#  include "type_traits"
+#endif
 #include "clocale"
 #include "cstring"
 #include "cwctype"
 #include "__sso_allocator"
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
 #include <support/win32/locale_win32.h>
-#else // _WIN32
+#else // _LIBCPP_MSVCRT
 #include <langinfo.h>
-#endif // _!WIN32
+#endif // !_LIBCPP_MSVCRT
 #include <stdlib.h>
+#include <stdio.h>
 
 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
 // lots of noise in the build log, but no bugs that I know of. 
+#if defined(__clang__)
 #pragma clang diagnostic ignored "-Wsign-conversion"
+#endif
 
 // @LOCALMOD-START Newlib doesn't have the following C extensions for locales.
 #if defined(_NEWLIB_VERSION)
@@ -116,6 +122,11 @@
 
 }
 
+#if defined(_AIX)
+// Set priority to INT_MIN + 256 + 150
+# pragma priority ( -2147483242 )
+#endif
+
 const locale::category locale::none;
 const locale::category locale::collate;
 const locale::category locale::ctype;
@@ -125,14 +136,23 @@
 const locale::category locale::messages;
 const locale::category locale::all;
 
+#if defined(__clang__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wpadded"
+#endif
 
 class _LIBCPP_HIDDEN locale::__imp
     : public facet
 {
     enum {N = 28};
+#if defined(_LIBCPP_MSVC)
+// FIXME: MSVC doesn't support aligned parameters by value.
+// I can't get the __sso_allocator to work here
+// for MSVC I think for this reason.
+    vector<facet*> facets_;
+#else
     vector<facet*, __sso_allocator<facet*, N> > facets_;
+#endif
     string         name_;
 public:
     explicit __imp(size_t refs = 0);
@@ -156,7 +176,9 @@
     template <class F> void install_from(const __imp& other);
 };
 
+#if defined(__clang__)
 #pragma clang diagnostic pop
+#endif
 
 locale::__imp::__imp(size_t refs)
     : facet(refs),
@@ -766,7 +788,7 @@
 bool
 ctype<wchar_t>::do_is(mask m, char_type c) const
 {
-    return isascii(c) ? ctype<char>::classic_table()[c] & m : false;
+    return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
 }
 
 const wchar_t*
@@ -801,7 +823,7 @@
 {
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
     return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
-#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__)
     return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
 #else
     return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
@@ -814,7 +836,7 @@
     for (; low != high; ++low)
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
         *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
-#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__)
         *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
                              : *low;
 #else
@@ -828,7 +850,7 @@
 {
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
     return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
-#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__)
     return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
 #else
     return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
@@ -841,7 +863,7 @@
     for (; low != high; ++low)
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
         *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
-#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__)
         *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
                              : *low;
 #else
@@ -908,9 +930,11 @@
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
     return isascii(c) ?
       static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
+#elif defined(__NetBSD__)
+    return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
 #elif defined(__GLIBC__) || defined(EMSCRIPTEN)
     return isascii(c) ? 
-      static_cast<char>(__classic_upper_table()[static_cast<size_t>(c)]) : c;
+      static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
 #else
     return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
 #endif
@@ -923,6 +947,8 @@
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
         *low = isascii(*low) ?
           static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
+#elif defined(__NetBSD__)
+        *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
 #elif defined(__GLIBC__) || defined(EMSCRIPTEN)
         *low = isascii(*low) ?
           static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
@@ -938,7 +964,9 @@
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
     return isascii(c) ?
       static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
-#elif defined(__GLIBC__) || defined(EMSCRIPTEN)
+#elif defined(__NetBSD__)
+    return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
+#elif defined(__GLIBC__) || defined(EMSCRIPTEN) || defined(__NetBSD__)
     return isascii(c) ?
       static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
 #else
@@ -952,6 +980,8 @@
     for (; low != high; ++low)
 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
         *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
+#elif defined(__NetBSD__)
+        *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
 #elif defined(__GLIBC__) || defined(EMSCRIPTEN)
         *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
 #else
@@ -1004,11 +1034,13 @@
 {
 #if defined(__APPLE__) || defined(__FreeBSD__)
     return _DefaultRuneLocale.__runetype;
+#elif defined(__NetBSD__)
+    return _C_ctype_tab_ + 1;
 #elif defined(__GLIBC__)
     return __cloc()->__ctype_b;
 #elif __sun__
     return __ctype_mask;
-#elif defined(_WIN32)
+#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     return _ctype+1; // internal ctype mask table defined in msvcrt.dll
 // This is assumed to be safe, which is a nonsense assumption because we're
 // going to end up dereferencing it later...
@@ -1018,10 +1050,13 @@
     // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
     return _ctype_ + 1;
     // @LOCALMOD-END
+#elif defined(_AIX)
+    return (const unsigned long *)__lc_ctype_ptr->obj->mask;
 #else
     // Platform not supported: abort so the person doing the port knows what to
     // fix
 # warning  ctype<char>::classic_table() is not implemented
+    printf("ctype<char>::classic_table() is not implemented\n");
     abort();
     return NULL;
 #endif
@@ -1039,9 +1074,20 @@
 {
     return __cloc()->__ctype_toupper;
 }
-#endif // __GLIBC__
+#elif __NetBSD__
+const short*
+ctype<char>::__classic_lower_table() _NOEXCEPT
+{
+    return _C_tolower_tab_ + 1;
+}
 
-#if defined(EMSCRIPTEN)
+const short*
+ctype<char>::__classic_upper_table() _NOEXCEPT
+{
+    return _C_toupper_tab_ + 1;
+}
+
+#elif defined(EMSCRIPTEN)
 const int*
 ctype<char>::__classic_lower_table() _NOEXCEPT
 {
@@ -1053,7 +1099,7 @@
 {
     return *__ctype_toupper_loc();
 }
-#endif // EMSCRIPTEN
+#endif // __GLIBC__ || EMSCRIPTEN || __NETBSD__
 
 // template <> class ctype_byname<char>
 
@@ -1391,7 +1437,7 @@
 
 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
     : locale::facet(refs),
-      __l(0)
+      __l(_LIBCPP_GET_C_LOCALE)
 {
 }
 
@@ -1408,7 +1454,7 @@
 
 codecvt<wchar_t, char, mbstate_t>::~codecvt()
 {
-    if (__l != 0)
+    if (__l != _LIBCPP_GET_C_LOCALE)
         freelocale(__l);
 }
 
@@ -3195,14 +3241,25 @@
     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
 {
+#if _WIN32
+    const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
+    const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
+    const uint16_t* _frm_nxt = _frm;
+#else
     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
     const uint32_t* _frm_nxt = _frm;
+#endif
     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
     uint8_t* _to_nxt = _to;
+#if _WIN32
+    result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
+                            _Maxcode_, _Mode_);
+#else
     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
                             _Maxcode_, _Mode_);
+#endif
     frm_nxt = frm + (_frm_nxt - _frm);
     to_nxt = to + (_to_nxt - _to);
     return r;
@@ -3216,11 +3273,19 @@
     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
     const uint8_t* _frm_nxt = _frm;
+#if _WIN32
+    uint16_t* _to = reinterpret_cast<uint16_t*>(to);
+    uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
+    uint16_t* _to_nxt = _to;
+    result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
+                            _Maxcode_, _Mode_);
+#else
     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
     uint32_t* _to_nxt = _to;
     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
                             _Maxcode_, _Mode_);
+#endif
     frm_nxt = frm + (_frm_nxt - _frm);
     to_nxt = to + (_to_nxt - _to);
     return r;
@@ -4322,7 +4387,7 @@
     if (__flags & ios_base::showpoint)
         *__fmtp++ = '#';
     ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
-    bool uppercase = __flags & ios_base::uppercase;
+    bool uppercase = (__flags & ios_base::uppercase) != 0;
     if (floatfield == (ios_base::fixed | ios_base::scientific))
         specify_precision = false;
     else
@@ -4653,9 +4718,12 @@
 {
     freelocale(__loc_);
 }
-
+#if defined(__clang__)
 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
+#endif
+#if defined(__GNUG__)
 #pragma GCC   diagnostic ignored "-Wmissing-field-initializers"
+#endif
 
 template <>
 string
@@ -4801,7 +4869,9 @@
     return result;
 }
 
+#if defined(__clang__)
 #pragma clang diagnostic ignored "-Wmissing-braces"
+#endif
 
 template <>
 wstring
@@ -5334,7 +5404,7 @@
 
 __time_put::~__time_put()
 {
-    if (__loc_)
+    if (__loc_ != _LIBCPP_GET_C_LOCALE)
         freelocale(__loc_);
 }
 
@@ -5820,19 +5890,19 @@
         __frac_digits_ = lc->int_frac_digits;
     else
         __frac_digits_ = base::do_frac_digits();
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     if (lc->p_sign_posn == 0)
-#else // _WIN32
+#else // _LIBCPP_MSVCRT
     if (lc->int_p_sign_posn == 0)
-#endif //_WIN32
+#endif // !_LIBCPP_MSVCRT
         __positive_sign_ = "()";
     else
         __positive_sign_ = lc->positive_sign;
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     if(lc->n_sign_posn == 0)
-#else // _WIN32
+#else // _LIBCPP_MSVCRT
     if (lc->int_n_sign_posn == 0)
-#endif // _WIN32
+#endif // !_LIBCPP_MSVCRT
         __negative_sign_ = "()";
     else
         __negative_sign_ = lc->negative_sign;
@@ -5840,19 +5910,19 @@
     // the same places in curr_symbol since there's no way to
     // represent anything else.
     string_type __dummy_curr_symbol = __curr_symbol_;
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     __init_pat(__pos_format_, __dummy_curr_symbol, true,
                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
     __init_pat(__neg_format_, __curr_symbol_, true,
                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
-#else
+#else // _LIBCPP_MSVCRT
     __init_pat(__pos_format_, __dummy_curr_symbol, true,
                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
                lc->int_p_sign_posn, ' ');
     __init_pat(__neg_format_, __curr_symbol_, true,
                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
                lc->int_n_sign_posn, ' ');
-#endif // _WIN32
+#endif // !_LIBCPP_MSVCRT
 }
 
 template<>
@@ -5979,11 +6049,11 @@
         __frac_digits_ = lc->int_frac_digits;
     else
         __frac_digits_ = base::do_frac_digits();
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     if (lc->p_sign_posn == 0)
-#else // _WIN32
+#else // _LIBCPP_MSVCRT
     if (lc->int_p_sign_posn == 0)
-#endif // _WIN32
+#endif // !_LIBCPP_MSVCRT
         __positive_sign_ = L"()";
     else
     {
@@ -5999,11 +6069,11 @@
         wbe = wbuf + j;
         __positive_sign_.assign(wbuf, wbe);
     }
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     if (lc->n_sign_posn == 0)
-#else // _WIN32
+#else // _LIBCPP_MSVCRT
     if (lc->int_n_sign_posn == 0)
-#endif // _WIN32
+#endif // !_LIBCPP_MSVCRT
         __negative_sign_ = L"()";
     else
     {
@@ -6023,19 +6093,19 @@
     // the same places in curr_symbol since there's no way to
     // represent anything else.
     string_type __dummy_curr_symbol = __curr_symbol_;
-#ifdef _WIN32
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
     __init_pat(__pos_format_, __dummy_curr_symbol, true,
                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
     __init_pat(__neg_format_, __curr_symbol_, true,
                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
-#else // _WIN32
+#else // _LIBCPP_MSVCRT
     __init_pat(__pos_format_, __dummy_curr_symbol, true,
                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
                lc->int_p_sign_posn, L' ');
     __init_pat(__neg_format_, __curr_symbol_, true,
                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
                lc->int_n_sign_posn, L' ');
-#endif // _WIN32
+#endif // !_LIBCPP_MSVCRT
 }
 
 void __do_nothing(void*) {}
diff --git a/src/mutex.cpp b/src/mutex.cpp
index 42195aa..0767897 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -42,6 +42,7 @@
 mutex::unlock() _NOEXCEPT
 {
     int ec = pthread_mutex_unlock(&__m_);
+    (void)ec;
     assert(ec == 0);
 }
 
@@ -79,6 +80,7 @@
 recursive_mutex::~recursive_mutex()
 {
     int e = pthread_mutex_destroy(&__m_);
+    (void)e;
     assert(e == 0);
 }
 
@@ -94,6 +96,7 @@
 recursive_mutex::unlock() _NOEXCEPT
 {
     int e = pthread_mutex_unlock(&__m_);
+    (void)e;
     assert(e == 0);
 }
 
diff --git a/src/new.cpp b/src/new.cpp
index b23a516..f4998cf 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define _LIBCPP_BUILDING_NEW
+
 #include <stdlib.h>
 
 #include "new"
@@ -20,7 +22,7 @@
 
     #ifndef _LIBCPPABI_VERSION
         // On Darwin, there are two STL shared libraries and a lower level ABI
-        // shared libray.  The global holding the current new handler is
+        // shared library.  The global holding the current new handler is
         // in the ABI library and named __cxa_new_handler.
         #define __new_handler __cxxabiapple::__cxa_new_handler
     #endif
@@ -28,16 +30,18 @@
     #if defined(LIBCXXRT) || __has_include(<cxxabi.h>)
         #include <cxxabi.h>
     #endif  // __has_include(<cxxabi.h>)
-    #ifndef _LIBCPPABI_VERSION
+    #if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
         static std::new_handler __new_handler;
     #endif  // _LIBCPPABI_VERSION
 #endif
 
+#ifndef __GLIBCXX__
+
 // Implement all new and delete operators as weak definitions
 // in this shared library, so that they can be overriden by programs
 // that define non-weak copies of the functions.
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void *
 operator new(std::size_t size)
 #if !__has_feature(cxx_noexcept)
@@ -64,7 +68,7 @@
     return p;
 }
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void*
 operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
 {
@@ -83,7 +87,7 @@
     return p;
 }
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void*
 operator new[](size_t size)
 #if !__has_feature(cxx_noexcept)
@@ -93,7 +97,7 @@
     return ::operator new(size);
 }
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void*
 operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
 {
@@ -112,7 +116,7 @@
     return p;
 }
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
 operator delete(void* ptr) _NOEXCEPT
 {
@@ -120,34 +124,40 @@
         ::free(ptr);
 }
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
 operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
 {
     ::operator delete(ptr);
 }
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
 operator delete[] (void* ptr) _NOEXCEPT
 {
     ::operator delete (ptr);
 }
 
-__attribute__((__weak__, __visibility__("default")))
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
 operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
 {
     ::operator delete[](ptr);
 }
 
+#endif // !__GLIBCXX__
+
 namespace std
 {
 
+#ifndef __GLIBCXX__
 const nothrow_t nothrow = {};
+#endif
 
 #ifndef _LIBCPPABI_VERSION
 
+#ifndef __GLIBCXX__
+
 new_handler
 set_new_handler(new_handler handler) _NOEXCEPT
 {
@@ -160,12 +170,16 @@
     return __sync_fetch_and_add(&__new_handler, (new_handler)0);
 }
 
+#endif // !__GLIBCXX__
+
 #ifndef LIBCXXRT
 
 bad_alloc::bad_alloc() _NOEXCEPT
 {
 }
 
+#ifndef __GLIBCXX__
+
 bad_alloc::~bad_alloc() _NOEXCEPT
 {
 }
@@ -176,6 +190,8 @@
     return "std::bad_alloc";
 }
 
+#endif // !__GLIBCXX__
+
 #endif //LIBCXXRT
 
 bad_array_new_length::bad_array_new_length() _NOEXCEPT
@@ -187,12 +203,28 @@
 }
 
 const char*
+bad_array_length::what() const _NOEXCEPT
+{
+    return "bad_array_length";
+}
+
+bad_array_length::bad_array_length() _NOEXCEPT
+{
+}
+
+bad_array_length::~bad_array_length() _NOEXCEPT
+{
+}
+
+const char*
 bad_array_new_length::what() const _NOEXCEPT
 {
     return "bad_array_new_length";
 }
 
-#endif
+#endif // _LIBCPPABI_VERSION
+
+#ifndef LIBSTDCXX
 
 void
 __throw_bad_alloc()
@@ -202,4 +234,6 @@
 #endif
 }
 
+#endif // !LIBSTDCXX
+
 }  // std
diff --git a/src/optional.cpp b/src/optional.cpp
new file mode 100644
index 0000000..b614d81
--- /dev/null
+++ b/src/optional.cpp
@@ -0,0 +1,25 @@
+//===------------------------ optional.cpp --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "experimental/optional"
+
+namespace std  // purposefully not using versioning namespace
+{ namespace experimental {
+
+#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
+bad_optional_access::~bad_optional_access() _NOEXCEPT {}
+
+#else
+
+bad_optional_access::~bad_optional_access() _NOEXCEPT = default;
+
+#endif
+
+}}  // std::experimental
diff --git a/src/random.cpp b/src/random.cpp
index c8486cf..f7f83c9 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -7,14 +7,22 @@
 //
 //===----------------------------------------------------------------------===//
 
+#if defined(_WIN32)
+// Must be defined before including stdlib.h to enable rand_s().
+#define _CRT_RAND_S
+#include <stdio.h>
+#endif
+
 #include "random"
 #include "system_error"
 
 #ifdef __sun__
 #define rename solaris_headers_are_broken
 #endif
+#if !defined(_WIN32)
 #include <fcntl.h>
 #include <unistd.h>
+#endif // defined(_WIN32)
 #include <errno.h>
 // @LOCALMOD-START
 #if defined(__native_client__)
@@ -24,6 +32,25 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#if defined(_WIN32)
+random_device::random_device(const string&)
+{
+}
+
+random_device::~random_device()
+{
+}
+
+unsigned
+random_device::operator()()
+{
+    unsigned r;
+    errno_t err = rand_s(&r);
+    if (err)
+        __throw_system_error(err, "random_device rand_s failed.");
+    return r;
+}
+#else
 random_device::random_device(const string& __token)
 // @LOCALMOD-START
 #if defined(__native_client__)
@@ -70,6 +97,7 @@
 // @LOCALMOD-END
     return r;
 }
+#endif // defined(_WIN32)
 
 double
 random_device::entropy() const _NOEXCEPT
diff --git a/src/shared_mutex.cpp b/src/shared_mutex.cpp
new file mode 100644
index 0000000..5fb22e4
--- /dev/null
+++ b/src/shared_mutex.cpp
@@ -0,0 +1,101 @@
+//===---------------------- shared_mutex.cpp ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define _LIBCPP_BUILDING_SHARED_MUTEX
+#include "shared_mutex"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+shared_mutex::shared_mutex()
+    : __state_(0)
+{
+}
+
+// Exclusive ownership
+
+void
+shared_mutex::lock()
+{
+    unique_lock<mutex> lk(__mut_);
+    while (__state_ & __write_entered_)
+        __gate1_.wait(lk);
+    __state_ |= __write_entered_;
+    while (__state_ & __n_readers_)
+        __gate2_.wait(lk);
+}
+
+bool
+shared_mutex::try_lock()
+{
+    unique_lock<mutex> lk(__mut_);
+    if (__state_ == 0)
+    {
+        __state_ = __write_entered_;
+        return true;
+    }
+    return false;
+}
+
+void
+shared_mutex::unlock()
+{
+    lock_guard<mutex> _(__mut_);
+    __state_ = 0;
+    __gate1_.notify_all();
+}
+
+// Shared ownership
+
+void
+shared_mutex::lock_shared()
+{
+    unique_lock<mutex> lk(__mut_);
+    while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+        __gate1_.wait(lk);
+    unsigned num_readers = (__state_ & __n_readers_) + 1;
+    __state_ &= ~__n_readers_;
+    __state_ |= num_readers;
+}
+
+bool
+shared_mutex::try_lock_shared()
+{
+    unique_lock<mutex> lk(__mut_);
+    unsigned num_readers = __state_ & __n_readers_;
+    if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
+    {
+        ++num_readers;
+        __state_ &= ~__n_readers_;
+        __state_ |= num_readers;
+        return true;
+    }
+    return false;
+}
+
+void
+shared_mutex::unlock_shared()
+{
+    lock_guard<mutex> _(__mut_);
+    unsigned num_readers = (__state_ & __n_readers_) - 1;
+    __state_ &= ~__n_readers_;
+    __state_ |= num_readers;
+    if (__state_ & __write_entered_)
+    {
+        if (num_readers == 0)
+            __gate2_.notify_one();
+    }
+    else
+    {
+        if (num_readers == __n_readers_ - 1)
+            __gate1_.notify_one();
+    }
+}
+
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/src/stdexcept.cpp b/src/stdexcept.cpp
index 0c4e832..a4207d6 100644
--- a/src/stdexcept.cpp
+++ b/src/stdexcept.cpp
@@ -28,7 +28,9 @@
 
 // Note:  optimize for size
 
+#if ! defined(_LIBCPP_MSVC)
 #pragma GCC visibility push(hidden)
+#endif
 
 namespace
 {
@@ -47,9 +49,9 @@
     count_t& count() const _NOEXCEPT {return (count_t&)(*(str_ - sizeof(count_t)));}
 public:
     explicit __libcpp_nmstr(const char* msg);
-    __libcpp_nmstr(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW;
-    __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _LIBCPP_CANTTHROW;
-    ~__libcpp_nmstr() _LIBCPP_CANTTHROW;
+    __libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT;
+    __libcpp_nmstr& operator=(const __libcpp_nmstr& s) _NOEXCEPT;
+    ~__libcpp_nmstr();
     const char* c_str() const _NOEXCEPT {return str_;}
 };
 
@@ -61,18 +63,18 @@
     c[0] = c[1] = len;
     str_ += offset;
     count() = 0;
-    std::strcpy(const_cast<char*>(c_str()), msg);
+    std::memcpy(const_cast<char*>(c_str()), msg, len + 1);
 }
 
 inline
-__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s)
+__libcpp_nmstr::__libcpp_nmstr(const __libcpp_nmstr& s) _NOEXCEPT
     : str_(s.str_)
 {
     __sync_add_and_fetch(&count(), 1);
 }
 
 __libcpp_nmstr&
-__libcpp_nmstr::operator=(const __libcpp_nmstr& s)
+__libcpp_nmstr::operator=(const __libcpp_nmstr& s) _NOEXCEPT
 {
     const char* p = str_;
     str_ = s.str_;
@@ -91,7 +93,9 @@
 
 }
 
+#if ! defined(_LIBCPP_MSVC)
 #pragma GCC visibility pop
+#endif
 
 namespace std  // purposefully not using versioning namespace
 {
@@ -123,7 +127,7 @@
     return *this;
 }
 
-#ifndef _LIBCPPABI_VERSION
+#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
 
 logic_error::~logic_error() _NOEXCEPT
 {
@@ -167,7 +171,7 @@
     return *this;
 }
 
-#ifndef _LIBCPPABI_VERSION
+#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
 
 runtime_error::~runtime_error() _NOEXCEPT
 {
diff --git a/src/string.cpp b/src/string.cpp
index c71af4f..fde5212 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -7,13 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+
 #include "string"
 #include "cstdlib"
 #include "cwchar"
 #include "cerrno"
-#ifdef _WIN32
+#include "limits"
+#include "stdexcept"
+#ifdef _LIBCPP_MSVCRT
 #include "support/win32/support.h"
-#endif // _WIN32
+#endif // _LIBCPP_MSVCRT
+#include <stdio.h>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -26,662 +31,500 @@
     string
     operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
 
+namespace
+{
+
+template<typename T>
+inline
+void throw_helper( const string& msg )
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw T( msg );
+#else
+    printf("%s\n", msg.c_str());
+    abort();
+#endif
+}
+
+inline
+void throw_from_string_out_of_range( const string& func )
+{
+    throw_helper<out_of_range>(func + ": out of range");
+}
+
+inline
+void throw_from_string_invalid_arg( const string& func )
+{
+    throw_helper<invalid_argument>(func + ": no conversion");
+}
+
+// as_integer
+
+template<typename V, typename S, typename F>
+inline
+V
+as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
+{
+    typename S::value_type* ptr;
+    const typename S::value_type* const p = str.c_str();
+    typename remove_reference<decltype(errno)>::type errno_save = errno;
+    errno = 0;
+    V r = f(p, &ptr, base);
+    swap(errno, errno_save);
+    if (errno_save == ERANGE)
+        throw_from_string_out_of_range(func);
+    if (ptr == p)
+        throw_from_string_invalid_arg(func);
+    if (idx)
+        *idx = static_cast<size_t>(ptr - p);
+    return r;
+}
+
+template<typename V, typename S>
+inline
+V
+as_integer(const string& func, const S& s, size_t* idx, int base);
+
+// string
+template<>
+inline
+int
+as_integer(const string& func, const string& s, size_t* idx, int base )
+{
+    // Use long as no Standard string to integer exists.
+    long r = as_integer_helper<long>( func, s, idx, base, strtol );
+    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
+        throw_from_string_out_of_range(func);
+    return static_cast<int>(r);
+}
+
+template<>
+inline
+long
+as_integer(const string& func, const string& s, size_t* idx, int base )
+{
+    return as_integer_helper<long>( func, s, idx, base, strtol );
+}
+
+template<>
+inline
+unsigned long
+as_integer( const string& func, const string& s, size_t* idx, int base )
+{
+    return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
+}
+
+template<>
+inline
+long long
+as_integer( const string& func, const string& s, size_t* idx, int base )
+{
+    return as_integer_helper<long long>( func, s, idx, base, strtoll );
+}
+
+template<>
+inline
+unsigned long long
+as_integer( const string& func, const string& s, size_t* idx, int base )
+{
+    return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
+}
+
+// wstring
+template<>
+inline
+int
+as_integer( const string& func, const wstring& s, size_t* idx, int base )
+{
+    // Use long as no Stantard string to integer exists.
+    long r = as_integer_helper<long>( func, s, idx, base, wcstol );
+    if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
+        throw_from_string_out_of_range(func);
+    return static_cast<int>(r);
+}
+
+template<>
+inline
+long
+as_integer( const string& func, const wstring& s, size_t* idx, int base )
+{
+    return as_integer_helper<long>( func, s, idx, base, wcstol );
+}
+
+template<>
+inline
+unsigned long
+as_integer( const string& func, const wstring& s, size_t* idx, int base )
+{
+    return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
+}
+
+template<>
+inline
+long long
+as_integer( const string& func, const wstring& s, size_t* idx, int base )
+{
+    return as_integer_helper<long long>( func, s, idx, base, wcstoll );
+}
+
+template<>
+inline
+unsigned long long
+as_integer( const string& func, const wstring& s, size_t* idx, int base )
+{
+    return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
+}
+
+// as_float
+
+template<typename V, typename S, typename F> 
+inline
+V
+as_float_helper(const string& func, const S& str, size_t* idx, F f )
+{
+    typename S::value_type* ptr;
+    const typename S::value_type* const p = str.c_str();
+    typename remove_reference<decltype(errno)>::type errno_save = errno;
+    errno = 0;
+    V r = f(p, &ptr);
+    swap(errno, errno_save);
+    if (errno_save == ERANGE)
+        throw_from_string_out_of_range(func);
+    if (ptr == p)
+        throw_from_string_invalid_arg(func);
+    if (idx)
+        *idx = static_cast<size_t>(ptr - p);
+    return r;
+}
+
+template<typename V, typename S>
+inline
+V as_float( const string& func, const S& s, size_t* idx = nullptr );
+
+template<>
+inline
+float
+as_float( const string& func, const string& s, size_t* idx )
+{
+    return as_float_helper<float>( func, s, idx, strtof );
+}
+
+template<>
+inline
+double
+as_float(const string& func, const string& s, size_t* idx )
+{
+    return as_float_helper<double>( func, s, idx, strtod );
+}
+
+template<>
+inline
+long double
+as_float( const string& func, const string& s, size_t* idx )
+{
+    return as_float_helper<long double>( func, s, idx, strtold );
+}
+
+template<>
+inline
+float
+as_float( const string& func, const wstring& s, size_t* idx )
+{
+    return as_float_helper<float>( func, s, idx, wcstof );
+}
+
+template<>
+inline
+double
+as_float( const string& func, const wstring& s, size_t* idx )
+{
+    return as_float_helper<double>( func, s, idx, wcstod );
+}
+
+template<>
+inline
+long double
+as_float( const string& func, const wstring& s, size_t* idx )
+{
+    return as_float_helper<long double>( func, s, idx, wcstold );
+}
+
+}  // unnamed namespace
+
 int
 stoi(const string& str, size_t* idx, int base)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long r = strtol(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE || r < numeric_limits<int>::min() ||
-                                numeric_limits<int>::max() < r)
-        throw out_of_range("stoi: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoi: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return static_cast<int>(r);
+    return as_integer<int>( "stoi", str, idx, base );
 }
 
 int
 stoi(const wstring& str, size_t* idx, int base)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long r = wcstol(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE || r < numeric_limits<int>::min() ||
-                                numeric_limits<int>::max() < r)
-        throw out_of_range("stoi: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoi: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return static_cast<int>(r);
+    return as_integer<int>( "stoi", str, idx, base );
 }
 
 long
 stol(const string& str, size_t* idx, int base)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long r = strtol(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stol: out of range");
-    if (ptr == p)
-        throw invalid_argument("stol: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<long>( "stol", str, idx, base );
 }
 
 long
 stol(const wstring& str, size_t* idx, int base)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long r = wcstol(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stol: out of range");
-    if (ptr == p)
-        throw invalid_argument("stol: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<long>( "stol", str, idx, base );
 }
 
 unsigned long
 stoul(const string& str, size_t* idx, int base)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    unsigned long r = strtoul(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stoul: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoul: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<unsigned long>( "stoul", str, idx, base );
 }
 
 unsigned long
 stoul(const wstring& str, size_t* idx, int base)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    unsigned long r = wcstoul(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stoul: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoul: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<unsigned long>( "stoul", str, idx, base );
 }
 
 long long
 stoll(const string& str, size_t* idx, int base)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long long r = strtoll(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stoll: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoll: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<long long>( "stoll", str, idx, base );
 }
 
 long long
 stoll(const wstring& str, size_t* idx, int base)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long long r = wcstoll(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stoll: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoll: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<long long>( "stoll", str, idx, base );
 }
 
 unsigned long long
 stoull(const string& str, size_t* idx, int base)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    unsigned long long r = strtoull(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stoull: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoull: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<unsigned long long>( "stoull", str, idx, base );
 }
 
 unsigned long long
 stoull(const wstring& str, size_t* idx, int base)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    unsigned long long r = wcstoull(p, &ptr, base);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stoull: out of range");
-    if (ptr == p)
-        throw invalid_argument("stoull: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_integer<unsigned long long>( "stoull", str, idx, base );
 }
 
 float
 stof(const string& str, size_t* idx)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    float r = strtof(p, &ptr);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stof: out of range");
-    if (ptr == p)
-        throw invalid_argument("stof: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_float<float>( "stof", str, idx );
 }
 
 float
 stof(const wstring& str, size_t* idx)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    float r = wcstof(p, &ptr);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stof: out of range");
-    if (ptr == p)
-        throw invalid_argument("stof: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_float<float>( "stof", str, idx );
 }
 
 double
 stod(const string& str, size_t* idx)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    double r = strtod(p, &ptr);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stod: out of range");
-    if (ptr == p)
-        throw invalid_argument("stod: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_float<double>( "stod", str, idx );
 }
 
 double
 stod(const wstring& str, size_t* idx)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    double r = wcstod(p, &ptr);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stod: out of range");
-    if (ptr == p)
-        throw invalid_argument("stod: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_float<double>( "stod", str, idx );
 }
 
 long double
 stold(const string& str, size_t* idx)
 {
-    char* ptr;
-    const char* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long double r = strtold(p, &ptr);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stold: out of range");
-    if (ptr == p)
-        throw invalid_argument("stold: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_float<long double>( "stold", str, idx );
 }
 
 long double
 stold(const wstring& str, size_t* idx)
 {
-    wchar_t* ptr;
-    const wchar_t* const p = str.c_str();
-    typename remove_reference<decltype(errno)>::type errno_save = errno;
-    errno = 0;
-    long double r = wcstold(p, &ptr);
-    swap(errno, errno_save);
-#ifndef _LIBCPP_NO_EXCEPTIONS
-    if (errno_save == ERANGE)
-        throw out_of_range("stold: out of range");
-    if (ptr == p)
-        throw invalid_argument("stold: no conversion");
-#endif  // _LIBCPP_NO_EXCEPTIONS
-    if (idx)
-        *idx = static_cast<size_t>(ptr - p);
-    return r;
+    return as_float<long double>( "stold", str, idx );
 }
 
+// to_string
+
+namespace
+{
+
+// as_string
+
+template<typename S, typename P, typename V >
+inline
+S
+as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
+{
+    typedef typename S::size_type size_type;
+    size_type available = s.size();
+    while (true)
+    {
+        int status = sprintf_like(&s[0], available + 1, fmt, a);
+        if ( status >= 0 )
+        {
+            size_type used = static_cast<size_type>(status);
+            if ( used <= available )
+            {
+                s.resize( used );
+                break;
+            }
+            available = used; // Assume this is advice of how much space we need.
+        }
+        else
+            available = available * 2 + 1;
+        s.resize(available);
+    }
+    return s;
+}
+
+template <class S, class V, bool = is_floating_point<V>::value>
+struct initial_string;
+
+template <class V, bool b>
+struct initial_string<string, V, b>
+{
+    string
+    operator()() const
+    {
+        string s;
+        s.resize(s.capacity());
+        return s;
+    }
+};
+
+template <class V>
+struct initial_string<wstring, V, false>
+{
+    wstring
+    operator()() const
+    {
+        const size_t n = (numeric_limits<unsigned long long>::digits / 3)
+          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
+          + 1;
+        wstring s(n, wchar_t());
+        s.resize(s.capacity());
+        return s;
+    }
+};
+
+template <class V>
+struct initial_string<wstring, V, true>
+{
+    wstring
+    operator()() const
+    {
+        wstring s(20, wchar_t());
+        s.resize(s.capacity());
+        return s;
+    }
+};
+
+typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
+
+inline
+wide_printf
+get_swprintf()
+{
+#ifndef _LIBCPP_MSVCRT
+    return swprintf;
+#else
+    return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
+#endif
+}
+
+}  // unnamed namespace
+
 string to_string(int val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%d", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, int>()(), "%d", val);
 }
 
 string to_string(unsigned val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%u", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
 }
 
 string to_string(long val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%ld", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
 }
 
 string to_string(unsigned long val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%lu", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
 }
 
 string to_string(long long val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%lld", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
 }
 
 string to_string(unsigned long long val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%llu", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
 }
 
 string to_string(float val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%f", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, float>()(), "%f", val);
 }
 
 string to_string(double val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%f", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, double>()(), "%f", val);
 }
 
 string to_string(long double val)
 {
-    string s;
-    s.resize(s.capacity());
-    while (true)
-    {
-        size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%Lf", val));
-        if (n2 <= s.size())
-        {
-            s.resize(n2);
-            break;
-        }
-        s.resize(n2);
-    }
-    return s;
+    return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
 }
 
 wstring to_wstring(int val)
 {
-    const size_t n = (numeric_limits<int>::digits / 3)
-          + ((numeric_limits<int>::digits % 3) != 0)
-          + 1;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%d", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
 }
 
 wstring to_wstring(unsigned val)
 {
-    const size_t n = (numeric_limits<unsigned>::digits / 3)
-          + ((numeric_limits<unsigned>::digits % 3) != 0)
-          + 1;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%u", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
 }
 
 wstring to_wstring(long val)
 {
-    const size_t n = (numeric_limits<long>::digits / 3)
-          + ((numeric_limits<long>::digits % 3) != 0)
-          + 1;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%ld", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
 }
 
 wstring to_wstring(unsigned long val)
 {
-    const size_t n = (numeric_limits<unsigned long>::digits / 3)
-          + ((numeric_limits<unsigned long>::digits % 3) != 0)
-          + 1;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%lu", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
 }
 
 wstring to_wstring(long long val)
 {
-    const size_t n = (numeric_limits<long long>::digits / 3)
-          + ((numeric_limits<long long>::digits % 3) != 0)
-          + 1;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%lld", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
 }
 
 wstring to_wstring(unsigned long long val)
 {
-    const size_t n = (numeric_limits<unsigned long long>::digits / 3)
-          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
-          + 1;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%llu", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
 }
 
 wstring to_wstring(float val)
 {
-    const size_t n = 20;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
 }
 
 wstring to_wstring(double val)
 {
-    const size_t n = 20;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
 }
 
 wstring to_wstring(long double val)
 {
-    const size_t n = 20;
-    wstring s(n, wchar_t());
-    s.resize(s.capacity());
-    while (true)
-    {
-        int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val);
-        if (n2 > 0)
-        {
-            s.resize(static_cast<size_t>(n2));
-            break;
-        }
-        s.resize(2*s.size());
-        s.resize(s.capacity());
-    }
-    return s;
+    return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
 }
-
 _LIBCPP_END_NAMESPACE_STD
diff --git a/src/strstream.cpp b/src/strstream.cpp
index 518422b..c1965ea 100644
--- a/src/strstream.cpp
+++ b/src/strstream.cpp
@@ -156,13 +156,13 @@
     {
         if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
             return int_type(EOF);
-        streamsize old_size = (epptr() ? epptr() : egptr()) - eback();
-        streamsize new_size = max<streamsize>(__alsize_, 2*old_size);
+        size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
+        size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size);
         if (new_size == 0)
             new_size = __default_alsize;
         char* buf = nullptr;
         if (__palloc_)
-            buf = static_cast<char*>(__palloc_(static_cast<size_t>(new_size)));
+            buf = static_cast<char*>(__palloc_(new_size));
         else
             buf = new char[new_size];
         if (buf == nullptr)
@@ -229,8 +229,8 @@
 strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
 {
     off_type __p(-1);
-    bool pos_in = __which & ios::in;
-    bool pos_out = __which & ios::out;
+    bool pos_in = (__which & ios::in) != 0;
+    bool pos_out = (__which & ios::out) != 0;
     bool legal = false;
     switch (__way)
     {
@@ -287,8 +287,8 @@
 strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
 {
     off_type __p(-1);
-    bool pos_in = __which & ios::in;
-    bool pos_out = __which & ios::out;
+    bool pos_in = (__which & ios::in) != 0;
+    bool pos_out = (__which & ios::out) != 0;
     if (pos_in || pos_out)
     {
         if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
diff --git a/src/support/win32/locale_win32.cpp b/src/support/win32/locale_win32.cpp
index e8c630c..5a43743 100644
--- a/src/support/win32/locale_win32.cpp
+++ b/src/support/win32/locale_win32.cpp
@@ -8,9 +8,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "support/win32/locale_win32.h"
-
-#include <stdarg.h> // va_start, va_end
+#include <locale>
+#include <cstdarg> // va_start, va_end
 
 // FIXME: base currently unused. Needs manual work to construct the new locale
 locale_t newlocale( int mask, const char * locale, locale_t /*base*/ )
@@ -34,38 +33,38 @@
     __locale_raii __current( uselocale(loc), uselocale );
     return localeconv();
 }
-size_t mbrlen_l( const char *__restrict__ s, size_t n,
-                 mbstate_t *__restrict__ ps, locale_t loc )
+size_t mbrlen_l( const char *__restrict s, size_t n,
+                 mbstate_t *__restrict ps, locale_t loc )
 {
     __locale_raii __current( uselocale(loc), uselocale );
     return mbrlen( s, n, ps );
 }
-size_t mbsrtowcs_l( wchar_t *__restrict__ dst, const char **__restrict__ src,
-                    size_t len, mbstate_t *__restrict__ ps, locale_t loc )
+size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                    size_t len, mbstate_t *__restrict ps, locale_t loc )
 {
     __locale_raii __current( uselocale(loc), uselocale );
     return mbsrtowcs( dst, src, len, ps );
 }
-size_t wcrtomb_l( char *__restrict__ s, wchar_t wc, mbstate_t *__restrict__ ps,
+size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,
                   locale_t loc )
 {
     __locale_raii __current( uselocale(loc), uselocale );
     return wcrtomb( s, wc, ps );
 }
-size_t mbrtowc_l( wchar_t *__restrict__ pwc, const char *__restrict__ s,
-                  size_t n, mbstate_t *__restrict__ ps, locale_t loc )
+size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,
+                  size_t n, mbstate_t *__restrict ps, locale_t loc )
 {
     __locale_raii __current( uselocale(loc), uselocale );
     return mbrtowc( pwc, s, n, ps );
 }
-size_t mbsnrtowcs_l( wchar_t *__restrict__ dst, const char **__restrict__ src,
-                     size_t nms, size_t len, mbstate_t *__restrict__ ps, locale_t loc )
+size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                     size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc )
 {
     __locale_raii __current( uselocale(loc), uselocale );
     return mbsnrtowcs( dst, src, nms, len, ps );
 }
-size_t wcsnrtombs_l( char *__restrict__ dst, const wchar_t **__restrict__ src,
-                     size_t nwc, size_t len, mbstate_t *__restrict__ ps, locale_t loc )
+size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
+                     size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc )
 {
     __locale_raii __current( uselocale(loc), uselocale );
     return wcsnrtombs( dst, src, nwc, len, ps );
@@ -81,6 +80,16 @@
     return wctob( c );
 }
 
+int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...)
+{
+    __locale_raii __current( uselocale(loc), uselocale );
+    va_list ap;
+    va_start( ap, format );
+    int result = vsnprintf( ret, n, format, ap );
+    va_end(ap);
+    return result;
+}
+
 int asprintf_l( char **ret, locale_t loc, const char *format, ... )
 {
     va_list ap;
diff --git a/src/support/win32/support.cpp b/src/support/win32/support.cpp
index 75f6391..6ee31e0 100644
--- a/src/support/win32/support.cpp
+++ b/src/support/win32/support.cpp
@@ -8,48 +8,58 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <support/win32/support.h>
-#include <stdarg.h> // va_start, va_end
-#include <stddef.h> // size_t
-#include <stdlib.h> // malloc
-#include <stdio.h>  // vsprintf, vsnprintf
-#include <string.h> // strcpy, wcsncpy
+#include <cstdarg> // va_start, va_end
+#include <cstddef> // size_t
+#include <cstdlib> // malloc
+#include <cstdio>  // vsprintf, vsnprintf
+#include <cstring> // strcpy, wcsncpy
+#include <cwchar>  // mbstate_t
 
-int asprintf(char **sptr, const char *__restrict fmt, ...)
+// Some of these functions aren't standard or if they conform, the name does not.
+
+int asprintf(char **sptr, const char *__restrict format, ...)
 {
     va_list ap;
-    va_start(ap, fmt);
-    int result = vasprintf(sptr, fmt, ap);
+    va_start(ap, format);
+    int result;
+    result = vasprintf(sptr, format, ap);
     va_end(ap);
     return result;
 }
 
-// Like sprintf, but when return value >= 0 it returns a pointer to a malloc'd string in *sptr.
+// Like sprintf, but when return value >= 0 it returns
+// a pointer to a malloc'd string in *sptr.
 // If return >= 0, use free to delete *sptr.
-int vasprintf( char **sptr, const char *__restrict fmt, va_list ap )
+int vasprintf( char **sptr, const char *__restrict format, va_list ap )
 {
     *sptr = NULL;
-    int count = vsnprintf( NULL, 0, fmt, ap ); // Query the buffer size required.
-    if( count >= 0 ) {
-        char* p = static_cast<char*>(malloc(count+1)); // Allocate memory for it and the terminator.
-        if ( p == NULL )
-            return -1;
-        if ( vsnprintf( p, count+1, fmt, ap ) == count ) // We should have used exactly what was required.
-            *sptr = p;
-        else { // Otherwise something is wrong, likely a bug in vsnprintf. If so free the memory and report the error.
-            free(p);
-            return -1;
-        }
+    // Query the count required.
+    int count = _vsnprintf( NULL, 0, format, ap );
+    if (count < 0)
+        return count;
+    size_t buffer_size = static_cast<size_t>(count) + 1;
+    char* p = static_cast<char*>(malloc(buffer_size));
+    if ( ! p )
+        return -1;
+    // If we haven't used exactly what was required, something is wrong.
+    // Maybe bug in vsnprintf. Report the error and return.
+    if (_vsnprintf(p, buffer_size, format, ap) != count) {
+        free(p);
+        return -1;
     }
-
+    // All good. This is returning memory to the caller not freeing it.
+    *sptr = p;
     return count;
 }
 
-// Returns >= 0: the number of wide characters found in the multi byte sequence src (of src_size_bytes),
-// that fit in the buffer dst (of max_dest_chars elements size). The count returned excludes the null terminator.
-// When dst is NULL, no characters are copied and no "out" parameters are updated.
+// Returns >= 0: the number of wide characters found in the 
+// multi byte sequence src (of src_size_bytes), that fit in the buffer dst 
+// (of max_dest_chars elements size). The count returned excludes the
+// null terminator. When dst is NULL, no characters are copied 
+// and no "out" parameters are updated.
 // Returns (size_t) -1: an incomplete sequence encountered.
-// Leaves *src pointing the next character to convert or NULL if a null character was converted from *src.
+// Leaves *src pointing the next character to convert or NULL 
+// if a null character was converted from *src.
 size_t mbsnrtowcs( wchar_t *__restrict dst, const char **__restrict src,
                    size_t src_size_bytes, size_t max_dest_chars, mbstate_t *__restrict ps )
 {
@@ -95,10 +105,13 @@
 }
 
 // Converts max_source_chars from the wide character buffer pointer to by *src,
-// into the multi byte character sequence buffer stored at dst which must be dst_size_bytes bytes in size.
-// Returns >= 0: the number of bytes in the sequence sequence converted frome *src, excluding the null terminator.
+// into the multi byte character sequence buffer stored at dst which must be
+// dst_size_bytes bytes in size.
+// Returns >= 0: the number of bytes in the sequence sequence 
+// converted frome *src, excluding the null terminator.
 // Returns size_t(-1) if an error occurs, also sets errno.
-// If dst is NULL dst_size_bytes is ignored and no bytes are copied to dst and no "out" parameters are updated.
+// If dst is NULL dst_size_bytes is ignored and no bytes are copied to dst 
+// and no "out" parameters are updated.
 size_t wcsnrtombs( char *__restrict dst, const wchar_t **__restrict src,
                    size_t max_source_chars, size_t dst_size_bytes, mbstate_t *__restrict ps )
 {
@@ -120,8 +133,9 @@
         if ( dst )
             result = wcrtomb_s( &char_size, dst + dest_converted, dest_remaining, c, ps);
         else
-            result = wcrtomb_s( &char_size, NULL, 0, c, ps); 
-        // If result is zero there is no error and char_size contains the size of the multi-byte-sequence converted.
+            result = wcrtomb_s( &char_size, NULL, 0, c, ps);
+        // If result is zero there is no error and char_size contains the 
+        // size of the multi-byte-sequence converted.
         // Otherwise result indicates an errno type error.
         if ( result == no_error ) {
             if ( c == L'\0' ) {
diff --git a/src/system_error.cpp b/src/system_error.cpp
index 7376b77..b40409f 100644
--- a/src/system_error.cpp
+++ b/src/system_error.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define	_LIBCPP_BUILDING_SYSTEM_ERROR
 #include "system_error"
 #include "string"
 #include "cstring"
diff --git a/src/thread.cpp b/src/thread.cpp
index de22025..a7351cf 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -14,13 +14,19 @@
 #include "limits"
 #include <sys/types.h>
 #if !defined(_WIN32)
-#if !defined(__sun__) && !defined(__linux__) && !defined(__native_client__) // @LOCALMOD
+#if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) // @LOCALMOD
 #include <sys/sysctl.h>
-#else
+#endif // !__sun__ && !__linux__ && !_AIX
 #include <unistd.h>
-#endif // !__sun__ && !__linux__
 #endif // !_WIN32
 
+#if defined(__NetBSD__)
+#pragma weak pthread_create // Do not create libpthread dependency
+#endif
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 thread::~thread()
@@ -67,7 +73,7 @@
     std::size_t s = sizeof(n);
     sysctl(mib, 2, &n, &s, 0, 0);
     return n;
-#elif (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && defined(_SC_NPROCESSORS_ONLN)) || defined(EMSCRIPTEN) || defined(__native_client__) // @LOCALMOD
+#elif defined(_SC_NPROCESSORS_ONLN)
     long result = sysconf(_SC_NPROCESSORS_ONLN);
     // sysconf returns -1 if the name is invalid, the option does not exist or
     // does not have a definite limit.
@@ -76,9 +82,18 @@
     if (result < 0)
         return 0;
     return static_cast<unsigned>(result);
+#elif defined(_WIN32)
+    SYSTEM_INFO info;
+    GetSystemInfo(&info);
+    return info.dwNumberOfProcessors;
 #else  // defined(CTL_HW) && defined(HW_NCPU)
     // TODO: grovel through /proc or check cpuid on x86 and similar
     // instructions on other architectures.
+#   if defined(_MSC_VER) && ! defined(__clang__)
+        _LIBCPP_WARNING("hardware_concurrency not yet implemented")
+#   else
+#       warning hardware_concurrency not yet implemented
+#   endif
     return 0;  // Means not computable [thread.thread.static]
 #endif  // defined(CTL_HW) && defined(HW_NCPU)
 }
diff --git a/src/typeinfo.cpp b/src/typeinfo.cpp
index 6082894..b428120 100644
--- a/src/typeinfo.cpp
+++ b/src/typeinfo.cpp
@@ -20,12 +20,18 @@
 
 #include "typeinfo"
 
-#if !(defined(_LIBCPPABI_VERSION) || defined(LIBCXXRT))
+#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
 
 std::bad_cast::bad_cast() _NOEXCEPT
 {
 }
 
+std::bad_typeid::bad_typeid() _NOEXCEPT
+{
+}
+
+#ifndef __GLIBCXX__
+
 std::bad_cast::~bad_cast() _NOEXCEPT
 {
 }
@@ -36,10 +42,6 @@
   return "std::bad_cast";
 }
 
-std::bad_typeid::bad_typeid() _NOEXCEPT
-{
-}
-
 std::bad_typeid::~bad_typeid() _NOEXCEPT
 {
 }
@@ -67,4 +69,5 @@
   }
 #endif
 
-#endif  // _LIBCPPABI_VERSION
+#endif  // !__GLIBCXX__
+#endif  // !LIBCXXRT && !_LIBCPPABI_VERSION
diff --git a/src/valarray.cpp b/src/valarray.cpp
index 2d8db52..e4c9ed0 100644
--- a/src/valarray.cpp
+++ b/src/valarray.cpp
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
+
 #include "valarray"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 496ba3d..4810b2c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,7 +8,12 @@
 
 include(FindPythonInterp)
 if(PYTHONINTERP_FOUND)
-  set(LIT_EXECUTABLE "" CACHE FILEPATH "Path to LLVM's lit.py.")
+  if(LIBCXX_BUILT_STANDALONE)
+    set(LIT_EXECUTABLE "" CACHE FILEPATH "Path to LLVM's lit.py.")
+  else()
+    set(LIT_EXECUTABLE "${CMAKE_SOURCE_DIR}/utils/lit/lit.py")
+  endif()
+
   set(LIT_ARGS_DEFAULT "-sv")
   if (MSVC OR XCODE)
     set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
@@ -19,7 +24,7 @@
   separate_arguments(LIT_ARGS)
 
   set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER})
-  set(LIBCXX_SOURCE_DIR ${CMAKE_SOURCE_DIR})
+  set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
   set(LIBCXX_BINARY_DIR ${CMAKE_BINARY_DIR})
   set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
   pythonize_bool(LIBCXX_ENABLE_SHARED)
@@ -37,7 +42,7 @@
             ${LIT_EXECUTABLE}
             ${LIT_ARGS}
             ${CMAKE_CURRENT_BINARY_DIR}
-    DEPENDS
+    DEPENDS cxx
     COMMENT "Running libcxx tests")
 else()
   message(WARNING "Could not find Python, no check target will be available!")
diff --git a/test/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp b/test/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
index b9be7c0..bffcf1b 100644
--- a/test/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
+++ b/test/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
@@ -45,6 +45,93 @@
     assert(ia[3] == 1);
 }
 
+void
+test_int_array()
+{
+    const unsigned n = 4;
+    int ia[n] = {0};
+    assert(std::fill_n(ia, n, static_cast<char>(1)) == std::next(ia, n));
+    assert(ia[0] == 1);
+    assert(ia[1] == 1);
+    assert(ia[2] == 1);
+    assert(ia[3] == 1);
+}
+
+struct source {
+    source() : i(0) { }
+    
+    operator int() const { return i++; }
+    mutable int i;
+};
+
+void
+test_int_array_struct_source()
+{
+    const unsigned n = 4;
+    int ia[n] = {0};
+    assert(std::fill_n(ia, n, source()) == std::next(ia, n));
+    assert(ia[0] == 0);
+    assert(ia[1] == 1);
+    assert(ia[2] == 2);
+    assert(ia[3] == 3);
+}
+
+struct test1 {
+    test1() : c(0) { }
+    test1(char c) : c(c + 1) { }
+    char c;
+};
+
+void
+test_struct_array()
+{
+    const unsigned n = 4;
+    test1 test1a[n] = {0};
+    assert(std::fill_n(test1a, n, static_cast<char>(10)) == std::next(test1a, n));    
+    assert(test1a[0].c == 11);
+    assert(test1a[1].c == 11);
+    assert(test1a[2].c == 11);
+    assert(test1a[3].c == 11);
+}
+
+class A
+{
+    char a_;
+public:
+    A() {}
+    explicit A(char a) : a_(a) {}
+    operator unsigned char() const {return 'b';}
+
+    friend bool operator==(const A& x, const A& y)
+        {return x.a_ == y.a_;}
+};
+
+void
+test5()
+{
+    A a[3];
+    assert(std::fill_n(&a[0], 3, A('a')) == a+3);
+    assert(a[0] == A('a'));
+    assert(a[1] == A('a'));
+    assert(a[2] == A('a'));
+}
+
+struct Storage
+{
+  union
+  {
+    unsigned char a;
+    unsigned char b;
+  };
+};
+ 
+void test6()
+{
+  Storage foo[5];
+  std::fill_n(&foo[0], 5, Storage());
+}
+
+
 int main()
 {
     test_char<forward_iterator<char*> >();
@@ -56,4 +143,11 @@
     test_int<bidirectional_iterator<int*> >();
     test_int<random_access_iterator<int*> >();
     test_int<int*>();
+    
+    test_int_array();
+    test_int_array_struct_source();
+    test_struct_array();
+
+    test5();
+    test6();
 }
diff --git a/test/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp b/test/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp
index 1b1a2ad..2348791 100644
--- a/test/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp
@@ -19,6 +19,10 @@
 
 #include "test_iterators.h"
 
+#if _LIBCPP_STD_VER > 11
+#define HAS_FOUR_ITERATOR_VERSION
+#endif
+
 int main()
 {
     int ia[] = {0, 1, 2, 3, 4, 5};
@@ -27,7 +31,36 @@
     assert(std::equal(input_iterator<const int*>(ia),
                       input_iterator<const int*>(ia+s),
                       input_iterator<const int*>(ia)));
+#ifdef HAS_FOUR_ITERATOR_VERSION
+    assert(std::equal(input_iterator<const int*>(ia),
+                      input_iterator<const int*>(ia+s),
+                      input_iterator<const int*>(ia),
+                      input_iterator<const int*>(ia+s)));
+    assert(std::equal(random_access_iterator<const int*>(ia),
+                      random_access_iterator<const int*>(ia+s),
+                      random_access_iterator<const int*>(ia),
+                      random_access_iterator<const int*>(ia+s)));
+#endif
     assert(!std::equal(input_iterator<const int*>(ia),
                        input_iterator<const int*>(ia+s),
                        input_iterator<const int*>(ib)));
+#ifdef HAS_FOUR_ITERATOR_VERSION
+    assert(!std::equal(input_iterator<const int*>(ia),
+                       input_iterator<const int*>(ia+s),
+                       input_iterator<const int*>(ib),
+                       input_iterator<const int*>(ib+s)));
+    assert(!std::equal(random_access_iterator<const int*>(ia),
+                       random_access_iterator<const int*>(ia+s),
+                       random_access_iterator<const int*>(ib),
+                       random_access_iterator<const int*>(ib+s)));
+    assert(!std::equal(input_iterator<const int*>(ia),
+                       input_iterator<const int*>(ia+s),
+                       input_iterator<const int*>(ia),
+                       input_iterator<const int*>(ia+s-1)));
+    assert(!std::equal(random_access_iterator<const int*>(ia),
+                       random_access_iterator<const int*>(ia+s),
+                       random_access_iterator<const int*>(ia),
+                       random_access_iterator<const int*>(ia+s-1)));
+    
+#endif
 }
diff --git a/test/algorithms/alg.nonmodifying/alg.equal/equal_pred.pass.cpp b/test/algorithms/alg.nonmodifying/alg.equal/equal_pred.pass.cpp
index b21d38b..047f720 100644
--- a/test/algorithms/alg.nonmodifying/alg.equal/equal_pred.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/alg.equal/equal_pred.pass.cpp
@@ -21,6 +21,17 @@
 
 #include "test_iterators.h"
 
+#if _LIBCPP_STD_VER > 11
+#define HAS_FOUR_ITERATOR_VERSION
+#endif
+
+int comparison_count = 0;
+template <typename T>
+bool counting_equals ( const T &a, const T &b ) {
+    ++comparison_count;
+    return a == b;
+}
+
 int main()
 {
     int ia[] = {0, 1, 2, 3, 4, 5};
@@ -30,8 +41,47 @@
                       input_iterator<const int*>(ia+s),
                       input_iterator<const int*>(ia),
                       std::equal_to<int>()));
+#ifdef HAS_FOUR_ITERATOR_VERSION
+    assert(std::equal(input_iterator<const int*>(ia),
+                      input_iterator<const int*>(ia+s),
+                      input_iterator<const int*>(ia),
+                      input_iterator<const int*>(ia+s),
+                      std::equal_to<int>()));
+    assert(std::equal(random_access_iterator<const int*>(ia),
+                      random_access_iterator<const int*>(ia+s),
+                      random_access_iterator<const int*>(ia),
+                      random_access_iterator<const int*>(ia+s),
+                      std::equal_to<int>()));
+
+    comparison_count = 0;
+    assert(!std::equal(input_iterator<const int*>(ia),
+                      input_iterator<const int*>(ia+s),
+                      input_iterator<const int*>(ia),
+                      input_iterator<const int*>(ia+s-1),
+                      counting_equals<int>));
+    assert(comparison_count > 0);
+    comparison_count = 0;
+    assert(!std::equal(random_access_iterator<const int*>(ia),
+                      random_access_iterator<const int*>(ia+s),
+                      random_access_iterator<const int*>(ia),
+                      random_access_iterator<const int*>(ia+s-1),
+                      counting_equals<int>));
+    assert(comparison_count == 0);
+#endif
     assert(!std::equal(input_iterator<const int*>(ia),
                        input_iterator<const int*>(ia+s),
                        input_iterator<const int*>(ib),
                        std::equal_to<int>()));
+#ifdef HAS_FOUR_ITERATOR_VERSION
+    assert(!std::equal(input_iterator<const int*>(ia),
+                       input_iterator<const int*>(ia+s),
+                       input_iterator<const int*>(ib),
+                       input_iterator<const int*>(ib+s),
+                       std::equal_to<int>()));
+    assert(!std::equal(random_access_iterator<const int*>(ia),
+                       random_access_iterator<const int*>(ia+s),
+                       random_access_iterator<const int*>(ib),
+                       random_access_iterator<const int*>(ib+s),
+                       std::equal_to<int>()));
+#endif
 }
diff --git a/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation.pass.cpp b/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation.pass.cpp
index f68cced..028aec5 100644
--- a/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation.pass.cpp
@@ -19,6 +19,10 @@
 
 #include "test_iterators.h"
 
+#if _LIBCPP_STD_VER > 11
+#define HAS_FOUR_ITERATOR_VERSION
+#endif
+
 int main()
 {
     {
@@ -28,9 +32,25 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + 0),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + 0),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + 0)) == true);
+#endif
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0};
@@ -39,6 +59,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
 
     {
@@ -48,6 +74,16 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0};
@@ -56,6 +92,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0};
@@ -64,6 +106,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0};
@@ -72,6 +120,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -80,6 +134,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -88,6 +148,16 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -96,6 +166,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -104,6 +180,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -112,6 +194,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -120,6 +208,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -128,6 +222,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -136,6 +236,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -144,6 +250,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -152,6 +264,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -160,6 +278,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -168,6 +292,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+#endif
     }
 
     {
@@ -177,6 +307,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -185,6 +321,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -193,6 +335,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -201,6 +349,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -209,6 +363,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -217,6 +377,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -225,6 +391,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -233,6 +405,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -241,6 +419,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -249,6 +433,16 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -257,6 +451,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -265,6 +465,16 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -273,6 +483,16 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -281,6 +501,16 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -289,6 +519,16 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -297,6 +537,12 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -305,6 +551,20 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib + 1),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
@@ -313,6 +573,20 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib + 1 ),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1)) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
@@ -321,5 +595,11 @@
         assert(std::is_permutation(forward_iterator<const int*>(ia),
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib)) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa)) == false);
+#endif
     }
 }
diff --git a/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp b/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp
index 2a3174f..ceb897d 100644
--- a/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/alg.is_permutation/is_permutation_pred.pass.cpp
@@ -20,6 +20,18 @@
 
 #include "test_iterators.h"
 
+#if _LIBCPP_STD_VER > 11
+#define HAS_FOUR_ITERATOR_VERSION
+#endif
+
+int comparison_count = 0;
+template <typename T>
+bool counting_equals ( const T &a, const T &b ) {
+    ++comparison_count;
+    return a == b;
+    }
+
+
 int main()
 {
     {
@@ -34,6 +46,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0};
@@ -43,6 +67,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
 
     {
@@ -53,6 +84,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0};
@@ -62,6 +105,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0};
@@ -71,6 +121,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0};
@@ -80,6 +137,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -89,6 +153,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -98,6 +169,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -107,6 +190,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1};
@@ -116,6 +211,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -125,6 +227,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -134,6 +243,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -143,6 +264,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 0};
@@ -152,6 +285,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -161,6 +301,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -170,6 +317,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -179,6 +333,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {1, 1};
@@ -188,6 +349,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
 
     {
@@ -198,6 +371,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -207,6 +387,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -216,6 +403,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -225,6 +419,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -234,6 +435,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -243,6 +451,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -252,6 +467,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -261,6 +483,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 0};
@@ -270,6 +499,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -279,6 +515,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -288,6 +536,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -297,6 +552,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -306,6 +573,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -315,6 +594,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2};
@@ -324,6 +615,18 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -333,6 +636,13 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 0, 1};
@@ -342,6 +652,23 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib + 1),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
     {
         const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
@@ -351,6 +678,37 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == true);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == true);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib + 1),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   std::equal_to<const int>()) == false);
+        comparison_count = 0;
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa - 1),
+                                   counting_equals<const int>) == false);
+        assert ( comparison_count > 0 );
+        comparison_count = 0;
+        assert(std::is_permutation(random_access_iterator<const int*>(ia),
+                                   random_access_iterator<const int*>(ia + sa),
+                                   random_access_iterator<const int*>(ib),
+                                   random_access_iterator<const int*>(ib + sa - 1),
+                                   counting_equals<const int>) == false);
+        assert ( comparison_count == 0 );
+#endif
     }
     {
         const int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};
@@ -360,5 +718,12 @@
                                    forward_iterator<const int*>(ia + sa),
                                    forward_iterator<const int*>(ib),
                                    std::equal_to<const int>()) == false);
+#ifdef HAS_FOUR_ITERATOR_VERSION
+        assert(std::is_permutation(forward_iterator<const int*>(ia),
+                                   forward_iterator<const int*>(ia + sa),
+                                   forward_iterator<const int*>(ib),
+                                   forward_iterator<const int*>(ib + sa),
+                                   std::equal_to<const int>()) == false);
+#endif
     }
 }
diff --git a/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp b/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
index 9dfebac..fe67854 100644
--- a/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
@@ -19,6 +19,10 @@
 
 #include "test_iterators.h"
 
+#if _LIBCPP_STD_VER > 11
+#define HAS_FOUR_ITERATOR_VERSION
+#endif
+
 int main()
 {
     int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
@@ -31,4 +35,24 @@
                                     input_iterator<const int*> >(
                             input_iterator<const int*>(ia+3),
                             input_iterator<const int*>(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(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))));
+#endif
 }
diff --git a/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp b/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
index 0258479..202a1b7 100644
--- a/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
+++ b/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
@@ -21,6 +21,11 @@
 
 #include "test_iterators.h"
 
+#if _LIBCPP_STD_VER > 11
+#define HAS_FOUR_ITERATOR_VERSION
+#endif
+
+
 int main()
 {
     int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
@@ -34,6 +39,24 @@
                                     input_iterator<const int*> >(
                             input_iterator<const int*>(ia+3),
                             input_iterator<const int*>(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::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))));
+#endif
+
     assert(std::mismatch(ia, ia + sa, ib, std::equal_to<int>()) ==
            (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>()) ==
+           (std::pair<int*,int*>(ia+3,ib+3)));
+    assert(std::mismatch(ia, ia + sa, ib, ib + 2, std::equal_to<int>()) ==
+           (std::pair<int*,int*>(ia+2,ib+2)));
+#endif
 }
diff --git a/test/containers/associative/map/compare.pass.cpp b/test/containers/associative/map/compare.pass.cpp
new file mode 100644
index 0000000..aa4d599
--- /dev/null
+++ b/test/containers/associative/map/compare.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// template <class Key, class T, class Compare = less<Key>,
+//           class Allocator = allocator<pair<const Key, T>>>
+// class map
+
+// http://llvm.org/bugs/show_bug.cgi?id=16538
+// http://llvm.org/bugs/show_bug.cgi?id=16549
+
+#include <map>
+
+struct Key {
+  template <typename T> Key(const T&) {}
+  bool operator< (const Key&) const { return false; }
+};
+
+int
+main()
+{
+    std::map<Key, int>::iterator it = std::map<Key, int>().find(Key(0));
+    std::pair<std::map<Key, int>::iterator, bool> result =
+                        std::map<Key, int>().insert(std::make_pair(Key(0), 0));
+}
diff --git a/test/containers/associative/map/map.access/at.pass.cpp b/test/containers/associative/map/map.access/at.pass.cpp
index 09f70b0..6c001a3 100644
--- a/test/containers/associative/map/map.access/at.pass.cpp
+++ b/test/containers/associative/map/map.access/at.pass.cpp
@@ -17,6 +17,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -83,4 +85,70 @@
         assert(m.at(8) == 8.5);
         assert(m.size() == 7);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1.5),
+            V(2, 2.5),
+            V(3, 3.5),
+            V(4, 4.5),
+            V(5, 5.5),
+            V(7, 7.5),
+            V(8, 8.5),
+        };
+        std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 7);
+        assert(m.at(1) == 1.5);
+        m.at(1) = -1.5;
+        assert(m.at(1) == -1.5);
+        assert(m.at(2) == 2.5);
+        assert(m.at(3) == 3.5);
+        assert(m.at(4) == 4.5);
+        assert(m.at(5) == 5.5);
+        try
+        {
+            m.at(6);
+            assert(false);
+        }
+        catch (std::out_of_range&)
+        {
+        }
+        assert(m.at(7) == 7.5);
+        assert(m.at(8) == 8.5);
+        assert(m.size() == 7);
+    }
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1.5),
+            V(2, 2.5),
+            V(3, 3.5),
+            V(4, 4.5),
+            V(5, 5.5),
+            V(7, 7.5),
+            V(8, 8.5),
+        };
+        const std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 7);
+        assert(m.at(1) == 1.5);
+        assert(m.at(2) == 2.5);
+        assert(m.at(3) == 3.5);
+        assert(m.at(4) == 4.5);
+        assert(m.at(5) == 5.5);
+        try
+        {
+            m.at(6);
+            assert(false);
+        }
+        catch (std::out_of_range&)
+        {
+        }
+        assert(m.at(7) == 7.5);
+        assert(m.at(8) == 8.5);
+        assert(m.size() == 7);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.access/empty.pass.cpp b/test/containers/associative/map/map.access/empty.pass.cpp
index b654117..2e542ac 100644
--- a/test/containers/associative/map/map.access/empty.pass.cpp
+++ b/test/containers/associative/map/map.access/empty.pass.cpp
@@ -16,8 +16,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::map<int, double> M;
     M m;
     assert(m.empty());
@@ -25,4 +28,16 @@
     assert(!m.empty());
     m.clear();
     assert(m.empty());
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    M m;
+    assert(m.empty());
+    m.insert(M::value_type(1, 1.5));
+    assert(!m.empty());
+    m.clear();
+    assert(m.empty());
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.access/index_key.pass.cpp b/test/containers/associative/map/map.access/index_key.pass.cpp
index fb82bbe..5dfdf40 100644
--- a/test/containers/associative/map/map.access/index_key.pass.cpp
+++ b/test/containers/associative/map/map.access/index_key.pass.cpp
@@ -16,8 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -41,4 +45,61 @@
     m[6] = 6.5;
     assert(m[6] == 6.5);
     assert(m.size() == 8);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1.5),
+        V(2, 2.5),
+        V(3, 3.5),
+        V(4, 4.5),
+        V(5, 5.5),
+        V(7, 7.5),
+        V(8, 8.5),
+    };
+    std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    assert(m.size() == 7);
+    assert(m[1] == 1.5);
+    assert(m.size() == 7);
+    const int i = 1;
+    m[i] = -1.5;
+    assert(m[1] == -1.5);
+    assert(m.size() == 7);
+    assert(m[6] == 0);
+    assert(m.size() == 8);
+    m[6] = 6.5;
+    assert(m[6] == 6.5);
+    assert(m.size() == 8);
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1.5),
+        V(2, 2.5),
+        V(3, 3.5),
+        V(4, 4.5),
+        V(5, 5.5),
+        V(7, 7.5),
+        V(8, 8.5),
+    };
+    std::map<int, double, std::less<>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+
+    assert(m.size() == 7);
+    assert(m[1] == 1.5);
+    assert(m.size() == 7);
+    m[1] = -1.5;
+    assert(m[1] == -1.5);
+    assert(m.size() == 7);
+    assert(m[6] == 0);
+    assert(m.size() == 8);
+    m[6] = 6.5;
+    assert(m[6] == 6.5);
+    assert(m.size() == 8);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.access/index_rv_key.pass.cpp b/test/containers/associative/map/map.access/index_rv_key.pass.cpp
index 4efe88c..4c15f08 100644
--- a/test/containers/associative/map/map.access/index_rv_key.pass.cpp
+++ b/test/containers/associative/map/map.access/index_rv_key.pass.cpp
@@ -17,10 +17,12 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     typedef std::pair<MoveOnly, double> V;
     std::map<MoveOnly, double> m;
     assert(m.size() == 0);
@@ -34,5 +36,23 @@
     m[6] = 6.5;
     assert(m[6] == 6.5);
     assert(m.size() == 2);
+    }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<MoveOnly, double> V;
+    std::map<MoveOnly, double, std::less<MoveOnly>, min_allocator<V>> m;
+    assert(m.size() == 0);
+    assert(m[1] == 0.0);
+    assert(m.size() == 1);
+    m[1] = -1.5;
+    assert(m[1] == -1.5);
+    assert(m.size() == 1);
+    assert(m[6] == 0);
+    assert(m.size() == 2);
+    m[6] = 6.5;
+    assert(m[6] == 6.5);
+    assert(m.size() == 2);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.access/index_tuple.pass.cpp b/test/containers/associative/map/map.access/index_tuple.pass.cpp
new file mode 100644
index 0000000..9a00829
--- /dev/null
+++ b/test/containers/associative/map/map.access/index_tuple.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// mapped_type& operator[](const key_type& k);
+
+// http://llvm.org/bugs/show_bug.cgi?id=16542
+
+#include <map>
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+#include <tuple>
+
+#endif
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    using namespace std;
+    map<tuple<int,int>, size_t> m;
+    m[make_tuple(2,3)]=7;
+#endif
+}
diff --git a/test/containers/associative/map/map.access/iterator.pass.cpp b/test/containers/associative/map/map.access/iterator.pass.cpp
index d8b2e1a..64a6284 100644
--- a/test/containers/associative/map/map.access/iterator.pass.cpp
+++ b/test/containers/associative/map/map.access/iterator.pass.cpp
@@ -29,6 +29,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -117,4 +119,106 @@
             assert(i->second == 1);
         }
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+            V(4, 1),
+            V(4, 1.5),
+            V(4, 2),
+            V(5, 1),
+            V(5, 1.5),
+            V(5, 2),
+            V(6, 1),
+            V(6, 1.5),
+            V(6, 2),
+            V(7, 1),
+            V(7, 1.5),
+            V(7, 2),
+            V(8, 1),
+            V(8, 1.5),
+            V(8, 2)
+        };
+        std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        std::map<int, double, std::less<int>, min_allocator<V>>::iterator i;
+        i = m.begin();
+        std::map<int, double, std::less<int>, min_allocator<V>>::const_iterator k = i;
+        assert(i == k);
+        for (int j = 1; j <= m.size(); ++j, ++i)
+        {
+            assert(i->first == j);
+            assert(i->second == 1);
+            i->second = 2.5;
+            assert(i->second == 2.5);
+        }
+    }
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+            V(4, 1),
+            V(4, 1.5),
+            V(4, 2),
+            V(5, 1),
+            V(5, 1.5),
+            V(5, 2),
+            V(6, 1),
+            V(6, 1.5),
+            V(6, 2),
+            V(7, 1),
+            V(7, 1.5),
+            V(7, 2),
+            V(8, 1),
+            V(8, 1.5),
+            V(8, 2)
+        };
+        const std::map<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.cbegin(), m.cend()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        assert(std::distance(m.crbegin(), m.crend()) == m.size());
+        std::map<int, double, std::less<int>, min_allocator<V>>::const_iterator i;
+        i = m.begin();
+        for (int j = 1; j <= m.size(); ++j, ++i)
+        {
+            assert(i->first == j);
+            assert(i->second == 1);
+        }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::map<int, double> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.access/max_size.pass.cpp b/test/containers/associative/map/map.access/max_size.pass.cpp
index e63587d..6f86d0e 100644
--- a/test/containers/associative/map/map.access/max_size.pass.cpp
+++ b/test/containers/associative/map/map.access/max_size.pass.cpp
@@ -16,9 +16,20 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::map<int, double> M;
     M m;
     assert(m.max_size() != 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    M m;
+    assert(m.max_size() != 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.access/size.pass.cpp b/test/containers/associative/map/map.access/size.pass.cpp
index ab4d7c6..ab4b05b 100644
--- a/test/containers/associative/map/map.access/size.pass.cpp
+++ b/test/containers/associative/map/map.access/size.pass.cpp
@@ -16,8 +16,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::map<int, double> M;
     M m;
     assert(m.size() == 0);
@@ -33,4 +36,24 @@
     assert(m.size() == 1);
     m.erase(m.begin());
     assert(m.size() == 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    M m;
+    assert(m.size() == 0);
+    m.insert(M::value_type(2, 1.5));
+    assert(m.size() == 1);
+    m.insert(M::value_type(1, 1.5));
+    assert(m.size() == 2);
+    m.insert(M::value_type(3, 1.5));
+    assert(m.size() == 3);
+    m.erase(m.begin());
+    assert(m.size() == 2);
+    m.erase(m.begin());
+    assert(m.size() == 1);
+    m.erase(m.begin());
+    assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/alloc.pass.cpp b/test/containers/associative/map/map.cons/alloc.pass.cpp
index 1a77f60..95d71da 100644
--- a/test/containers/associative/map/map.cons/alloc.pass.cpp
+++ b/test/containers/associative/map/map.cons/alloc.pass.cpp
@@ -17,13 +17,26 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::less<int> C;
     typedef test_allocator<std::pair<const int, double> > A;
     std::map<int, double, C, A> m(A(5));
     assert(m.empty());
     assert(m.begin() == m.end());
     assert(m.get_allocator() == A(5));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::less<int> C;
+    typedef min_allocator<std::pair<const int, double> > A;
+    std::map<int, double, C, A> m(A{});
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    assert(m.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/assign_initializer_list.pass.cpp b/test/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
index 2fdf5b2..a583f0d 100644
--- a/test/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::pair<const int, double> V;
     std::map<int, double> m =
                             {
@@ -41,5 +44,32 @@
     assert(*m.begin() == V(1, 1));
     assert(*next(m.begin()) == V(2, 1));
     assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    std::map<int, double, std::less<int>, min_allocator<V>> m =
+                            {
+                                {20, 1},
+                            };
+    m =
+                            {
+                                {1, 1},
+                                {1, 1.5},
+                                {1, 2},
+                                {2, 1},
+                                {2, 1.5},
+                                {2, 2},
+                                {3, 1},
+                                {3, 1.5},
+                                {3, 2}
+                            };
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/map/map.cons/compare.pass.cpp b/test/containers/associative/map/map.cons/compare.pass.cpp
index 5648ff0..2c4bb1a 100644
--- a/test/containers/associative/map/map.cons/compare.pass.cpp
+++ b/test/containers/associative/map/map.cons/compare.pass.cpp
@@ -17,12 +17,24 @@
 #include <cassert>
 
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef test_compare<std::less<int> > C;
     std::map<int, double, C> m(C(3));
     assert(m.empty());
     assert(m.begin() == m.end());
     assert(m.key_comp() == C(3));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef test_compare<std::less<int> > C;
+    std::map<int, double, C, min_allocator<std::pair<const int, double>>> m(C(3));
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    assert(m.key_comp() == C(3));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/compare_alloc.pass.cpp b/test/containers/associative/map/map.cons/compare_alloc.pass.cpp
index 26efa0d..670acff 100644
--- a/test/containers/associative/map/map.cons/compare_alloc.pass.cpp
+++ b/test/containers/associative/map/map.cons/compare_alloc.pass.cpp
@@ -18,9 +18,11 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef test_compare<std::less<int> > C;
     typedef test_allocator<std::pair<const int, double> > A;
     std::map<int, double, C, A> m(C(4), A(5));
@@ -28,4 +30,16 @@
     assert(m.begin() == m.end());
     assert(m.key_comp() == C(4));
     assert(m.get_allocator() == A(5));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef test_compare<std::less<int> > C;
+    typedef min_allocator<std::pair<const int, double> > A;
+    std::map<int, double, C, A> m(C(4), A());
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    assert(m.key_comp() == C(4));
+    assert(m.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/copy.pass.cpp b/test/containers/associative/map/map.cons/copy.pass.cpp
index 01c0d89..ce20d69 100644
--- a/test/containers/associative/map/map.cons/copy.pass.cpp
+++ b/test/containers/associative/map/map.cons/copy.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -91,4 +92,40 @@
         assert(*next(mo.begin(), 2) == V(3, 1));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::map<int, double, C, A> m = mo;
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 3);
+        assert(distance(m.begin(), m.end()) == 3);
+        assert(*m.begin() == V(1, 1));
+        assert(*next(m.begin()) == V(2, 1));
+        assert(*next(m.begin(), 2) == V(3, 1));
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 3);
+        assert(distance(mo.begin(), mo.end()) == 3);
+        assert(*mo.begin() == V(1, 1));
+        assert(*next(mo.begin()) == V(2, 1));
+        assert(*next(mo.begin(), 2) == V(3, 1));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/copy_alloc.pass.cpp b/test/containers/associative/map/map.cons/copy_alloc.pass.cpp
index 27b1c97..8492404 100644
--- a/test/containers/associative/map/map.cons/copy_alloc.pass.cpp
+++ b/test/containers/associative/map/map.cons/copy_alloc.pass.cpp
@@ -18,9 +18,11 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -53,4 +55,41 @@
     assert(*mo.begin() == V(1, 1));
     assert(*next(mo.begin()) == V(2, 1));
     assert(*next(mo.begin(), 2) == V(3, 1));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef test_compare<std::less<int> > C;
+    typedef min_allocator<V> A;
+    std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+    std::map<int, double, C, A> m(mo, A());
+    assert(m.get_allocator() == A());
+    assert(m.key_comp() == C(5));
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+
+    assert(mo.get_allocator() == A());
+    assert(mo.key_comp() == C(5));
+    assert(mo.size() == 3);
+    assert(distance(mo.begin(), mo.end()) == 3);
+    assert(*mo.begin() == V(1, 1));
+    assert(*next(mo.begin()) == V(2, 1));
+    assert(*next(mo.begin(), 2) == V(3, 1));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/copy_assign.pass.cpp b/test/containers/associative/map/map.cons/copy_assign.pass.cpp
index 7422ec9..fefb35c 100644
--- a/test/containers/associative/map/map.cons/copy_assign.pass.cpp
+++ b/test/containers/associative/map/map.cons/copy_assign.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -91,4 +92,76 @@
         assert(*next(mo.begin()) == V(2, 1));
         assert(*next(mo.begin(), 2) == V(3, 1));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2)
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A());
+        m = mo;
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 3);
+        assert(distance(m.begin(), m.end()) == 3);
+        assert(*m.begin() == V(1, 1));
+        assert(*next(m.begin()) == V(2, 1));
+        assert(*next(m.begin(), 2) == V(3, 1));
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 3);
+        assert(distance(mo.begin(), mo.end()) == 3);
+        assert(*mo.begin() == V(1, 1));
+        assert(*next(mo.begin()) == V(2, 1));
+        assert(*next(mo.begin(), 2) == V(3, 1));
+    }
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2)
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A());
+        m = mo;
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 3);
+        assert(distance(m.begin(), m.end()) == 3);
+        assert(*m.begin() == V(1, 1));
+        assert(*next(m.begin()) == V(2, 1));
+        assert(*next(m.begin(), 2) == V(3, 1));
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 3);
+        assert(distance(mo.begin(), mo.end()) == 3);
+        assert(*mo.begin() == V(1, 1));
+        assert(*next(mo.begin()) == V(2, 1));
+        assert(*next(mo.begin(), 2) == V(3, 1));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/default.pass.cpp b/test/containers/associative/map/map.cons/default.pass.cpp
index 8b5397c..49fc223 100644
--- a/test/containers/associative/map/map.cons/default.pass.cpp
+++ b/test/containers/associative/map/map.cons/default.pass.cpp
@@ -16,9 +16,20 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     std::map<int, double> m;
     assert(m.empty());
     assert(m.begin() == m.end());
+    }
+#if __cplusplus >= 201103L
+    {
+    std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> m;
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/default_recursive.pass.cpp b/test/containers/associative/map/map.cons/default_recursive.pass.cpp
index 452746c..8b393d3 100644
--- a/test/containers/associative/map/map.cons/default_recursive.pass.cpp
+++ b/test/containers/associative/map/map.cons/default_recursive.pass.cpp
@@ -19,7 +19,7 @@
 
 struct X
 {
-    std::multimap<int, X> m;
+    std::map<int, X> m;
 };
 
 #endif
diff --git a/test/containers/associative/map/map.cons/initializer_list.pass.cpp b/test/containers/associative/map/map.cons/initializer_list.pass.cpp
index 4acf2dc..63820be 100644
--- a/test/containers/associative/map/map.cons/initializer_list.pass.cpp
+++ b/test/containers/associative/map/map.cons/initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::pair<const int, double> V;
     std::map<int, double> m =
                             {
@@ -37,5 +40,28 @@
     assert(*m.begin() == V(1, 1));
     assert(*next(m.begin()) == V(2, 1));
     assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    std::map<int, double, std::less<int>, min_allocator<V>> m =
+                            {
+                                {1, 1},
+                                {1, 1.5},
+                                {1, 2},
+                                {2, 1},
+                                {2, 1.5},
+                                {2, 2},
+                                {3, 1},
+                                {3, 1.5},
+                                {3, 2}
+                            };
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/map/map.cons/initializer_list_compare.pass.cpp b/test/containers/associative/map/map.cons/initializer_list_compare.pass.cpp
index 723a03f..0c3bd23 100644
--- a/test/containers/associative/map/map.cons/initializer_list_compare.pass.cpp
+++ b/test/containers/associative/map/map.cons/initializer_list_compare.pass.cpp
@@ -16,10 +16,12 @@
 #include <map>
 #include <cassert>
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::pair<const int, double> V;
     typedef test_compare<std::less<int> > C;
     std::map<int, double, C> m({
@@ -39,5 +41,29 @@
     assert(*next(m.begin()) == V(2, 1));
     assert(*next(m.begin(), 2) == V(3, 1));
     assert(m.key_comp() == C(3));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef test_compare<std::less<int> > C;
+    std::map<int, double, C, min_allocator<std::pair<const int, double>>> m({
+                                {1, 1},
+                                {1, 1.5},
+                                {1, 2},
+                                {2, 1},
+                                {2, 1.5},
+                                {2, 2},
+                                {3, 1},
+                                {3, 1.5},
+                                {3, 2}
+                               }, C(3));
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    assert(m.key_comp() == C(3));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp b/test/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp
index f6300de..d844624 100644
--- a/test/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp
+++ b/test/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp
@@ -17,10 +17,12 @@
 #include <cassert>
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::pair<const int, double> V;
     typedef test_compare<std::less<int> > C;
     typedef test_allocator<std::pair<const int, double> > A;
@@ -42,5 +44,57 @@
     assert(*next(m.begin(), 2) == V(3, 1));
     assert(m.key_comp() == C(3));
     assert(m.get_allocator() == A(6));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef test_compare<std::less<int> > C;
+    typedef min_allocator<std::pair<const int, double> > A;
+    std::map<int, double, C, A> m({
+                                   {1, 1},
+                                   {1, 1.5},
+                                   {1, 2},
+                                   {2, 1},
+                                   {2, 1.5},
+                                   {2, 2},
+                                   {3, 1},
+                                   {3, 1.5},
+                                   {3, 2}
+                                  }, C(3), A());
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    assert(m.key_comp() == C(3));
+    assert(m.get_allocator() == A());
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef min_allocator<V> A;
+    typedef test_compare<std::less<int> > C;
+    typedef std::map<int, double, C, A> M;
+    A a;
+    M m ({ {1, 1},
+           {1, 1.5},
+           {1, 2},
+           {2, 1},
+           {2, 1.5},
+           {2, 2},
+           {3, 1},
+           {3, 1.5},
+           {3, 2}
+          }, a);
+
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    assert(m.get_allocator() == a);
+    }
+#endif
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/map/map.cons/iter_iter.pass.cpp b/test/containers/associative/map/map.cons/iter_iter.pass.cpp
index 00d3d8a..d981ccf 100644
--- a/test/containers/associative/map/map.cons/iter_iter.pass.cpp
+++ b/test/containers/associative/map/map.cons/iter_iter.pass.cpp
@@ -17,8 +17,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -38,4 +41,28 @@
     assert(*m.begin() == V(1, 1));
     assert(*next(m.begin()) == V(2, 1));
     assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/iter_iter_comp.pass.cpp b/test/containers/associative/map/map.cons/iter_iter_comp.pass.cpp
index 6f85193..0481de2 100644
--- a/test/containers/associative/map/map.cons/iter_iter_comp.pass.cpp
+++ b/test/containers/associative/map/map.cons/iter_iter_comp.pass.cpp
@@ -18,9 +18,11 @@
 #include <cassert>
 
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -42,4 +44,30 @@
     assert(*m.begin() == V(1, 1));
     assert(*next(m.begin()) == V(2, 1));
     assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef test_compare<std::less<int> > C;
+    std::map<int, double, C, min_allocator<std::pair<const int, double>>> m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5));
+    assert(m.key_comp() == C(5));
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp b/test/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp
index abee6d9..2c76712 100644
--- a/test/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp
+++ b/test/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp
@@ -20,9 +20,11 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -46,4 +48,61 @@
     assert(*m.begin() == V(1, 1));
     assert(*next(m.begin()) == V(2, 1));
     assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef test_compare<std::less<int> > C;
+    typedef min_allocator<V> A;
+    std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+    assert(m.get_allocator() == A());
+    assert(m.key_comp() == C(5));
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef std::pair<const int, double> V;
+    typedef min_allocator<V> A;
+    typedef test_compare<std::less<int> > C;
+    A a;
+    std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), a );
+
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    assert(m.get_allocator() == a);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/associative/map/map.cons/move.pass.cpp b/test/containers/associative/map/map.cons/move.pass.cpp
index b86dd6e..323a265 100644
--- a/test/containers/associative/map/map.cons/move.pass.cpp
+++ b/test/containers/associative/map/map.cons/move.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -68,5 +69,52 @@
         assert(mo.size() == 0);
         assert(distance(mo.begin(), mo.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::map<int, double, C, A> mo(C(5), A());
+        std::map<int, double, C, A> m = std::move(mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 0);
+        assert(distance(m.begin(), m.end()) == 0);
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 0);
+        assert(distance(mo.begin(), mo.end()) == 0);
+    }
+    {
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::map<int, double, C, A> m = std::move(mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 3);
+        assert(distance(m.begin(), m.end()) == 3);
+        assert(*m.begin() == V(1, 1));
+        assert(*next(m.begin()) == V(2, 1));
+        assert(*next(m.begin(), 2) == V(3, 1));
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 0);
+        assert(distance(mo.begin(), mo.end()) == 0);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/map/map.cons/move_alloc.pass.cpp b/test/containers/associative/map/map.cons/move_alloc.pass.cpp
index c9675db..2bb2c06 100644
--- a/test/containers/associative/map/map.cons/move_alloc.pass.cpp
+++ b/test/containers/associative/map/map.cons/move_alloc.pass.cpp
@@ -19,6 +19,7 @@
 #include "../../../MoveOnly.h"
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -140,5 +141,46 @@
         assert(m3.key_comp() == C(5));
         assert(m1.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<MoveOnly, MoveOnly> V;
+        typedef std::pair<const MoveOnly, MoveOnly> VC;
+        typedef test_compare<std::less<MoveOnly> > C;
+        typedef min_allocator<VC> A;
+        typedef std::map<MoveOnly, MoveOnly, C, A> M;
+        typedef std::move_iterator<V*> I;
+        V a1[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A());
+        V a2[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A());
+        M m3(std::move(m1), A());
+        assert(m3 == m2);
+        assert(m3.get_allocator() == A());
+        assert(m3.key_comp() == C(5));
+        assert(m1.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/map/map.cons/move_assign.pass.cpp b/test/containers/associative/map/map.cons/move_assign.pass.cpp
index e8b9a88..2e6ede7 100644
--- a/test/containers/associative/map/map.cons/move_assign.pass.cpp
+++ b/test/containers/associative/map/map.cons/move_assign.pass.cpp
@@ -19,6 +19,7 @@
 #include "../../../MoveOnly.h"
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -143,5 +144,47 @@
         assert(m3.key_comp() == C(5));
         assert(m1.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<MoveOnly, MoveOnly> V;
+        typedef std::pair<const MoveOnly, MoveOnly> VC;
+        typedef test_compare<std::less<MoveOnly> > C;
+        typedef min_allocator<VC> A;
+        typedef std::map<MoveOnly, MoveOnly, C, A> M;
+        typedef std::move_iterator<V*> I;
+        V a1[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A());
+        V a2[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A());
+        M m3(C(3), A());
+        m3 = std::move(m1);
+        assert(m3 == m2);
+        assert(m3.get_allocator() == A());
+        assert(m3.key_comp() == C(5));
+        assert(m1.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/map/map.modifiers/clear.pass.cpp b/test/containers/associative/map/map.modifiers/clear.pass.cpp
index a181e63..77f50ba 100644
--- a/test/containers/associative/map/map.modifiers/clear.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/clear.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -37,4 +39,25 @@
         m.clear();
         assert(m.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        P ar[] =
+        {
+            P(1, 1.5),
+            P(2, 2.5),
+            P(3, 3.5),
+            P(4, 4.5),
+            P(5, 5.5),
+            P(6, 6.5),
+            P(7, 7.5),
+            P(8, 8.5),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        m.clear();
+        assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.modifiers/emplace.pass.cpp b/test/containers/associative/map/map.modifiers/emplace.pass.cpp
index 4eb7e9f..9a87bec 100644
--- a/test/containers/associative/map/map.modifiers/emplace.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/emplace.pass.cpp
@@ -20,6 +20,7 @@
 
 #include "../../../Emplaceable.h"
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -36,14 +37,16 @@
         assert(m.begin()->first == 0);
         assert(m.begin()->second == DefaultOnly());
         assert(DefaultOnly::count == 1);
-        r = m.emplace(1);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
         assert(r.second);
         assert(r.first == next(m.begin()));
         assert(m.size() == 2);
         assert(next(m.begin())->first == 1);
         assert(next(m.begin())->second == DefaultOnly());
         assert(DefaultOnly::count == 2);
-        r = m.emplace(1);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
         assert(!r.second);
         assert(r.first == next(m.begin()));
         assert(m.size() == 2);
@@ -56,7 +59,8 @@
         typedef std::map<int, Emplaceable> M;
         typedef std::pair<M::iterator, bool> R;
         M m;
-        R r = m.emplace(2);
+        R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
+                                                  std::forward_as_tuple());
         assert(r.second);
         assert(r.first == m.begin());
         assert(m.size() == 1);
@@ -88,5 +92,74 @@
         assert(m.begin()->first == 2);
         assert(m.begin()->second == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        assert(DefaultOnly::count == 0);
+        R r = m.emplace();
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 0);
+        assert(m.begin()->second == DefaultOnly());
+        assert(DefaultOnly::count == 1);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
+        assert(r.second);
+        assert(r.first == next(m.begin()));
+        assert(m.size() == 2);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == DefaultOnly());
+        assert(DefaultOnly::count == 2);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
+        assert(!r.second);
+        assert(r.first == next(m.begin()));
+        assert(m.size() == 2);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == DefaultOnly());
+        assert(DefaultOnly::count == 2);
+    }
+    assert(DefaultOnly::count == 0);
+    {
+        typedef std::map<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
+                                                  std::forward_as_tuple());
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == Emplaceable());
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple(2, 3.5));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 2);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == Emplaceable(2, 3.5));
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple(2, 3.5));
+        assert(!r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 2);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == Emplaceable(2, 3.5));
+    }
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        R r = m.emplace(M::value_type(2, 3.5));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 3.5);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/map/map.modifiers/emplace_hint.pass.cpp b/test/containers/associative/map/map.modifiers/emplace_hint.pass.cpp
index 2bc225e..bf8173f 100644
--- a/test/containers/associative/map/map.modifiers/emplace_hint.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/emplace_hint.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../../Emplaceable.h"
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -34,13 +35,17 @@
         assert(m.begin()->first == 0);
         assert(m.begin()->second == DefaultOnly());
         assert(DefaultOnly::count == 1);
-        r = m.emplace_hint(m.end(), 1);
+        r = m.emplace_hint(m.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
         assert(r == next(m.begin()));
         assert(m.size() == 2);
         assert(next(m.begin())->first == 1);
         assert(next(m.begin())->second == DefaultOnly());
         assert(DefaultOnly::count == 2);
-        r = m.emplace_hint(m.end(), 1);
+        r = m.emplace_hint(m.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
         assert(r == next(m.begin()));
         assert(m.size() == 2);
         assert(next(m.begin())->first == 1);
@@ -52,7 +57,9 @@
         typedef std::map<int, Emplaceable> M;
         typedef M::iterator R;
         M m;
-        R r = m.emplace_hint(m.end(), 2);
+        R r = m.emplace_hint(m.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(2),
+                                       std::forward_as_tuple());
         assert(r == m.begin());
         assert(m.size() == 1);
         assert(m.begin()->first == 2);
@@ -82,5 +89,72 @@
         assert(m.begin()->first == 2);
         assert(m.begin()->second == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
+        typedef M::iterator R;
+        M m;
+        assert(DefaultOnly::count == 0);
+        R r = m.emplace_hint(m.end());
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 0);
+        assert(m.begin()->second == DefaultOnly());
+        assert(DefaultOnly::count == 1);
+        r = m.emplace_hint(m.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
+        assert(r == next(m.begin()));
+        assert(m.size() == 2);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == DefaultOnly());
+        assert(DefaultOnly::count == 2);
+        r = m.emplace_hint(m.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
+        assert(r == next(m.begin()));
+        assert(m.size() == 2);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == DefaultOnly());
+        assert(DefaultOnly::count == 2);
+    }
+    assert(DefaultOnly::count == 0);
+    {
+        typedef std::map<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace_hint(m.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(2),
+                                       std::forward_as_tuple());
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == Emplaceable());
+        r = m.emplace_hint(m.end(), std::piecewise_construct, 
+                                    std::forward_as_tuple(1),
+                                    std::forward_as_tuple(2, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == Emplaceable(2, 3.5));
+        r = m.emplace_hint(m.end(), std::piecewise_construct,
+                                    std::forward_as_tuple(1),
+                                    std::forward_as_tuple(2, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == Emplaceable(2, 3.5));
+    }
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace_hint(m.end(), M::value_type(2, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 3.5);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/map/map.modifiers/erase_iter.pass.cpp b/test/containers/associative/map/map.modifiers/erase_iter.pass.cpp
index caf1647..086096b 100644
--- a/test/containers/associative/map/map.modifiers/erase_iter.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/erase_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -124,4 +126,112 @@
         assert(i == m.begin());
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        typedef M::iterator I;
+        P ar[] =
+        {
+            P(1, 1.5),
+            P(2, 2.5),
+            P(3, 3.5),
+            P(4, 4.5),
+            P(5, 5.5),
+            P(6, 6.5),
+            P(7, 7.5),
+            P(8, 8.5),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(next(m.cbegin(), 3));
+        assert(m.size() == 7);
+        assert(i == next(m.begin(), 3));
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1.5);
+        assert(next(m.begin())->first == 2);
+        assert(next(m.begin())->second == 2.5);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 3.5);
+        assert(next(m.begin(), 3)->first == 5);
+        assert(next(m.begin(), 3)->second == 5.5);
+        assert(next(m.begin(), 4)->first == 6);
+        assert(next(m.begin(), 4)->second == 6.5);
+        assert(next(m.begin(), 5)->first == 7);
+        assert(next(m.begin(), 5)->second == 7.5);
+        assert(next(m.begin(), 6)->first == 8);
+        assert(next(m.begin(), 6)->second == 8.5);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 6);
+        assert(i == m.begin());
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 3);
+        assert(next(m.begin())->second == 3.5);
+        assert(next(m.begin(), 2)->first == 5);
+        assert(next(m.begin(), 2)->second == 5.5);
+        assert(next(m.begin(), 3)->first == 6);
+        assert(next(m.begin(), 3)->second == 6.5);
+        assert(next(m.begin(), 4)->first == 7);
+        assert(next(m.begin(), 4)->second == 7.5);
+        assert(next(m.begin(), 5)->first == 8);
+        assert(next(m.begin(), 5)->second == 8.5);
+
+        i = m.erase(next(m.cbegin(), 5));
+        assert(m.size() == 5);
+        assert(i == m.end());
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 3);
+        assert(next(m.begin())->second == 3.5);
+        assert(next(m.begin(), 2)->first == 5);
+        assert(next(m.begin(), 2)->second == 5.5);
+        assert(next(m.begin(), 3)->first == 6);
+        assert(next(m.begin(), 3)->second == 6.5);
+        assert(next(m.begin(), 4)->first == 7);
+        assert(next(m.begin(), 4)->second == 7.5);
+
+        i = m.erase(next(m.cbegin(), 1));
+        assert(m.size() == 4);
+        assert(i == next(m.begin()));
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 5);
+        assert(next(m.begin())->second == 5.5);
+        assert(next(m.begin(), 2)->first == 6);
+        assert(next(m.begin(), 2)->second == 6.5);
+        assert(next(m.begin(), 3)->first == 7);
+        assert(next(m.begin(), 3)->second == 7.5);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 3);
+        assert(i == next(m.begin(), 2));
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 5);
+        assert(next(m.begin())->second == 5.5);
+        assert(next(m.begin(), 2)->first == 7);
+        assert(next(m.begin(), 2)->second == 7.5);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 2));
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 5);
+        assert(next(m.begin())->second == 5.5);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 1);
+        assert(i == next(m.begin(), 0));
+        assert(m.begin()->first == 5);
+        assert(m.begin()->second == 5.5);
+
+        i = m.erase(m.cbegin());
+        assert(m.size() == 0);
+        assert(i == m.begin());
+        assert(i == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp b/test/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp
index b595d8a..6589ace 100644
--- a/test/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -84,4 +86,72 @@
         assert(i == m.begin());
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        typedef M::iterator I;
+        P ar[] =
+        {
+            P(1, 1.5),
+            P(2, 2.5),
+            P(3, 3.5),
+            P(4, 4.5),
+            P(5, 5.5),
+            P(6, 6.5),
+            P(7, 7.5),
+            P(8, 8.5),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(m.cbegin(), m.cbegin());
+        assert(m.size() == 8);
+        assert(i == m.begin());
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1.5);
+        assert(next(m.begin())->first == 2);
+        assert(next(m.begin())->second == 2.5);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 3.5);
+        assert(next(m.begin(), 3)->first == 4);
+        assert(next(m.begin(), 3)->second == 4.5);
+        assert(next(m.begin(), 4)->first == 5);
+        assert(next(m.begin(), 4)->second == 5.5);
+        assert(next(m.begin(), 5)->first == 6);
+        assert(next(m.begin(), 5)->second == 6.5);
+        assert(next(m.begin(), 6)->first == 7);
+        assert(next(m.begin(), 6)->second == 7.5);
+        assert(next(m.begin(), 7)->first == 8);
+        assert(next(m.begin(), 7)->second == 8.5);
+
+        i = m.erase(m.cbegin(), next(m.cbegin(), 2));
+        assert(m.size() == 6);
+        assert(i == m.begin());
+        assert(next(m.begin(), 0)->first == 3);
+        assert(next(m.begin(), 0)->second == 3.5);
+        assert(next(m.begin(), 1)->first == 4);
+        assert(next(m.begin(), 1)->second == 4.5);
+        assert(next(m.begin(), 2)->first == 5);
+        assert(next(m.begin(), 2)->second == 5.5);
+        assert(next(m.begin(), 3)->first == 6);
+        assert(next(m.begin(), 3)->second == 6.5);
+        assert(next(m.begin(), 4)->first == 7);
+        assert(next(m.begin(), 4)->second == 7.5);
+        assert(next(m.begin(), 5)->first == 8);
+        assert(next(m.begin(), 5)->second == 8.5);
+
+        i = m.erase(next(m.cbegin(), 2), next(m.cbegin(), 6));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 2));
+        assert(next(m.begin(), 0)->first == 3);
+        assert(next(m.begin(), 0)->second == 3.5);
+        assert(next(m.begin(), 1)->first == 4);
+        assert(next(m.begin(), 1)->second == 4.5);
+
+        i = m.erase(m.cbegin(), m.cend());
+        assert(m.size() == 0);
+        assert(i == m.begin());
+        assert(i == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.modifiers/erase_key.pass.cpp b/test/containers/associative/map/map.modifiers/erase_key.pass.cpp
index e78a00f..4a93173 100644
--- a/test/containers/associative/map/map.modifiers/erase_key.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/erase_key.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -143,4 +145,131 @@
         assert(m.size() == 0);
         assert(s == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        typedef M::size_type R;
+        P ar[] =
+        {
+            P(1, 1.5),
+            P(2, 2.5),
+            P(3, 3.5),
+            P(4, 4.5),
+            P(5, 5.5),
+            P(6, 6.5),
+            P(7, 7.5),
+            P(8, 8.5),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        R s = m.erase(9);
+        assert(s == 0);
+        assert(m.size() == 8);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1.5);
+        assert(next(m.begin())->first == 2);
+        assert(next(m.begin())->second == 2.5);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 3.5);
+        assert(next(m.begin(), 3)->first == 4);
+        assert(next(m.begin(), 3)->second == 4.5);
+        assert(next(m.begin(), 4)->first == 5);
+        assert(next(m.begin(), 4)->second == 5.5);
+        assert(next(m.begin(), 5)->first == 6);
+        assert(next(m.begin(), 5)->second == 6.5);
+        assert(next(m.begin(), 6)->first == 7);
+        assert(next(m.begin(), 6)->second == 7.5);
+        assert(next(m.begin(), 7)->first == 8);
+        assert(next(m.begin(), 7)->second == 8.5);
+
+        s = m.erase(4);
+        assert(m.size() == 7);
+        assert(s == 1);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1.5);
+        assert(next(m.begin())->first == 2);
+        assert(next(m.begin())->second == 2.5);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 3.5);
+        assert(next(m.begin(), 3)->first == 5);
+        assert(next(m.begin(), 3)->second == 5.5);
+        assert(next(m.begin(), 4)->first == 6);
+        assert(next(m.begin(), 4)->second == 6.5);
+        assert(next(m.begin(), 5)->first == 7);
+        assert(next(m.begin(), 5)->second == 7.5);
+        assert(next(m.begin(), 6)->first == 8);
+        assert(next(m.begin(), 6)->second == 8.5);
+
+        s = m.erase(1);
+        assert(m.size() == 6);
+        assert(s == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 3);
+        assert(next(m.begin())->second == 3.5);
+        assert(next(m.begin(), 2)->first == 5);
+        assert(next(m.begin(), 2)->second == 5.5);
+        assert(next(m.begin(), 3)->first == 6);
+        assert(next(m.begin(), 3)->second == 6.5);
+        assert(next(m.begin(), 4)->first == 7);
+        assert(next(m.begin(), 4)->second == 7.5);
+        assert(next(m.begin(), 5)->first == 8);
+        assert(next(m.begin(), 5)->second == 8.5);
+
+        s = m.erase(8);
+        assert(m.size() == 5);
+        assert(s == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 3);
+        assert(next(m.begin())->second == 3.5);
+        assert(next(m.begin(), 2)->first == 5);
+        assert(next(m.begin(), 2)->second == 5.5);
+        assert(next(m.begin(), 3)->first == 6);
+        assert(next(m.begin(), 3)->second == 6.5);
+        assert(next(m.begin(), 4)->first == 7);
+        assert(next(m.begin(), 4)->second == 7.5);
+
+        s = m.erase(3);
+        assert(m.size() == 4);
+        assert(s == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 5);
+        assert(next(m.begin())->second == 5.5);
+        assert(next(m.begin(), 2)->first == 6);
+        assert(next(m.begin(), 2)->second == 6.5);
+        assert(next(m.begin(), 3)->first == 7);
+        assert(next(m.begin(), 3)->second == 7.5);
+
+        s = m.erase(6);
+        assert(m.size() == 3);
+        assert(s == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 5);
+        assert(next(m.begin())->second == 5.5);
+        assert(next(m.begin(), 2)->first == 7);
+        assert(next(m.begin(), 2)->second == 7.5);
+
+        s = m.erase(7);
+        assert(m.size() == 2);
+        assert(s == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 2.5);
+        assert(next(m.begin())->first == 5);
+        assert(next(m.begin())->second == 5.5);
+
+        s = m.erase(2);
+        assert(m.size() == 1);
+        assert(s == 1);
+        assert(m.begin()->first == 5);
+        assert(m.begin()->second == 5.5);
+
+        s = m.erase(5);
+        assert(m.size() == 0);
+        assert(s == 1);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.modifiers/insert_cv.pass.cpp b/test/containers/associative/map/map.modifiers/insert_cv.pass.cpp
index f405c4c..24d3f84 100644
--- a/test/containers/associative/map/map.modifiers/insert_cv.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/insert_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -50,4 +52,38 @@
         assert(r.first->first == 3);
         assert(r.first->second == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        R r = m.insert(M::value_type(2, 2.5));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(r.first->first == 2);
+        assert(r.first->second == 2.5);
+
+        r = m.insert(M::value_type(1, 1.5));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 2);
+        assert(r.first->first == 1);
+        assert(r.first->second == 1.5);
+
+        r = m.insert(M::value_type(3, 3.5));
+        assert(r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r.first->first == 3);
+        assert(r.first->second == 3.5);
+
+        r = m.insert(M::value_type(3, 3.5));
+        assert(!r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r.first->first == 3);
+        assert(r.first->second == 3.5);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp b/test/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp
index 66714d5..bc7e760 100644
--- a/test/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::pair<const int, double> V;
     std::map<int, double> m =
                             {
@@ -39,5 +42,30 @@
     assert(*m.begin() == V(1, 1));
     assert(*next(m.begin()) == V(2, 1));
     assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    std::map<int, double, std::less<int>, min_allocator<V>> m =
+                            {
+                                {1, 1},
+                                {1, 1.5},
+                                {1, 2},
+                                {3, 1},
+                                {3, 1.5},
+                                {3, 2}
+                            };
+    m.insert({
+                 {2, 1},
+                 {2, 1.5},
+                 {2, 2},
+             });
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(2, 1));
+    assert(*next(m.begin(), 2) == V(3, 1));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp b/test/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp
index 105b456..43ca35a 100644
--- a/test/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -46,4 +48,34 @@
         assert(r->first == 3);
         assert(r->second == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.end(), M::value_type(2, 2.5));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(r->first == 2);
+        assert(r->second == 2.5);
+
+        r = m.insert(m.end(), M::value_type(1, 1.5));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(r->first == 1);
+        assert(r->second == 1.5);
+
+        r = m.insert(m.end(), M::value_type(3, 3.5));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3.5);
+
+        r = m.insert(m.end(), M::value_type(3, 3.5));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3.5);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp b/test/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp
index 307e3e4..d1acdf2 100644
--- a/test/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,31 @@
         assert(next(m.begin(), 2)->first == 3);
         assert(next(m.begin(), 2)->second == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        P ar[] =
+        {
+            P(1, 1),
+            P(1, 1.5),
+            P(1, 2),
+            P(2, 1),
+            P(2, 1.5),
+            P(2, 2),
+            P(3, 1),
+            P(3, 1.5),
+            P(3, 2),
+        };
+        M m;
+        m.insert(input_iterator<P*>(ar), input_iterator<P*>(ar + sizeof(ar)/sizeof(ar[0])));
+        assert(m.size() == 3);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1);
+        assert(next(m.begin())->first == 2);
+        assert(next(m.begin())->second == 1);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 1);
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp b/test/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp
index 620c015..e84a82b 100644
--- a/test/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -51,5 +52,36 @@
         assert(r->first == 3);
         assert(r->second == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
+        typedef std::pair<int, MoveOnly> P;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.end(), P(2, 2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(r->first == 2);
+        assert(r->second == 2);
+
+        r = m.insert(m.end(), P(1, 1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(r->first == 1);
+        assert(r->second == 1);
+
+        r = m.insert(m.end(), P(3, 3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3);
+
+        r = m.insert(m.end(), P(3, 3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/map/map.modifiers/insert_rv.pass.cpp b/test/containers/associative/map/map.modifiers/insert_rv.pass.cpp
index b95202b..c5724c4 100644
--- a/test/containers/associative/map/map.modifiers/insert_rv.pass.cpp
+++ b/test/containers/associative/map/map.modifiers/insert_rv.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -54,5 +55,39 @@
         assert(r.first->first == 3);
         assert(r.first->second == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        R r = m.insert(M::value_type(2, 2));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(r.first->first == 2);
+        assert(r.first->second == 2);
+
+        r = m.insert(M::value_type(1, 1));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 2);
+        assert(r.first->first == 1);
+        assert(r.first->second == 1);
+
+        r = m.insert(M::value_type(3, 3));
+        assert(r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r.first->first == 3);
+        assert(r.first->second == 3);
+
+        r = m.insert(M::value_type(3, 3));
+        assert(!r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r.first->first == 3);
+        assert(r.first->second == 3);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/map/map.ops/count.pass.cpp b/test/containers/associative/map/map.ops/count.pass.cpp
index 427feff..70eadac 100644
--- a/test/containers/associative/map/map.ops/count.pass.cpp
+++ b/test/containers/associative/map/map.ops/count.pass.cpp
@@ -16,8 +16,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     typedef std::map<int, double> M;
     {
@@ -53,4 +56,44 @@
         r = m.count(4);
         assert(r == 0);
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<int>, min_allocator<V>> M;
+    {
+        typedef M::size_type R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.count(5);
+        assert(r == 1);
+        r = m.count(6);
+        assert(r == 1);
+        r = m.count(7);
+        assert(r == 1);
+        r = m.count(8);
+        assert(r == 1);
+        r = m.count(9);
+        assert(r == 1);
+        r = m.count(10);
+        assert(r == 1);
+        r = m.count(11);
+        assert(r == 1);
+        r = m.count(12);
+        assert(r == 1);
+        r = m.count(4);
+        assert(r == 0);
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.ops/equal_range.pass.cpp b/test/containers/associative/map/map.ops/equal_range.pass.cpp
index 057ef6a..b08acb0 100644
--- a/test/containers/associative/map/map.ops/equal_range.pass.cpp
+++ b/test/containers/associative/map/map.ops/equal_range.pass.cpp
@@ -17,8 +17,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     typedef std::map<int, double> M;
     {
@@ -153,4 +157,281 @@
         assert(r.first == next(m.begin(), 8));
         assert(r.second == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<int>, min_allocator<V>> M;
+    {
+        typedef std::pair<M::iterator, M::iterator> R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(7, 6),
+            V(9, 7),
+            V(11, 8),
+            V(13, 9),
+            V(15, 10),
+            V(17, 11),
+            V(19, 12)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.equal_range(5);
+        assert(r.first == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 1));
+        r = m.equal_range(7);
+        assert(r.first == next(m.begin(), 1));
+        assert(r.second == next(m.begin(), 2));
+        r = m.equal_range(9);
+        assert(r.first == next(m.begin(), 2));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(11);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 4));
+        r = m.equal_range(13);
+        assert(r.first == next(m.begin(), 4));
+        assert(r.second == next(m.begin(), 5));
+        r = m.equal_range(15);
+        assert(r.first == next(m.begin(), 5));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(17);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 7));
+        r = m.equal_range(19);
+        assert(r.first == next(m.begin(), 7));
+        assert(r.second == next(m.begin(), 8));
+        r = m.equal_range(4);
+        assert(r.first == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 0));
+        r = m.equal_range(6);
+        assert(r.first == next(m.begin(), 1));
+        assert(r.second == next(m.begin(), 1));
+        r = m.equal_range(8);
+        assert(r.first == next(m.begin(), 2));
+        assert(r.second == next(m.begin(), 2));
+        r = m.equal_range(10);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(12);
+        assert(r.first == next(m.begin(), 4));
+        assert(r.second == next(m.begin(), 4));
+        r = m.equal_range(14);
+        assert(r.first == next(m.begin(), 5));
+        assert(r.second == next(m.begin(), 5));
+        r = m.equal_range(16);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(18);
+        assert(r.first == next(m.begin(), 7));
+        assert(r.second == next(m.begin(), 7));
+        r = m.equal_range(20);
+        assert(r.first == next(m.begin(), 8));
+        assert(r.second == next(m.begin(), 8));
+    }
+    {
+        typedef std::pair<M::const_iterator, M::const_iterator> R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(7, 6),
+            V(9, 7),
+            V(11, 8),
+            V(13, 9),
+            V(15, 10),
+            V(17, 11),
+            V(19, 12)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.equal_range(5);
+        assert(r.first == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 1));
+        r = m.equal_range(7);
+        assert(r.first == next(m.begin(), 1));
+        assert(r.second == next(m.begin(), 2));
+        r = m.equal_range(9);
+        assert(r.first == next(m.begin(), 2));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(11);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 4));
+        r = m.equal_range(13);
+        assert(r.first == next(m.begin(), 4));
+        assert(r.second == next(m.begin(), 5));
+        r = m.equal_range(15);
+        assert(r.first == next(m.begin(), 5));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(17);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 7));
+        r = m.equal_range(19);
+        assert(r.first == next(m.begin(), 7));
+        assert(r.second == next(m.begin(), 8));
+        r = m.equal_range(4);
+        assert(r.first == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 0));
+        r = m.equal_range(6);
+        assert(r.first == next(m.begin(), 1));
+        assert(r.second == next(m.begin(), 1));
+        r = m.equal_range(8);
+        assert(r.first == next(m.begin(), 2));
+        assert(r.second == next(m.begin(), 2));
+        r = m.equal_range(10);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(12);
+        assert(r.first == next(m.begin(), 4));
+        assert(r.second == next(m.begin(), 4));
+        r = m.equal_range(14);
+        assert(r.first == next(m.begin(), 5));
+        assert(r.second == next(m.begin(), 5));
+        r = m.equal_range(16);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(18);
+        assert(r.first == next(m.begin(), 7));
+        assert(r.second == next(m.begin(), 7));
+        r = m.equal_range(20);
+        assert(r.first == next(m.begin(), 8));
+        assert(r.second == next(m.begin(), 8));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<>> M;
+    typedef std::pair<M::iterator, M::iterator> R;
+
+    V ar[] =
+    {
+        V(5, 5),
+        V(7, 6),
+        V(9, 7),
+        V(11, 8),
+        V(13, 9),
+        V(15, 10),
+        V(17, 11),
+        V(19, 12)
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.equal_range(5);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(7);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(9);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(11);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(13);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(15);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(17);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(19);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 8));
+    r = m.equal_range(4);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 0));
+    r = m.equal_range(6);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(8);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(10);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(12);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(14);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(16);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(18);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(20);
+    assert(r.first == next(m.begin(), 8));
+    assert(r.second == next(m.begin(), 8));
+    }
+    {
+    typedef PrivateConstructor PC;
+    typedef std::map<PC, double, std::less<>> M;
+    typedef std::pair<M::iterator, M::iterator> R;
+
+    M m;
+    m [ PC::make(5)  ] = 5;
+    m [ PC::make(7)  ] = 6;
+    m [ PC::make(9)  ] = 7;
+    m [ PC::make(11) ] = 8;
+    m [ PC::make(13) ] = 9;
+    m [ PC::make(15) ] = 10;
+    m [ PC::make(17) ] = 11;
+    m [ PC::make(19) ] = 12;
+
+    R r = m.equal_range(5);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(7);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(9);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(11);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(13);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(15);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(17);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(19);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 8));
+    r = m.equal_range(4);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 0));
+    r = m.equal_range(6);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(8);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(10);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(12);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(14);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(16);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(18);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(20);
+    assert(r.first == next(m.begin(), 8));
+    assert(r.second == next(m.begin(), 8));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.ops/find.pass.cpp b/test/containers/associative/map/map.ops/find.pass.cpp
index afebf12..4d1beab 100644
--- a/test/containers/associative/map/map.ops/find.pass.cpp
+++ b/test/containers/associative/map/map.ops/find.pass.cpp
@@ -17,8 +17,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     typedef std::map<int, double> M;
     {
@@ -87,4 +91,150 @@
         r = m.find(4);
         assert(r == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<int>, min_allocator<V>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.find(5);
+        assert(r == m.begin());
+        r = m.find(6);
+        assert(r == next(m.begin()));
+        r = m.find(7);
+        assert(r == next(m.begin(), 2));
+        r = m.find(8);
+        assert(r == next(m.begin(), 3));
+        r = m.find(9);
+        assert(r == next(m.begin(), 4));
+        r = m.find(10);
+        assert(r == next(m.begin(), 5));
+        r = m.find(11);
+        assert(r == next(m.begin(), 6));
+        r = m.find(12);
+        assert(r == next(m.begin(), 7));
+        r = m.find(4);
+        assert(r == next(m.begin(), 8));
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.find(5);
+        assert(r == m.begin());
+        r = m.find(6);
+        assert(r == next(m.begin()));
+        r = m.find(7);
+        assert(r == next(m.begin(), 2));
+        r = m.find(8);
+        assert(r == next(m.begin(), 3));
+        r = m.find(9);
+        assert(r == next(m.begin(), 4));
+        r = m.find(10);
+        assert(r == next(m.begin(), 5));
+        r = m.find(11);
+        assert(r == next(m.begin(), 6));
+        r = m.find(12);
+        assert(r == next(m.begin(), 7));
+        r = m.find(4);
+        assert(r == next(m.begin(), 8));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<>> M;
+    typedef M::iterator R;
+
+    V ar[] =
+    {
+        V(5, 5),
+        V(6, 6),
+        V(7, 7),
+        V(8, 8),
+        V(9, 9),
+        V(10, 10),
+        V(11, 11),
+        V(12, 12)
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.find(5);
+    assert(r == m.begin());
+    r = m.find(6);
+    assert(r == next(m.begin()));
+    r = m.find(7);
+    assert(r == next(m.begin(), 2));
+    r = m.find(8);
+    assert(r == next(m.begin(), 3));
+    r = m.find(9);
+    assert(r == next(m.begin(), 4));
+    r = m.find(10);
+    assert(r == next(m.begin(), 5));
+    r = m.find(11);
+    assert(r == next(m.begin(), 6));
+    r = m.find(12);
+    assert(r == next(m.begin(), 7));
+    r = m.find(4);
+    assert(r == next(m.begin(), 8));
+    }
+
+    {
+    typedef PrivateConstructor PC;
+    typedef std::map<PC, double, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m [ PC::make(5)  ] = 5;
+    m [ PC::make(6)  ] = 6;
+    m [ PC::make(7)  ] = 7;
+    m [ PC::make(8)  ] = 8;
+    m [ PC::make(9)  ] = 9;
+    m [ PC::make(10) ] = 10;
+    m [ PC::make(11) ] = 11;
+    m [ PC::make(12) ] = 12;
+
+    R r = m.find(5);
+    assert(r == m.begin());
+    r = m.find(6);
+    assert(r == next(m.begin()));
+    r = m.find(7);
+    assert(r == next(m.begin(), 2));
+    r = m.find(8);
+    assert(r == next(m.begin(), 3));
+    r = m.find(9);
+    assert(r == next(m.begin(), 4));
+    r = m.find(10);
+    assert(r == next(m.begin(), 5));
+    r = m.find(11);
+    assert(r == next(m.begin(), 6));
+    r = m.find(12);
+    assert(r == next(m.begin(), 7));
+    r = m.find(4);
+    assert(r == next(m.begin(), 8));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.ops/lower_bound.pass.cpp b/test/containers/associative/map/map.ops/lower_bound.pass.cpp
index f2f03cf..1ac1753 100644
--- a/test/containers/associative/map/map.ops/lower_bound.pass.cpp
+++ b/test/containers/associative/map/map.ops/lower_bound.pass.cpp
@@ -17,8 +17,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     typedef std::map<int, double> M;
     {
@@ -119,4 +123,214 @@
         r = m.lower_bound(20);
         assert(r == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<int>, min_allocator<V>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(7, 6),
+            V(9, 7),
+            V(11, 8),
+            V(13, 9),
+            V(15, 10),
+            V(17, 11),
+            V(19, 12)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.lower_bound(5);
+        assert(r == m.begin());
+        r = m.lower_bound(7);
+        assert(r == next(m.begin()));
+        r = m.lower_bound(9);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(11);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(13);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(15);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(17);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(19);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.lower_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.lower_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(7, 6),
+            V(9, 7),
+            V(11, 8),
+            V(13, 9),
+            V(15, 10),
+            V(17, 11),
+            V(19, 12)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.lower_bound(5);
+        assert(r == m.begin());
+        r = m.lower_bound(7);
+        assert(r == next(m.begin()));
+        r = m.lower_bound(9);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(11);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(13);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(15);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(17);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(19);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.lower_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.lower_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less <>> M;
+    typedef M::iterator R;
+
+    V ar[] =
+    {
+        V(5, 5),
+        V(7, 6),
+        V(9, 7),
+        V(11, 8),
+        V(13, 9),
+        V(15, 10),
+        V(17, 11),
+        V(19, 12)
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.lower_bound(5);
+    assert(r == m.begin());
+    r = m.lower_bound(7);
+    assert(r == next(m.begin()));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(11);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(13);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(15);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(17);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(19);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+    
+    {
+    typedef PrivateConstructor PC;
+    typedef std::map<PC, double, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m [ PC::make(5)  ] = 5;
+    m [ PC::make(7)  ] = 6;
+    m [ PC::make(9)  ] = 7;
+    m [ PC::make(11) ] = 8;
+    m [ PC::make(13) ] = 9;
+    m [ PC::make(15) ] = 10;
+    m [ PC::make(17) ] = 11;
+    m [ PC::make(19) ] = 12;
+
+    R r = m.lower_bound(5);
+    assert(r == m.begin());
+    r = m.lower_bound(7);
+    assert(r == next(m.begin()));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(11);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(13);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(15);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(17);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(19);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.ops/upper_bound.pass.cpp b/test/containers/associative/map/map.ops/upper_bound.pass.cpp
index 0d97e70..20973e3 100644
--- a/test/containers/associative/map/map.ops/upper_bound.pass.cpp
+++ b/test/containers/associative/map/map.ops/upper_bound.pass.cpp
@@ -17,8 +17,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     typedef std::map<int, double> M;
     {
@@ -119,4 +123,213 @@
         r = m.upper_bound(20);
         assert(r == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<int>, min_allocator<V>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(7, 6),
+            V(9, 7),
+            V(11, 8),
+            V(13, 9),
+            V(15, 10),
+            V(17, 11),
+            V(19, 12)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(5);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(11);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(13);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(15);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(17);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(19);
+        assert(r == next(m.begin(), 8));
+        r = m.upper_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            V(5, 5),
+            V(7, 6),
+            V(9, 7),
+            V(11, 8),
+            V(13, 9),
+            V(15, 10),
+            V(17, 11),
+            V(19, 12)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(5);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(11);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(13);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(15);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(17);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(19);
+        assert(r == next(m.begin(), 8));
+        r = m.upper_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<>> M;
+    typedef M::iterator R;
+    V ar[] =
+    {
+        V(5, 5),
+        V(7, 6),
+        V(9, 7),
+        V(11, 8),
+        V(13, 9),
+        V(15, 10),
+        V(17, 11),
+        V(19, 12)
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.upper_bound(5);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(11);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(13);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(15);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(17);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(19);
+    assert(r == next(m.begin(), 8));
+    r = m.upper_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+    
+    {
+    typedef PrivateConstructor PC;
+    typedef std::map<PC, double, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m [ PC::make(5)  ] = 5;
+    m [ PC::make(7)  ] = 6;
+    m [ PC::make(9)  ] = 7;
+    m [ PC::make(11) ] = 8;
+    m [ PC::make(13) ] = 9;
+    m [ PC::make(15) ] = 10;
+    m [ PC::make(17) ] = 11;
+    m [ PC::make(19) ] = 12;
+
+    R r = m.upper_bound(5);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(11);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(13);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(15);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(17);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(19);
+    assert(r == next(m.begin(), 8));
+    r = m.upper_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.special/member_swap.pass.cpp b/test/containers/associative/map/map.special/member_swap.pass.cpp
index 8451345..af59225 100644
--- a/test/containers/associative/map/map.special/member_swap.pass.cpp
+++ b/test/containers/associative/map/map.special/member_swap.pass.cpp
@@ -16,8 +16,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     typedef std::map<int, double> M;
     {
@@ -104,4 +107,95 @@
         assert(m1 == m2_save);
         assert(m2 == m1_save);
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<int>, min_allocator<V>> M;
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/map/map.special/non_member_swap.pass.cpp b/test/containers/associative/map/map.special/non_member_swap.pass.cpp
index ef67892..e474a46 100644
--- a/test/containers/associative/map/map.special/non_member_swap.pass.cpp
+++ b/test/containers/associative/map/map.special/non_member_swap.pass.cpp
@@ -19,9 +19,11 @@
 #include <cassert>
 #include "../../../test_allocator.h"
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     typedef std::map<int, double> M;
     {
@@ -176,4 +178,129 @@
         assert(m2.key_comp() == C(1));
         assert(m2.get_allocator() == A(1));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::map<int, double, std::less<int>, min_allocator<V>> M;
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        typedef min_allocator<V> A;
+        typedef test_compare<std::less<int> > C;
+        typedef std::map<int, double, C, A> M;
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]), C(1), A());
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]), C(2), A());
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+        assert(m1.key_comp() == C(2));
+        assert(m1.get_allocator() == A());
+        assert(m2.key_comp() == C(1));
+        assert(m2.get_allocator() == A());
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/map/types.pass.cpp b/test/containers/associative/map/types.pass.cpp
index 313b7bd..aca81df 100644
--- a/test/containers/associative/map/types.pass.cpp
+++ b/test/containers/associative/map/types.pass.cpp
@@ -32,8 +32,11 @@
 #include <map>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     static_assert((std::is_same<std::map<int, double>::key_type, int>::value), "");
     static_assert((std::is_same<std::map<int, double>::mapped_type, double>::value), "");
     static_assert((std::is_same<std::map<int, double>::value_type, std::pair<const int, double> >::value), "");
@@ -45,4 +48,20 @@
     static_assert((std::is_same<std::map<int, double>::const_pointer, const std::pair<const int, double>*>::value), "");
     static_assert((std::is_same<std::map<int, double>::size_type, std::size_t>::value), "");
     static_assert((std::is_same<std::map<int, double>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#if __cplusplus >= 201103L
+    {
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::key_type, int>::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::mapped_type, double>::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::value_type, std::pair<const int, double> >::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::key_compare, std::less<int> >::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::allocator_type, min_allocator<std::pair<const int, double> > >::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::reference, std::pair<const int, double>&>::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::const_reference, const std::pair<const int, double>&>::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::pointer, min_pointer<std::pair<const int, double>>>::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::const_pointer, min_pointer<const std::pair<const int, double>>>::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::size_type, std::size_t>::value), "");
+    static_assert((std::is_same<std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/empty.pass.cpp b/test/containers/associative/multimap/empty.pass.cpp
index c54920e..cafdb73 100644
--- a/test/containers/associative/multimap/empty.pass.cpp
+++ b/test/containers/associative/multimap/empty.pass.cpp
@@ -16,8 +16,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::multimap<int, double> M;
     M m;
     assert(m.empty());
@@ -25,4 +28,16 @@
     assert(!m.empty());
     m.clear();
     assert(m.empty());
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    M m;
+    assert(m.empty());
+    m.insert(M::value_type(1, 1.5));
+    assert(!m.empty());
+    m.clear();
+    assert(m.empty());
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/iterator.pass.cpp b/test/containers/associative/multimap/iterator.pass.cpp
index dfb2fdf..a58b583 100644
--- a/test/containers/associative/multimap/iterator.pass.cpp
+++ b/test/containers/associative/multimap/iterator.pass.cpp
@@ -29,6 +29,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -119,4 +121,108 @@
                 assert(i->second == d);
             }
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+            V(4, 1),
+            V(4, 1.5),
+            V(4, 2),
+            V(5, 1),
+            V(5, 1.5),
+            V(5, 2),
+            V(6, 1),
+            V(6, 1.5),
+            V(6, 2),
+            V(7, 1),
+            V(7, 1.5),
+            V(7, 2),
+            V(8, 1),
+            V(8, 1.5),
+            V(8, 2)
+        };
+        std::multimap<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        std::multimap<int, double, std::less<int>, min_allocator<V>>::iterator i;
+        i = m.begin();
+        std::multimap<int, double, std::less<int>, min_allocator<V>>::const_iterator k = i;
+        assert(i == k);
+        for (int j = 1; j <= 8; ++j)
+            for (double d = 1; d <= 2; d += .5, ++i)
+            {
+                assert(i->first == j);
+                assert(i->second == d);
+                i->second = 2.5;
+                assert(i->second == 2.5);
+            }
+    }
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+            V(4, 1),
+            V(4, 1.5),
+            V(4, 2),
+            V(5, 1),
+            V(5, 1.5),
+            V(5, 2),
+            V(6, 1),
+            V(6, 1.5),
+            V(6, 2),
+            V(7, 1),
+            V(7, 1.5),
+            V(7, 2),
+            V(8, 1),
+            V(8, 1.5),
+            V(8, 2)
+        };
+        const std::multimap<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.cbegin(), m.cend()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        assert(std::distance(m.crbegin(), m.crend()) == m.size());
+        std::multimap<int, double, std::less<int>, min_allocator<V>>::const_iterator i;
+        i = m.begin();
+        for (int j = 1; j <= 8; ++j)
+            for (double d = 1; d <= 2; d += .5, ++i)
+            {
+                assert(i->first == j);
+                assert(i->second == d);
+            }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::multimap<int, double> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/max_size.pass.cpp b/test/containers/associative/multimap/max_size.pass.cpp
index 2fcd569..7bcb12a 100644
--- a/test/containers/associative/multimap/max_size.pass.cpp
+++ b/test/containers/associative/multimap/max_size.pass.cpp
@@ -16,9 +16,20 @@
 #include <map>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::multimap<int, double> M;
     M m;
     assert(m.max_size() != 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    M m;
+    assert(m.max_size() != 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/alloc.pass.cpp b/test/containers/associative/multimap/multimap.cons/alloc.pass.cpp
index 3087c2e..aa3b6e2 100644
--- a/test/containers/associative/multimap/multimap.cons/alloc.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/alloc.pass.cpp
@@ -17,13 +17,26 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::less<int> C;
     typedef test_allocator<std::pair<const int, double> > A;
     std::multimap<int, double, C, A> m(A(5));
     assert(m.empty());
     assert(m.begin() == m.end());
     assert(m.get_allocator() == A(5));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::less<int> C;
+    typedef min_allocator<std::pair<const int, double> > A;
+    std::multimap<int, double, C, A> m(A{});
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    assert(m.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp b/test/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp
index 73e8f24..8c658d4 100644
--- a/test/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/assign_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::multimap<int, double> C;
     typedef C::value_type V;
     C m = {{20, 1}};
@@ -46,5 +49,37 @@
     assert(*++i == V(3, 1));
     assert(*++i == V(3, 1.5));
     assert(*++i == V(3, 2));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C;
+    typedef C::value_type V;
+    C m = {{20, 1}};
+    m =
+           {
+               {1, 1},
+               {1, 1.5},
+               {1, 2},
+               {2, 1},
+               {2, 1.5},
+               {2, 2},
+               {3, 1},
+               {3, 1.5},
+               {3, 2}
+           };
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1, 1));
+    assert(*++i == V(1, 1.5));
+    assert(*++i == V(1, 2));
+    assert(*++i == V(2, 1));
+    assert(*++i == V(2, 1.5));
+    assert(*++i == V(2, 2));
+    assert(*++i == V(3, 1));
+    assert(*++i == V(3, 1.5));
+    assert(*++i == V(3, 2));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/multimap/multimap.cons/compare.pass.cpp b/test/containers/associative/multimap/multimap.cons/compare.pass.cpp
index 594db42..99265ef 100644
--- a/test/containers/associative/multimap/multimap.cons/compare.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/compare.pass.cpp
@@ -17,12 +17,24 @@
 #include <cassert>
 
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef test_compare<std::less<int> > C;
     std::multimap<int, double, C> m(C(3));
     assert(m.empty());
     assert(m.begin() == m.end());
     assert(m.key_comp() == C(3));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef test_compare<std::less<int> > C;
+    std::multimap<int, double, C, min_allocator<std::pair<const int, double>>> m(C(3));
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    assert(m.key_comp() == C(3));
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp b/test/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp
index 9354683..864a542 100644
--- a/test/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/compare_alloc.pass.cpp
@@ -18,9 +18,11 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef test_compare<std::less<int> > C;
     typedef test_allocator<std::pair<const int, double> > A;
     std::multimap<int, double, C, A> m(C(4), A(5));
@@ -28,4 +30,16 @@
     assert(m.begin() == m.end());
     assert(m.key_comp() == C(4));
     assert(m.get_allocator() == A(5));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef test_compare<std::less<int> > C;
+    typedef min_allocator<std::pair<const int, double> > A;
+    std::multimap<int, double, C, A> m(C(4), A());
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    assert(m.key_comp() == C(4));
+    assert(m.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/copy.pass.cpp b/test/containers/associative/multimap/multimap.cons/copy.pass.cpp
index b995b6e..65a1e92 100644
--- a/test/containers/associative/multimap/multimap.cons/copy.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/copy.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -73,4 +74,31 @@
         assert(mo.key_comp() == C(5));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::multimap<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::multimap<int, double, C, A> m = mo;
+        assert(m == mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp b/test/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp
index bbbc397..a9cba17 100644
--- a/test/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/copy_alloc.pass.cpp
@@ -18,9 +18,11 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -44,4 +46,32 @@
 
     assert(mo.get_allocator() == A(7));
     assert(mo.key_comp() == C(5));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef test_compare<std::less<int> > C;
+    typedef min_allocator<V> A;
+    std::multimap<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+    std::multimap<int, double, C, A> m(mo, A());
+    assert(m == mo);
+    assert(m.get_allocator() == A());
+    assert(m.key_comp() == C(5));
+
+    assert(mo.get_allocator() == A());
+    assert(mo.key_comp() == C(5));
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp b/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp
index 9b69803..533338c 100644
--- a/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -73,4 +74,32 @@
         assert(mo.get_allocator() == A(2));
         assert(mo.key_comp() == C(5));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<const int, double> V;
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::multimap<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::multimap<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A());
+        m = mo;
+        assert(m == mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/default.pass.cpp b/test/containers/associative/multimap/multimap.cons/default.pass.cpp
index d2e3f60..ca8225f 100644
--- a/test/containers/associative/multimap/multimap.cons/default.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/default.pass.cpp
@@ -16,9 +16,20 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     std::multimap<int, double> m;
     assert(m.empty());
     assert(m.begin() == m.end());
+    }
+#if __cplusplus >= 201103L
+    {
+    std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> m;
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp b/test/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp
index 7683506..139052c 100644
--- a/test/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::multimap<int, double> C;
     typedef C::value_type V;
     C m =
@@ -45,5 +48,36 @@
     assert(*++i == V(3, 1));
     assert(*++i == V(3, 1.5));
     assert(*++i == V(3, 2));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C;
+    typedef C::value_type V;
+    C m =
+           {
+               {1, 1},
+               {1, 1.5},
+               {1, 2},
+               {2, 1},
+               {2, 1.5},
+               {2, 2},
+               {3, 1},
+               {3, 1.5},
+               {3, 2}
+           };
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1, 1));
+    assert(*++i == V(1, 1.5));
+    assert(*++i == V(1, 2));
+    assert(*++i == V(2, 1));
+    assert(*++i == V(2, 1.5));
+    assert(*++i == V(2, 2));
+    assert(*++i == V(3, 1));
+    assert(*++i == V(3, 1.5));
+    assert(*++i == V(3, 2));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp b/test/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp
index 6d7f546..f2545c0 100644
--- a/test/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/initializer_list_compare.pass.cpp
@@ -16,10 +16,12 @@
 #include <map>
 #include <cassert>
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef test_compare<std::less<int> > Cmp;
     typedef std::multimap<int, double, Cmp> C;
     typedef C::value_type V;
@@ -50,5 +52,40 @@
     assert(*++i == V(3, 1.5));
     assert(*++i == V(3, 2));
     assert(m.key_comp() == Cmp(4));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef test_compare<std::less<int> > Cmp;
+    typedef std::multimap<int, double, Cmp, min_allocator<std::pair<const int, double>>> C;
+    typedef C::value_type V;
+    C m(
+           {
+               {1, 1},
+               {1, 1.5},
+               {1, 2},
+               {2, 1},
+               {2, 1.5},
+               {2, 2},
+               {3, 1},
+               {3, 1.5},
+               {3, 2}
+           },
+           Cmp(4)
+        );
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1, 1));
+    assert(*++i == V(1, 1.5));
+    assert(*++i == V(1, 2));
+    assert(*++i == V(2, 1));
+    assert(*++i == V(2, 1.5));
+    assert(*++i == V(2, 2));
+    assert(*++i == V(3, 1));
+    assert(*++i == V(3, 1.5));
+    assert(*++i == V(3, 2));
+    assert(m.key_comp() == Cmp(4));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp b/test/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp
index 47b48f1..a2c0cdb 100644
--- a/test/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/initializer_list_compare_alloc.pass.cpp
@@ -17,10 +17,12 @@
 #include <cassert>
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef test_compare<std::less<int> > Cmp;
     typedef test_allocator<std::pair<const int, double> > A;
     typedef std::multimap<int, double, Cmp, A> C;
@@ -53,5 +55,75 @@
     assert(*++i == V(3, 2));
     assert(m.key_comp() == Cmp(4));
     assert(m.get_allocator() == A(5));
+    }
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if __cplusplus >= 201103L
+    {
+    typedef test_compare<std::less<int> > Cmp;
+    typedef min_allocator<std::pair<const int, double> > A;
+    typedef std::multimap<int, double, Cmp, A> C;
+    typedef C::value_type V;
+    C m(
+           {
+               {1, 1},
+               {1, 1.5},
+               {1, 2},
+               {2, 1},
+               {2, 1.5},
+               {2, 2},
+               {3, 1},
+               {3, 1.5},
+               {3, 2}
+           },
+           Cmp(4), A()
+        );
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1, 1));
+    assert(*++i == V(1, 1.5));
+    assert(*++i == V(1, 2));
+    assert(*++i == V(2, 1));
+    assert(*++i == V(2, 1.5));
+    assert(*++i == V(2, 2));
+    assert(*++i == V(3, 1));
+    assert(*++i == V(3, 1.5));
+    assert(*++i == V(3, 2));
+    assert(m.key_comp() == Cmp(4));
+    assert(m.get_allocator() == A());
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef test_compare<std::less<int> > C;
+    typedef std::pair<const int, double> V;
+    typedef min_allocator<V> A;
+    typedef std::multimap<int, double, C, A> M;
+    A a;
+    M m ({ {1, 1},
+           {1, 1.5},
+           {1, 2},
+           {2, 1},
+           {2, 1.5},
+           {2, 2},
+           {3, 1},
+           {3, 1.5},
+           {3, 2}
+          }, a);
+
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    M::const_iterator i = m.cbegin();
+    assert(*i == V(1, 1));
+    assert(*++i == V(1, 1.5));
+    assert(*++i == V(1, 2));
+    assert(*++i == V(2, 1));
+    assert(*++i == V(2, 1.5));
+    assert(*++i == V(2, 2));
+    assert(*++i == V(3, 1));
+    assert(*++i == V(3, 1.5));
+    assert(*++i == V(3, 2));
+    assert(m.get_allocator() == a);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp b/test/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp
index 00556eb..78fdbdb 100644
--- a/test/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/iter_iter.pass.cpp
@@ -17,8 +17,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -44,4 +47,66 @@
     assert(*next(m.begin(), 6) == V(3, 1));
     assert(*next(m.begin(), 7) == V(3, 1.5));
     assert(*next(m.begin(), 8) == V(3, 2));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    std::multimap<int, double, std::less<int>, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(1, 1.5));
+    assert(*next(m.begin(), 2) == V(1, 2));
+    assert(*next(m.begin(), 3) == V(2, 1));
+    assert(*next(m.begin(), 4) == V(2, 1.5));
+    assert(*next(m.begin(), 5) == V(2, 2));
+    assert(*next(m.begin(), 6) == V(3, 1));
+    assert(*next(m.begin(), 7) == V(3, 1.5));
+    assert(*next(m.begin(), 8) == V(3, 2));
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef min_allocator<std::pair<const int, double>> A;
+    A a;
+    std::multimap<int, double, std::less<int>, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), a);
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(1, 1.5));
+    assert(*next(m.begin(), 2) == V(1, 2));
+    assert(*next(m.begin(), 3) == V(2, 1));
+    assert(*next(m.begin(), 4) == V(2, 1.5));
+    assert(*next(m.begin(), 5) == V(2, 2));
+    assert(*next(m.begin(), 6) == V(3, 1));
+    assert(*next(m.begin(), 7) == V(3, 1.5));
+    assert(*next(m.begin(), 8) == V(3, 2));
+    assert(m.get_allocator() == a);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp b/test/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp
index 57f8796..267edc2 100644
--- a/test/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/iter_iter_comp.pass.cpp
@@ -19,9 +19,11 @@
 #include <cassert>
 
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -49,4 +51,36 @@
     assert(*next(m.begin(), 6) == V(3, 1));
     assert(*next(m.begin(), 7) == V(3, 1.5));
     assert(*next(m.begin(), 8) == V(3, 2));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef test_compare<std::less<int> > C;
+    std::multimap<int, double, C, min_allocator<V>> m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5));
+    assert(m.key_comp() == C(5));
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(1, 1.5));
+    assert(*next(m.begin(), 2) == V(1, 2));
+    assert(*next(m.begin(), 3) == V(2, 1));
+    assert(*next(m.begin(), 4) == V(2, 1.5));
+    assert(*next(m.begin(), 5) == V(2, 2));
+    assert(*next(m.begin(), 6) == V(3, 1));
+    assert(*next(m.begin(), 7) == V(3, 1.5));
+    assert(*next(m.begin(), 8) == V(3, 2));
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp b/test/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp
index c7b0d97..883f64c 100644
--- a/test/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp
@@ -20,9 +20,11 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef std::pair<const int, double> V;
     V ar[] =
     {
@@ -52,4 +54,38 @@
     assert(*next(m.begin(), 6) == V(3, 1));
     assert(*next(m.begin(), 7) == V(3, 1.5));
     assert(*next(m.begin(), 8) == V(3, 2));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::pair<const int, double> V;
+    V ar[] =
+    {
+        V(1, 1),
+        V(1, 1.5),
+        V(1, 2),
+        V(2, 1),
+        V(2, 1.5),
+        V(2, 2),
+        V(3, 1),
+        V(3, 1.5),
+        V(3, 2),
+    };
+    typedef test_compare<std::less<int> > C;
+    typedef min_allocator<V> A;
+    std::multimap<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+    assert(m.get_allocator() == A());
+    assert(m.key_comp() == C(5));
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    assert(*m.begin() == V(1, 1));
+    assert(*next(m.begin()) == V(1, 1.5));
+    assert(*next(m.begin(), 2) == V(1, 2));
+    assert(*next(m.begin(), 3) == V(2, 1));
+    assert(*next(m.begin(), 4) == V(2, 1.5));
+    assert(*next(m.begin(), 5) == V(2, 2));
+    assert(*next(m.begin(), 6) == V(3, 1));
+    assert(*next(m.begin(), 7) == V(3, 1.5));
+    assert(*next(m.begin(), 8) == V(3, 2));
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.cons/move.pass.cpp b/test/containers/associative/multimap/multimap.cons/move.pass.cpp
index 815fc55..d6e835c 100644
--- a/test/containers/associative/multimap/multimap.cons/move.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/move.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -74,5 +75,58 @@
         assert(mo.size() == 0);
         assert(distance(mo.begin(), mo.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::multimap<int, double, C, A> mo(C(5), A());
+        std::multimap<int, double, C, A> m = std::move(mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 0);
+        assert(distance(m.begin(), m.end()) == 0);
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 0);
+        assert(distance(mo.begin(), mo.end()) == 0);
+    }
+    {
+        V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::multimap<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::multimap<int, double, C, A> m = std::move(mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 9);
+        assert(distance(m.begin(), m.end()) == 9);
+        assert(*m.begin() == V(1, 1));
+        assert(*next(m.begin()) == V(1, 1.5));
+        assert(*next(m.begin(), 2) == V(1, 2));
+        assert(*next(m.begin(), 3) == V(2, 1));
+        assert(*next(m.begin(), 4) == V(2, 1.5));
+        assert(*next(m.begin(), 5) == V(2, 2));
+        assert(*next(m.begin(), 6) == V(3, 1));
+        assert(*next(m.begin(), 7) == V(3, 1.5));
+        assert(*next(m.begin(), 8) == V(3, 2));
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 0);
+        assert(distance(mo.begin(), mo.end()) == 0);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp b/test/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp
index ed5eb24..c807b4f 100644
--- a/test/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/move_alloc.pass.cpp
@@ -19,6 +19,7 @@
 #include "../../../MoveOnly.h"
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -140,5 +141,46 @@
         assert(m3.key_comp() == C(5));
         assert(m1.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<MoveOnly, MoveOnly> V;
+        typedef std::pair<const MoveOnly, MoveOnly> VC;
+        typedef test_compare<std::less<MoveOnly> > C;
+        typedef min_allocator<VC> A;
+        typedef std::multimap<MoveOnly, MoveOnly, C, A> M;
+        typedef std::move_iterator<V*> I;
+        V a1[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A());
+        V a2[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A());
+        M m3(std::move(m1), A());
+        assert(m3 == m2);
+        assert(m3.get_allocator() == A());
+        assert(m3.key_comp() == C(5));
+        assert(m1.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multimap/multimap.cons/move_assign.pass.cpp b/test/containers/associative/multimap/multimap.cons/move_assign.pass.cpp
index 4a1e2e9..0aa7c18 100644
--- a/test/containers/associative/multimap/multimap.cons/move_assign.pass.cpp
+++ b/test/containers/associative/multimap/multimap.cons/move_assign.pass.cpp
@@ -19,6 +19,7 @@
 #include "../../../MoveOnly.h"
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -143,5 +144,47 @@
         assert(m3.key_comp() == C(5));
         assert(m1.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<MoveOnly, MoveOnly> V;
+        typedef std::pair<const MoveOnly, MoveOnly> VC;
+        typedef test_compare<std::less<MoveOnly> > C;
+        typedef min_allocator<VC> A;
+        typedef std::multimap<MoveOnly, MoveOnly, C, A> M;
+        typedef std::move_iterator<V*> I;
+        V a1[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A());
+        V a2[] =
+        {
+            V(1, 1),
+            V(1, 2),
+            V(1, 3),
+            V(2, 1),
+            V(2, 2),
+            V(2, 3),
+            V(3, 1),
+            V(3, 2),
+            V(3, 3)
+        };
+        M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A());
+        M m3(C(3), A());
+        m3 = std::move(m1);
+        assert(m3 == m2);
+        assert(m3.get_allocator() == A());
+        assert(m3.key_comp() == C(5));
+        assert(m1.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/clear.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/clear.pass.cpp
index e10b06a..4864ec1 100644
--- a/test/containers/associative/multimap/multimap.modifiers/clear.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/clear.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -37,4 +39,25 @@
         m.clear();
         assert(m.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        P ar[] =
+        {
+            P(1, 1.5),
+            P(2, 2.5),
+            P(3, 3.5),
+            P(4, 4.5),
+            P(5, 5.5),
+            P(6, 6.5),
+            P(7, 7.5),
+            P(8, 8.5),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        m.clear();
+        assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp
index 22406d8..7af4426 100644
--- a/test/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/emplace.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../../Emplaceable.h"
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -34,13 +35,15 @@
         assert(m.begin()->first == 0);
         assert(m.begin()->second == DefaultOnly());
         assert(DefaultOnly::count == 1);
-        r = m.emplace(1);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
         assert(r == next(m.begin()));
         assert(m.size() == 2);
         assert(next(m.begin())->first == 1);
         assert(next(m.begin())->second == DefaultOnly());
         assert(DefaultOnly::count == 2);
-        r = m.emplace(1);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
         assert(r == next(m.begin(), 2));
         assert(m.size() == 3);
         assert(next(m.begin(), 2)->first == 1);
@@ -52,7 +55,8 @@
         typedef std::multimap<int, Emplaceable> M;
         typedef M::iterator R;
         M m;
-        R r = m.emplace(2);
+        R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
+                                                  std::forward_as_tuple());
         assert(r == m.begin());
         assert(m.size() == 1);
         assert(m.begin()->first == 2);
@@ -80,5 +84,67 @@
         assert(m.begin()->first == 2);
         assert(m.begin()->second == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
+        typedef M::iterator R;
+        M m;
+        assert(DefaultOnly::count == 0);
+        R r = m.emplace();
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 0);
+        assert(m.begin()->second == DefaultOnly());
+        assert(DefaultOnly::count == 1);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
+        assert(r == next(m.begin()));
+        assert(m.size() == 2);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == DefaultOnly());
+        assert(DefaultOnly::count == 2);
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple());
+        assert(r == next(m.begin(), 2));
+        assert(m.size() == 3);
+        assert(next(m.begin(), 2)->first == 1);
+        assert(next(m.begin(), 2)->second == DefaultOnly());
+        assert(DefaultOnly::count == 3);
+    }
+    assert(DefaultOnly::count == 0);
+    {
+        typedef std::multimap<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
+                                                  std::forward_as_tuple());
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == Emplaceable());
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple(2, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == Emplaceable(2, 3.5));
+        r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
+                                                std::forward_as_tuple(3, 3.5));
+        assert(r == next(m.begin()));
+        assert(m.size() == 3);
+        assert(r->first == 1);
+        assert(r->second == Emplaceable(3, 3.5));
+    }
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace(M::value_type(2, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 3.5);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp
index 4c3e468..3f94c03 100644
--- a/test/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/emplace_hint.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../../Emplaceable.h"
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -34,13 +35,17 @@
         assert(m.begin()->first == 0);
         assert(m.begin()->second == DefaultOnly());
         assert(DefaultOnly::count == 1);
-        r = m.emplace_hint(m.cend(), 1);
+        r = m.emplace_hint(m.cend(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
         assert(r == next(m.begin()));
         assert(m.size() == 2);
         assert(next(m.begin())->first == 1);
         assert(next(m.begin())->second == DefaultOnly());
         assert(DefaultOnly::count == 2);
-        r = m.emplace_hint(m.cend(), 1);
+        r = m.emplace_hint(m.cend(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
         assert(r == next(m.begin(), 2));
         assert(m.size() == 3);
         assert(next(m.begin(), 2)->first == 1);
@@ -52,7 +57,9 @@
         typedef std::multimap<int, Emplaceable> M;
         typedef M::iterator R;
         M m;
-        R r = m.emplace_hint(m.cend(), 2);
+        R r = m.emplace_hint(m.cend(), std::piecewise_construct,
+                                       std::forward_as_tuple(2),
+                                       std::forward_as_tuple());
         assert(r == m.begin());
         assert(m.size() == 1);
         assert(m.begin()->first == 2);
@@ -82,5 +89,72 @@
         assert(m.begin()->first == 2);
         assert(m.begin()->second == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
+        typedef M::iterator R;
+        M m;
+        assert(DefaultOnly::count == 0);
+        R r = m.emplace_hint(m.cend());
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 0);
+        assert(m.begin()->second == DefaultOnly());
+        assert(DefaultOnly::count == 1);
+        r = m.emplace_hint(m.cend(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
+        assert(r == next(m.begin()));
+        assert(m.size() == 2);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == DefaultOnly());
+        assert(DefaultOnly::count == 2);
+        r = m.emplace_hint(m.cend(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple());
+        assert(r == next(m.begin(), 2));
+        assert(m.size() == 3);
+        assert(next(m.begin(), 2)->first == 1);
+        assert(next(m.begin(), 2)->second == DefaultOnly());
+        assert(DefaultOnly::count == 3);
+    }
+    assert(DefaultOnly::count == 0);
+    {
+        typedef std::multimap<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace_hint(m.cend(), std::piecewise_construct,
+                                       std::forward_as_tuple(2),
+                                       std::forward_as_tuple());
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == Emplaceable());
+        r = m.emplace_hint(m.cbegin(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple(2, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == Emplaceable(2, 3.5));
+        r = m.emplace_hint(m.cbegin(), std::piecewise_construct,
+                                       std::forward_as_tuple(1),
+                                       std::forward_as_tuple(3, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 3);
+        assert(r->first == 1);
+        assert(r->second == Emplaceable(3, 3.5));
+    }
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace_hint(m.cend(), M::value_type(2, 3.5));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(m.begin()->first == 2);
+        assert(m.begin()->second == 3.5);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp
index 794d311..d2979b1 100644
--- a/test/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -145,4 +147,133 @@
         assert(i == m.begin());
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        typedef M::iterator I;
+        P ar[] =
+        {
+            P(1, 1),
+            P(1, 1.5),
+            P(1, 2),
+            P(2, 1),
+            P(2, 1.5),
+            P(2, 2),
+            P(3, 1),
+            P(3, 1.5),
+            P(3, 2),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 9);
+        I i = m.erase(next(m.cbegin(), 3));
+        assert(m.size() == 8);
+        assert(i == next(m.begin(), 3));
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == 1.5);
+        assert(next(m.begin(), 2)->first == 1);
+        assert(next(m.begin(), 2)->second == 2);
+        assert(next(m.begin(), 3)->first == 2);
+        assert(next(m.begin(), 3)->second == 1.5);
+        assert(next(m.begin(), 4)->first == 2);
+        assert(next(m.begin(), 4)->second == 2);
+        assert(next(m.begin(), 5)->first == 3);
+        assert(next(m.begin(), 5)->second == 1);
+        assert(next(m.begin(), 6)->first == 3);
+        assert(next(m.begin(), 6)->second == 1.5);
+        assert(next(m.begin(), 7)->first == 3);
+        assert(next(m.begin(), 7)->second == 2);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 7);
+        assert(i == m.begin());
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1.5);
+        assert(next(m.begin(), 1)->first == 1);
+        assert(next(m.begin(), 1)->second == 2);
+        assert(next(m.begin(), 2)->first == 2);
+        assert(next(m.begin(), 2)->second == 1.5);
+        assert(next(m.begin(), 3)->first == 2);
+        assert(next(m.begin(), 3)->second == 2);
+        assert(next(m.begin(), 4)->first == 3);
+        assert(next(m.begin(), 4)->second == 1);
+        assert(next(m.begin(), 5)->first == 3);
+        assert(next(m.begin(), 5)->second == 1.5);
+        assert(next(m.begin(), 6)->first == 3);
+        assert(next(m.begin(), 6)->second == 2);
+
+        i = m.erase(next(m.cbegin(), 5));
+        assert(m.size() == 6);
+        assert(i == prev(m.end()));
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1.5);
+        assert(next(m.begin(), 1)->first == 1);
+        assert(next(m.begin(), 1)->second == 2);
+        assert(next(m.begin(), 2)->first == 2);
+        assert(next(m.begin(), 2)->second == 1.5);
+        assert(next(m.begin(), 3)->first == 2);
+        assert(next(m.begin(), 3)->second == 2);
+        assert(next(m.begin(), 4)->first == 3);
+        assert(next(m.begin(), 4)->second == 1);
+        assert(next(m.begin(), 5)->first == 3);
+        assert(next(m.begin(), 5)->second == 2);
+
+        i = m.erase(next(m.cbegin(), 1));
+        assert(m.size() == 5);
+        assert(i == next(m.begin()));
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1.5);
+        assert(next(m.begin(), 1)->first == 2);
+        assert(next(m.begin(), 1)->second == 1.5);
+        assert(next(m.begin(), 2)->first == 2);
+        assert(next(m.begin(), 2)->second == 2);
+        assert(next(m.begin(), 3)->first == 3);
+        assert(next(m.begin(), 3)->second == 1);
+        assert(next(m.begin(), 4)->first == 3);
+        assert(next(m.begin(), 4)->second == 2);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 4);
+        assert(i == next(m.begin(), 2));
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1.5);
+        assert(next(m.begin(), 1)->first == 2);
+        assert(next(m.begin(), 1)->second == 1.5);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 1);
+        assert(next(m.begin(), 3)->first == 3);
+        assert(next(m.begin(), 3)->second == 2);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 3);
+        assert(i == next(m.begin(), 2));
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1.5);
+        assert(next(m.begin(), 1)->first == 2);
+        assert(next(m.begin(), 1)->second == 1.5);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 2);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 0));
+        assert(next(m.begin(), 0)->first == 2);
+        assert(next(m.begin(), 0)->second == 1.5);
+        assert(next(m.begin(), 1)->first == 3);
+        assert(next(m.begin(), 1)->second == 2);
+
+        i = m.erase(next(m.cbegin(), 1));
+        assert(m.size() == 1);
+        assert(i == m.end());
+        assert(next(m.begin(), 0)->first == 2);
+        assert(next(m.begin(), 0)->second == 1.5);
+
+        i = m.erase(m.cbegin());
+        assert(m.size() == 0);
+        assert(i == m.begin());
+        assert(i == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp
index 954c56d..be1ab6f 100644
--- a/test/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/erase_iter_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -84,4 +86,72 @@
         assert(i == m.begin());
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        typedef M::iterator I;
+        P ar[] =
+        {
+            P(1, 1.5),
+            P(2, 2.5),
+            P(3, 3.5),
+            P(4, 4.5),
+            P(5, 5.5),
+            P(6, 6.5),
+            P(7, 7.5),
+            P(8, 8.5),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(m.cbegin(), m.cbegin());
+        assert(m.size() == 8);
+        assert(i == m.begin());
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1.5);
+        assert(next(m.begin())->first == 2);
+        assert(next(m.begin())->second == 2.5);
+        assert(next(m.begin(), 2)->first == 3);
+        assert(next(m.begin(), 2)->second == 3.5);
+        assert(next(m.begin(), 3)->first == 4);
+        assert(next(m.begin(), 3)->second == 4.5);
+        assert(next(m.begin(), 4)->first == 5);
+        assert(next(m.begin(), 4)->second == 5.5);
+        assert(next(m.begin(), 5)->first == 6);
+        assert(next(m.begin(), 5)->second == 6.5);
+        assert(next(m.begin(), 6)->first == 7);
+        assert(next(m.begin(), 6)->second == 7.5);
+        assert(next(m.begin(), 7)->first == 8);
+        assert(next(m.begin(), 7)->second == 8.5);
+
+        i = m.erase(m.cbegin(), next(m.cbegin(), 2));
+        assert(m.size() == 6);
+        assert(i == m.begin());
+        assert(next(m.begin(), 0)->first == 3);
+        assert(next(m.begin(), 0)->second == 3.5);
+        assert(next(m.begin(), 1)->first == 4);
+        assert(next(m.begin(), 1)->second == 4.5);
+        assert(next(m.begin(), 2)->first == 5);
+        assert(next(m.begin(), 2)->second == 5.5);
+        assert(next(m.begin(), 3)->first == 6);
+        assert(next(m.begin(), 3)->second == 6.5);
+        assert(next(m.begin(), 4)->first == 7);
+        assert(next(m.begin(), 4)->second == 7.5);
+        assert(next(m.begin(), 5)->first == 8);
+        assert(next(m.begin(), 5)->second == 8.5);
+
+        i = m.erase(next(m.cbegin(), 2), next(m.cbegin(), 6));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 2));
+        assert(next(m.begin(), 0)->first == 3);
+        assert(next(m.begin(), 0)->second == 3.5);
+        assert(next(m.begin(), 1)->first == 4);
+        assert(next(m.begin(), 1)->second == 4.5);
+
+        i = m.erase(m.cbegin(), m.cend());
+        assert(m.size() == 0);
+        assert(i == m.begin());
+        assert(i == m.end());
+    }
+#endif
 }
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 cdf5b9d..c5dd6fb 100644
--- a/test/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/erase_key.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -81,4 +83,69 @@
         assert(m.size() == 0);
         assert(i == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        typedef M::size_type I;
+        P ar[] =
+        {
+            P(1, 1),
+            P(1, 1.5),
+            P(1, 2),
+            P(2, 1),
+            P(2, 1.5),
+            P(2, 2),
+            P(3, 1),
+            P(3, 1.5),
+            P(3, 2),
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 9);
+        I i = m.erase(2);
+        assert(m.size() == 6);
+        assert(i == 3);
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1);
+        assert(next(m.begin(), 1)->first == 1);
+        assert(next(m.begin(), 1)->second == 1.5);
+        assert(next(m.begin(), 2)->first == 1);
+        assert(next(m.begin(), 2)->second == 2);
+        assert(next(m.begin(), 3)->first == 3);
+        assert(next(m.begin(), 3)->second == 1);
+        assert(next(m.begin(), 4)->first == 3);
+        assert(next(m.begin(), 4)->second == 1.5);
+        assert(next(m.begin(), 5)->first == 3);
+        assert(next(m.begin(), 5)->second == 2);
+
+        i = m.erase(2);
+        assert(m.size() == 6);
+        assert(i == 0);
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1);
+        assert(next(m.begin(), 1)->first == 1);
+        assert(next(m.begin(), 1)->second == 1.5);
+        assert(next(m.begin(), 2)->first == 1);
+        assert(next(m.begin(), 2)->second == 2);
+        assert(next(m.begin(), 3)->first == 3);
+        assert(next(m.begin(), 3)->second == 1);
+        assert(next(m.begin(), 4)->first == 3);
+        assert(next(m.begin(), 4)->second == 1.5);
+        assert(next(m.begin(), 5)->first == 3);
+        assert(next(m.begin(), 5)->second == 2);
+
+        i = m.erase(3);
+        assert(m.size() == 3);
+        assert(next(m.begin(), 0)->first == 1);
+        assert(next(m.begin(), 0)->second == 1);
+        assert(next(m.begin(), 1)->first == 1);
+        assert(next(m.begin(), 1)->second == 1.5);
+        assert(next(m.begin(), 2)->first == 1);
+        assert(next(m.begin(), 2)->second == 2);
+
+        i = m.erase(1);
+        assert(m.size() == 0);
+        assert(i == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp
index 4ad2704..c23d821 100644
--- a/test/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/insert_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -46,4 +48,34 @@
         assert(r->first == 3);
         assert(r->second == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(M::value_type(2, 2.5));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(r->first == 2);
+        assert(r->second == 2.5);
+
+        r = m.insert(M::value_type(1, 1.5));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(r->first == 1);
+        assert(r->second == 1.5);
+
+        r = m.insert(M::value_type(3, 3.5));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3.5);
+
+        r = m.insert(M::value_type(3, 3.5));
+        assert(r == prev(m.end()));
+        assert(m.size() == 4);
+        assert(r->first == 3);
+        assert(r->second == 3.5);
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp
index 26a9cb8..8fc080d 100644
--- a/test/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/insert_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::multimap<int, double> C;
     typedef C::value_type V;
     C m =
@@ -49,5 +52,40 @@
     assert(*++i == V(3, 1));
     assert(*++i == V(3, 2));
     assert(*++i == V(3, 1.5));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> C;
+    typedef C::value_type V;
+    C m =
+           {
+               {1, 1},
+               {1, 2},
+               {2, 1},
+               {2, 2},
+               {3, 1},
+               {3, 2}
+           };
+    m.insert(
+               {
+                   {1, 1.5},
+                   {2, 1.5},
+                   {3, 1.5},
+               }
+            );
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1, 1));
+    assert(*++i == V(1, 2));
+    assert(*++i == V(1, 1.5));
+    assert(*++i == V(2, 1));
+    assert(*++i == V(2, 2));
+    assert(*++i == V(2, 1.5));
+    assert(*++i == V(3, 1));
+    assert(*++i == V(3, 2));
+    assert(*++i == V(3, 1.5));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp
index ebe4901..0c8e916 100644
--- a/test/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/insert_iter_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -46,4 +48,34 @@
         assert(r->first == 3);
         assert(r->second == 4.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.end(), M::value_type(2, 2.5));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(r->first == 2);
+        assert(r->second == 2.5);
+
+        r = m.insert(m.end(), M::value_type(1, 1.5));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(r->first == 1);
+        assert(r->second == 1.5);
+
+        r = m.insert(m.end(), M::value_type(3, 3.5));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3.5);
+
+        r = m.insert(prev(m.end()), M::value_type(3, 4.5));
+        assert(r == prev(m.end(), 2));
+        assert(m.size() == 4);
+        assert(r->first == 3);
+        assert(r->second == 4.5);
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp
index fcd4cee..6e3d2f2 100644
--- a/test/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/insert_iter_iter.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -58,4 +59,43 @@
         assert(next(m.begin(), 8)->first == 3);
         assert(next(m.begin(), 8)->second == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+        typedef std::pair<int, double> P;
+        P ar[] =
+        {
+            P(1, 1),
+            P(1, 1.5),
+            P(1, 2),
+            P(2, 1),
+            P(2, 1.5),
+            P(2, 2),
+            P(3, 1),
+            P(3, 1.5),
+            P(3, 2),
+        };
+        M m;
+        m.insert(input_iterator<P*>(ar), input_iterator<P*>(ar + sizeof(ar)/sizeof(ar[0])));
+        assert(m.size() == 9);
+        assert(m.begin()->first == 1);
+        assert(m.begin()->second == 1);
+        assert(next(m.begin())->first == 1);
+        assert(next(m.begin())->second == 1.5);
+        assert(next(m.begin(), 2)->first == 1);
+        assert(next(m.begin(), 2)->second == 2);
+        assert(next(m.begin(), 3)->first == 2);
+        assert(next(m.begin(), 3)->second == 1);
+        assert(next(m.begin(), 4)->first == 2);
+        assert(next(m.begin(), 4)->second == 1.5);
+        assert(next(m.begin(), 5)->first == 2);
+        assert(next(m.begin(), 5)->second == 2);
+        assert(next(m.begin(), 6)->first == 3);
+        assert(next(m.begin(), 6)->second == 1);
+        assert(next(m.begin(), 7)->first == 3);
+        assert(next(m.begin(), 7)->second == 1.5);
+        assert(next(m.begin(), 8)->first == 3);
+        assert(next(m.begin(), 8)->second == 2);
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp
index 15993cb..efc99e1 100644
--- a/test/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/insert_iter_rv.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -51,5 +52,36 @@
         assert(r->first == 3);
         assert(r->second == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
+        typedef std::pair<int, MoveOnly> P;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.cend(), P(2, 2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(r->first == 2);
+        assert(r->second == 2);
+
+        r = m.insert(m.cend(), P(1, 1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(r->first == 1);
+        assert(r->second == 1);
+
+        r = m.insert(m.cend(), P(3, 3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3);
+
+        r = m.insert(m.cend(), P(3, 2));
+        assert(r == prev(m.end()));
+        assert(m.size() == 4);
+        assert(r->first == 3);
+        assert(r->second == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp b/test/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp
index 285881c..1678c9d 100644
--- a/test/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp
+++ b/test/containers/associative/multimap/multimap.modifiers/insert_rv.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -50,5 +51,35 @@
         assert(r->first == 3);
         assert(r->second == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(M::value_type(2, 2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(r->first == 2);
+        assert(r->second == 2);
+
+        r = m.insert(M::value_type(1, 1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(r->first == 1);
+        assert(r->second == 1);
+
+        r = m.insert(M::value_type(3, 3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == 3);
+
+        r = m.insert(M::value_type(3, 3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 4);
+        assert(r->first == 3);
+        assert(r->second == 3);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multimap/multimap.ops/count.pass.cpp b/test/containers/associative/multimap/multimap.ops/count.pass.cpp
index e707cd7..b0e4c58 100644
--- a/test/containers/associative/multimap/multimap.ops/count.pass.cpp
+++ b/test/containers/associative/multimap/multimap.ops/count.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     typedef std::pair<const int, double> V;
+    {
     typedef std::multimap<int, double> M;
     {
         typedef M::size_type R;
@@ -50,4 +53,40 @@
         r = m.count(10);
         assert(r == 0);
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    {
+        typedef M::size_type R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.count(4);
+        assert(r == 0);
+        r = m.count(5);
+        assert(r == 3);
+        r = m.count(6);
+        assert(r == 0);
+        r = m.count(7);
+        assert(r == 3);
+        r = m.count(8);
+        assert(r == 0);
+        r = m.count(9);
+        assert(r == 3);
+        r = m.count(10);
+        assert(r == 0);
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.ops/equal_range.pass.cpp b/test/containers/associative/multimap/multimap.ops/equal_range.pass.cpp
index 73f392c..4632eb1 100644
--- a/test/containers/associative/multimap/multimap.ops/equal_range.pass.cpp
+++ b/test/containers/associative/multimap/multimap.ops/equal_range.pass.cpp
@@ -17,9 +17,13 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
     typedef std::pair<const int, double> V;
+    {
     typedef std::multimap<int, double> M;
     {
         typedef std::pair<M::iterator, M::iterator> R;
@@ -95,4 +99,166 @@
         assert(r.first == m.end());
         assert(r.second == m.end());
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    {
+        typedef std::pair<M::iterator, M::iterator> R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.equal_range(4);
+        assert(r.first == m.begin());
+        assert(r.second == m.begin());
+        r = m.equal_range(5);
+        assert(r.first == m.begin());
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(6);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(7);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(8);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(9);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 9));
+        r = m.equal_range(10);
+        assert(r.first == m.end());
+        assert(r.second == m.end());
+    }
+    {
+        typedef std::pair<M::const_iterator, M::const_iterator> R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.equal_range(4);
+        assert(r.first == m.begin());
+        assert(r.second == m.begin());
+        r = m.equal_range(5);
+        assert(r.first == m.begin());
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(6);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(7);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(8);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(9);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 9));
+        r = m.equal_range(10);
+        assert(r.first == m.end());
+        assert(r.second == m.end());
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::multimap<int, double, std::less<>> M;
+
+    typedef std::pair<M::iterator, M::iterator> R;
+    V ar[] =
+    {
+        V(5, 1),
+        V(5, 2),
+        V(5, 3),
+        V(7, 1),
+        V(7, 2),
+        V(7, 3),
+        V(9, 1),
+        V(9, 2),
+        V(9, 3)
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.equal_range(4);
+    assert(r.first == m.begin());
+    assert(r.second == m.begin());
+    r = m.equal_range(5);
+    assert(r.first == m.begin());
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(6);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(7);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(8);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(9);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 9));
+    r = m.equal_range(10);
+    assert(r.first == m.end());
+    assert(r.second == m.end());
+    }
+
+    {
+    typedef PrivateConstructor PC;
+    typedef std::multimap<PC, double, std::less<>> M;
+    typedef std::pair<M::iterator, M::iterator> R;
+
+    M m;
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 3 ));
+
+//  assert(m.size() == 9);
+    R r = m.equal_range(4);
+    assert(r.first == m.begin());
+    assert(r.second == m.begin());
+    r = m.equal_range(5);
+    assert(r.first == m.begin());
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(6);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(7);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(8);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(9);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 9));
+    r = m.equal_range(10);
+    assert(r.first == m.end());
+    assert(r.second == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.ops/find.pass.cpp b/test/containers/associative/multimap/multimap.ops/find.pass.cpp
index fe7e34f..e4dba28 100644
--- a/test/containers/associative/multimap/multimap.ops/find.pass.cpp
+++ b/test/containers/associative/multimap/multimap.ops/find.pass.cpp
@@ -17,9 +17,13 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
     typedef std::pair<const int, double> V;
+    {
     typedef std::multimap<int, double> M;
     {
         typedef M::iterator R;
@@ -77,4 +81,129 @@
         r = m.find(10);
         assert(r == m.end());
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.find(5);
+        assert(r == m.begin());
+        r = m.find(6);
+        assert(r == m.end());
+        r = m.find(7);
+        assert(r == next(m.begin(), 3));
+        r = m.find(8);
+        assert(r == m.end());
+        r = m.find(9);
+        assert(r == next(m.begin(), 6));
+        r = m.find(10);
+        assert(r == m.end());
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.find(5);
+        assert(r == m.begin());
+        r = m.find(6);
+        assert(r == m.end());
+        r = m.find(7);
+        assert(r == next(m.begin(), 3));
+        r = m.find(8);
+        assert(r == m.end());
+        r = m.find(9);
+        assert(r == next(m.begin(), 6));
+        r = m.find(10);
+        assert(r == m.end());
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::multimap<int, double, std::less<>> M;
+    typedef M::iterator R;
+
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.find(5);
+        assert(r == m.begin());
+        r = m.find(6);
+        assert(r == m.end());
+        r = m.find(7);
+        assert(r == next(m.begin(), 3));
+        r = m.find(8);
+        assert(r == m.end());
+        r = m.find(9);
+        assert(r == next(m.begin(), 6));
+        r = m.find(10);
+        assert(r == m.end());
+    }
+
+    {
+    typedef PrivateConstructor PC;
+    typedef std::multimap<PC, double, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 3 ));
+
+    R r = m.find(5);
+    assert(r == m.begin());
+    r = m.find(6);
+    assert(r == m.end());
+    r = m.find(7);
+    assert(r == next(m.begin(), 3));
+    r = m.find(8);
+    assert(r == m.end());
+    r = m.find(9);
+    assert(r == next(m.begin(), 6));
+    r = m.find(10);
+    assert(r == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp b/test/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp
index fe682f1..5ec1210 100644
--- a/test/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp
+++ b/test/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp
@@ -17,9 +17,13 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
     typedef std::pair<const int, double> V;
+    {
     typedef std::multimap<int, double> M;
     {
         typedef M::iterator R;
@@ -81,4 +85,137 @@
         r = m.lower_bound(10);
         assert(r == m.end());
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.lower_bound(4);
+        assert(r == m.begin());
+        r = m.lower_bound(5);
+        assert(r == m.begin());
+        r = m.lower_bound(6);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(7);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(8);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(9);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(10);
+        assert(r == m.end());
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.lower_bound(4);
+        assert(r == m.begin());
+        r = m.lower_bound(5);
+        assert(r == m.begin());
+        r = m.lower_bound(6);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(7);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(8);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(9);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(10);
+        assert(r == m.end());
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::multimap<int, double, std::less<>> M;
+    typedef M::iterator R;
+    V ar[] =
+    {
+        V(5, 1),
+        V(5, 2),
+        V(5, 3),
+        V(7, 1),
+        V(7, 2),
+        V(7, 3),
+        V(9, 1),
+        V(9, 2),
+        V(9, 3)
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.lower_bound(4);
+    assert(r == m.begin());
+    r = m.lower_bound(5);
+    assert(r == m.begin());
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(7);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(10);
+    assert(r == m.end());
+    }
+
+    {
+    typedef PrivateConstructor PC;
+    typedef std::multimap<PC, double, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 3 ));
+
+    R r = m.lower_bound(4);
+    assert(r == m.begin());
+    r = m.lower_bound(5);
+    assert(r == m.begin());
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(7);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(10);
+    assert(r == m.end());
+    }
+
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp b/test/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp
index 3d6bd88..aa5a525 100644
--- a/test/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp
+++ b/test/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp
@@ -17,9 +17,13 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
     typedef std::pair<const int, double> V;
+    {
     typedef std::multimap<int, double> M;
     {
         typedef M::iterator R;
@@ -81,4 +85,137 @@
         r = m.upper_bound(10);
         assert(r == m.end());
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(4);
+        assert(r == m.begin());
+        r = m.upper_bound(5);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 9));
+        r = m.upper_bound(10);
+        assert(r == m.end());
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            V(5, 1),
+            V(5, 2),
+            V(5, 3),
+            V(7, 1),
+            V(7, 2),
+            V(7, 3),
+            V(9, 1),
+            V(9, 2),
+            V(9, 3)
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(4);
+        assert(r == m.begin());
+        r = m.upper_bound(5);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 9));
+        r = m.upper_bound(10);
+        assert(r == m.end());
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::pair<const int, double> V;
+    typedef std::multimap<int, double, std::less<>> M;
+    typedef M::iterator R;
+    V ar[] =
+    {
+        V(5, 1),
+        V(5, 2),
+        V(5, 3),
+        V(7, 1),
+        V(7, 2),
+        V(7, 3),
+        V(9, 1),
+        V(9, 2),
+        V(9, 3)
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.upper_bound(4);
+    assert(r == m.begin());
+    r = m.upper_bound(5);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 9));
+    r = m.upper_bound(10);
+    assert(r == m.end());
+    }
+
+    {
+    typedef PrivateConstructor PC;
+    typedef std::multimap<PC, double, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(5), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(7), 3 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 1 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 2 ));
+    m.insert ( std::make_pair<PC, double> ( PC::make(9), 3 ));
+
+    R r = m.upper_bound(4);
+    assert(r == m.begin());
+    r = m.upper_bound(5);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 9));
+    r = m.upper_bound(10);
+    assert(r == m.end());
+    }
+
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.special/member_swap.pass.cpp b/test/containers/associative/multimap/multimap.special/member_swap.pass.cpp
index 05d1260..1e1ab23 100644
--- a/test/containers/associative/multimap/multimap.special/member_swap.pass.cpp
+++ b/test/containers/associative/multimap/multimap.special/member_swap.pass.cpp
@@ -16,9 +16,12 @@
 #include <map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     typedef std::pair<const int, double> V;
+    {
     typedef std::multimap<int, double> M;
     {
         V ar1[] =
@@ -104,4 +107,94 @@
         assert(m1 == m2_save);
         assert(m2 == m1_save);
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp b/test/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp
index 390340f..6f5b92f 100644
--- a/test/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp
+++ b/test/containers/associative/multimap/multimap.special/non_member_swap.pass.cpp
@@ -19,10 +19,12 @@
 #include <cassert>
 #include "../../../test_allocator.h"
 #include "../../../test_compare.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
     typedef std::pair<const int, double> V;
+    {
     typedef std::multimap<int, double> M;
     {
         V ar1[] =
@@ -176,4 +178,128 @@
         assert(m2.key_comp() == C(1));
         assert(m2.get_allocator() == A(1));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        typedef min_allocator<V> A;
+        typedef test_compare<std::less<int> > C;
+        typedef std::multimap<int, double, C, A> M;
+        V ar1[] =
+        {
+            V(1, 1),
+            V(2, 2),
+            V(3, 3),
+            V(4, 4)
+        };
+        V ar2[] =
+        {
+            V(5, 5),
+            V(6, 6),
+            V(7, 7),
+            V(8, 8),
+            V(9, 9),
+            V(10, 10),
+            V(11, 11),
+            V(12, 12)
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]), C(1), A());
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]), C(2), A());
+        M m1_save = m1;
+        M m2_save = m2;
+        swap(m1, m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+        assert(m1.key_comp() == C(2));
+        assert(m1.get_allocator() == A());
+        assert(m2.key_comp() == C(1));
+        assert(m2.get_allocator() == A());
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/scary.pass.cpp b/test/containers/associative/multimap/scary.pass.cpp
new file mode 100644
index 0000000..b99d9bc
--- /dev/null
+++ b/test/containers/associative/multimap/scary.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map class multimap
+
+// Extension:  SCARY/N2913 iterator compatibility between map and multimap
+
+#include <map>
+
+int main()
+{
+    typedef std::map<int, int> M1;
+    typedef std::multimap<int, int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}
diff --git a/test/containers/associative/multimap/size.pass.cpp b/test/containers/associative/multimap/size.pass.cpp
index eb7b1c9..794c34a 100644
--- a/test/containers/associative/multimap/size.pass.cpp
+++ b/test/containers/associative/multimap/size.pass.cpp
@@ -16,8 +16,11 @@
 #include <map>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::multimap<int, double> M;
     M m;
     assert(m.size() == 0);
@@ -33,4 +36,24 @@
     assert(m.size() == 1);
     m.erase(m.begin());
     assert(m.size() == 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
+    M m;
+    assert(m.size() == 0);
+    m.insert(M::value_type(2, 1.5));
+    assert(m.size() == 1);
+    m.insert(M::value_type(1, 1.5));
+    assert(m.size() == 2);
+    m.insert(M::value_type(3, 1.5));
+    assert(m.size() == 3);
+    m.erase(m.begin());
+    assert(m.size() == 2);
+    m.erase(m.begin());
+    assert(m.size() == 1);
+    m.erase(m.begin());
+    assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/multimap/types.pass.cpp b/test/containers/associative/multimap/types.pass.cpp
index 4bb7242..2fe8fe0 100644
--- a/test/containers/associative/multimap/types.pass.cpp
+++ b/test/containers/associative/multimap/types.pass.cpp
@@ -32,8 +32,11 @@
 #include <map>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     static_assert((std::is_same<std::multimap<int, double>::key_type, int>::value), "");
     static_assert((std::is_same<std::multimap<int, double>::mapped_type, double>::value), "");
     static_assert((std::is_same<std::multimap<int, double>::value_type, std::pair<const int, double> >::value), "");
@@ -45,4 +48,20 @@
     static_assert((std::is_same<std::multimap<int, double>::const_pointer, const std::pair<const int, double>*>::value), "");
     static_assert((std::is_same<std::multimap<int, double>::size_type, std::size_t>::value), "");
     static_assert((std::is_same<std::multimap<int, double>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#if __cplusplus >= 201103L
+    {
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::key_type, int>::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::mapped_type, double>::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::value_type, std::pair<const int, double> >::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::key_compare, std::less<int> >::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::allocator_type, min_allocator<std::pair<const int, double> > >::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::reference, std::pair<const int, double>&>::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::const_reference, const std::pair<const int, double>&>::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::pointer, min_pointer<std::pair<const int, double>>>::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::const_pointer, min_pointer<const std::pair<const int, double>>>::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::size_type, std::size_t>::value), "");
+    static_assert((std::is_same<std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/clear.pass.cpp b/test/containers/associative/multiset/clear.pass.cpp
index f91b74f..f325a70 100644
--- a/test/containers/associative/multiset/clear.pass.cpp
+++ b/test/containers/associative/multiset/clear.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -37,4 +39,25 @@
         m.clear();
         assert(m.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+            7,
+            8
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        m.clear();
+        assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/count.pass.cpp b/test/containers/associative/multiset/count.pass.cpp
index 726c805..cba6430 100644
--- a/test/containers/associative/multiset/count.pass.cpp
+++ b/test/containers/associative/multiset/count.pass.cpp
@@ -16,8 +16,11 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::multiset<int> M;
     {
@@ -50,4 +53,41 @@
         r = m.count(10);
         assert(r == 0);
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+    {
+        typedef M::size_type R;
+        V ar[] =
+        {
+            5,
+            5,
+            5,
+            5,
+            7,
+            7,
+            7,
+            9,
+            9
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.count(4);
+        assert(r == 0);
+        r = m.count(5);
+        assert(r == 4);
+        r = m.count(6);
+        assert(r == 0);
+        r = m.count(7);
+        assert(r == 3);
+        r = m.count(8);
+        assert(r == 0);
+        r = m.count(9);
+        assert(r == 2);
+        r = m.count(10);
+        assert(r == 0);
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/emplace.pass.cpp b/test/containers/associative/multiset/emplace.pass.cpp
index 55f11fc..08ac42b 100644
--- a/test/containers/associative/multiset/emplace.pass.cpp
+++ b/test/containers/associative/multiset/emplace.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../Emplaceable.h"
 #include "../../DefaultOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -67,5 +68,16 @@
         assert(m.size() == 1);
         assert(*r == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace(M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multiset/emplace_hint.pass.cpp b/test/containers/associative/multiset/emplace_hint.pass.cpp
index 9e4befa..1510c01 100644
--- a/test/containers/associative/multiset/emplace_hint.pass.cpp
+++ b/test/containers/associative/multiset/emplace_hint.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../Emplaceable.h"
 #include "../../DefaultOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -67,5 +68,16 @@
         assert(m.size() == 1);
         assert(*r == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace_hint(m.cend(), M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/multiset/empty.pass.cpp b/test/containers/associative/multiset/empty.pass.cpp
index 8213fbb..154180d 100644
--- a/test/containers/associative/multiset/empty.pass.cpp
+++ b/test/containers/associative/multiset/empty.pass.cpp
@@ -16,8 +16,11 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::multiset<int> M;
     M m;
     assert(m.empty());
@@ -25,4 +28,16 @@
     assert(!m.empty());
     m.clear();
     assert(m.empty());
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+    M m;
+    assert(m.empty());
+    m.insert(M::value_type(1));
+    assert(!m.empty());
+    m.clear();
+    assert(m.empty());
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/equal_range.pass.cpp b/test/containers/associative/multiset/equal_range.pass.cpp
index 4d8cd98..6babfa1 100644
--- a/test/containers/associative/multiset/equal_range.pass.cpp
+++ b/test/containers/associative/multiset/equal_range.pass.cpp
@@ -17,8 +17,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::multiset<int> M;
     {
@@ -95,4 +99,165 @@
         assert(r.first  == next(m.begin(), 9));
         assert(r.second == next(m.begin(), 9));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+    {
+        typedef std::pair<M::iterator, M::iterator> R;
+        V ar[] =
+        {
+            5,
+            5,
+            5,
+            7,
+            7,
+            7,
+            9,
+            9,
+            9
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.equal_range(4);
+        assert(r.first  == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 0));
+        r = m.equal_range(5);
+        assert(r.first  == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(6);
+        assert(r.first  == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(7);
+        assert(r.first  == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(8);
+        assert(r.first  == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(9);
+        assert(r.first  == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 9));
+        r = m.equal_range(10);
+        assert(r.first  == next(m.begin(), 9));
+        assert(r.second == next(m.begin(), 9));
+    }
+    {
+        typedef std::pair<M::const_iterator, M::const_iterator> R;
+        V ar[] =
+        {
+            5,
+            5,
+            5,
+            7,
+            7,
+            7,
+            9,
+            9,
+            9
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.equal_range(4);
+        assert(r.first  == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 0));
+        r = m.equal_range(5);
+        assert(r.first  == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(6);
+        assert(r.first  == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(7);
+        assert(r.first  == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(8);
+        assert(r.first  == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(9);
+        assert(r.first  == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 9));
+        r = m.equal_range(10);
+        assert(r.first  == next(m.begin(), 9));
+        assert(r.second == next(m.begin(), 9));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    typedef std::multiset<V, std::less<>> M;
+    typedef std::pair<M::iterator, M::iterator> R;
+    V ar[] =
+    {
+        5,
+        5,
+        5,
+        7,
+        7,
+        7,
+        9,
+        9,
+        9
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.equal_range(4);
+    assert(r.first  == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 0));
+    r = m.equal_range(5);
+    assert(r.first  == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(6);
+    assert(r.first  == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(7);
+    assert(r.first  == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(8);
+    assert(r.first  == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(9);
+    assert(r.first  == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 9));
+    r = m.equal_range(10);
+    assert(r.first  == next(m.begin(), 9));
+    assert(r.second == next(m.begin(), 9));
+    }
+
+    {
+    typedef PrivateConstructor V;
+    typedef std::multiset<V, std::less<>> M;
+    typedef std::pair<M::iterator, M::iterator> R;
+
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 9 ));
+
+    R r = m.equal_range(4);
+    assert(r.first  == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 0));
+    r = m.equal_range(5);
+    assert(r.first  == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(6);
+    assert(r.first  == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(7);
+    assert(r.first  == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(8);
+    assert(r.first  == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(9);
+    assert(r.first  == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 9));
+    r = m.equal_range(10);
+    assert(r.first  == next(m.begin(), 9));
+    assert(r.second == next(m.begin(), 9));
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/erase_iter.pass.cpp b/test/containers/associative/multiset/erase_iter.pass.cpp
index 207a720..3657f52 100644
--- a/test/containers/associative/multiset/erase_iter.pass.cpp
+++ b/test/containers/associative/multiset/erase_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -96,4 +98,84 @@
         assert(i == m.begin());
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        typedef M::iterator I;
+        V ar[] =
+        {
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+            7,
+            8
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(next(m.cbegin(), 3));
+        assert(m.size() == 7);
+        assert(i == next(m.begin(), 3));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 5);
+        assert(*next(m.begin(), 4) == 6);
+        assert(*next(m.begin(), 5) == 7);
+        assert(*next(m.begin(), 6) == 8);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 6);
+        assert(i == m.begin());
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 5);
+        assert(*next(m.begin(), 3) == 6);
+        assert(*next(m.begin(), 4) == 7);
+        assert(*next(m.begin(), 5) == 8);
+
+        i = m.erase(next(m.cbegin(), 5));
+        assert(m.size() == 5);
+        assert(i == m.end());
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 5);
+        assert(*next(m.begin(), 3) == 6);
+        assert(*next(m.begin(), 4) == 7);
+
+        i = m.erase(next(m.cbegin(), 1));
+        assert(m.size() == 4);
+        assert(i == next(m.begin()));
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+        assert(*next(m.begin(), 2) == 6);
+        assert(*next(m.begin(), 3) == 7);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 3);
+        assert(i == next(m.begin(), 2));
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+        assert(*next(m.begin(), 2) == 7);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 2));
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 1);
+        assert(i == next(m.begin(), 0));
+        assert(*next(m.begin(), 0) == 5);
+
+        i = m.erase(m.cbegin());
+        assert(m.size() == 0);
+        assert(i == m.begin());
+        assert(i == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/erase_iter_iter.pass.cpp b/test/containers/associative/multiset/erase_iter_iter.pass.cpp
index 0912128..de4c878 100644
--- a/test/containers/associative/multiset/erase_iter_iter.pass.cpp
+++ b/test/containers/associative/multiset/erase_iter_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -76,4 +78,64 @@
         assert(m.size() == 0);
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        typedef M::iterator I;
+        V ar[] =
+        {
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+            7,
+            8
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(next(m.cbegin(), 5), next(m.cbegin(), 5));
+        assert(m.size() == 8);
+        assert(i == next(m.begin(), 5));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 4);
+        assert(*next(m.begin(), 4) == 5);
+        assert(*next(m.begin(), 5) == 6);
+        assert(*next(m.begin(), 6) == 7);
+        assert(*next(m.begin(), 7) == 8);
+
+        i = m.erase(next(m.cbegin(), 3), next(m.cbegin(), 4));
+        assert(m.size() == 7);
+        assert(i == next(m.begin(), 3));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 5);
+        assert(*next(m.begin(), 4) == 6);
+        assert(*next(m.begin(), 5) == 7);
+        assert(*next(m.begin(), 6) == 8);
+
+        i = m.erase(next(m.cbegin(), 2), next(m.cbegin(), 5));
+        assert(m.size() == 4);
+        assert(i == next(m.begin(), 2));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 7);
+        assert(*next(m.begin(), 3) == 8);
+
+        i = m.erase(next(m.cbegin(), 0), next(m.cbegin(), 2));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 0));
+        assert(*next(m.begin(), 0) == 7);
+        assert(*next(m.begin(), 1) == 8);
+
+        i = m.erase(m.cbegin(), m.cend());
+        assert(m.size() == 0);
+        assert(i == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/erase_key.pass.cpp b/test/containers/associative/multiset/erase_key.pass.cpp
index 20ba86d..1702329 100644
--- a/test/containers/associative/multiset/erase_key.pass.cpp
+++ b/test/containers/associative/multiset/erase_key.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -70,4 +72,58 @@
         assert(m.size() == 0);
         assert(i == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        typedef M::size_type I;
+        V ar[] =
+        {
+            3,
+            3,
+            3,
+            5,
+            5,
+            5,
+            7,
+            7,
+            7
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 9);
+        I i = m.erase(6);
+        assert(m.size() == 9);
+        assert(i == 0);
+        assert(*next(m.begin(), 0) == 3);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 5);
+        assert(*next(m.begin(), 4) == 5);
+        assert(*next(m.begin(), 5) == 5);
+        assert(*next(m.begin(), 6) == 7);
+        assert(*next(m.begin(), 7) == 7);
+        assert(*next(m.begin(), 8) == 7);
+
+        i = m.erase(5);
+        assert(m.size() == 6);
+        assert(i == 3);
+        assert(*next(m.begin(), 0) == 3);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 7);
+        assert(*next(m.begin(), 4) == 7);
+        assert(*next(m.begin(), 5) == 7);
+
+        i = m.erase(3);
+        assert(m.size() == 3);
+        assert(i == 3);
+        assert(*next(m.begin(), 0) == 7);
+        assert(*next(m.begin(), 1) == 7);
+        assert(*next(m.begin(), 2) == 7);
+
+        i = m.erase(7);
+        assert(m.size() == 0);
+        assert(i == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/find.pass.cpp b/test/containers/associative/multiset/find.pass.cpp
index f2af8f6..b4963e9 100644
--- a/test/containers/associative/multiset/find.pass.cpp
+++ b/test/containers/associative/multiset/find.pass.cpp
@@ -17,74 +17,224 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
+        typedef int V;
+        typedef std::multiset<int> M;
+        {
+            typedef M::iterator R;
+            V ar[] =
+            {
+                5,
+                6,
+                7,
+                8,
+                9,
+                10,
+                11,
+                12
+            };
+            M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.find(5);
+            assert(r == m.begin());
+            r = m.find(6);
+            assert(r == next(m.begin()));
+            r = m.find(7);
+            assert(r == next(m.begin(), 2));
+            r = m.find(8);
+            assert(r == next(m.begin(), 3));
+            r = m.find(9);
+            assert(r == next(m.begin(), 4));
+            r = m.find(10);
+            assert(r == next(m.begin(), 5));
+            r = m.find(11);
+            assert(r == next(m.begin(), 6));
+            r = m.find(12);
+            assert(r == next(m.begin(), 7));
+            r = m.find(4);
+            assert(r == next(m.begin(), 8));
+        }
+        {
+            typedef M::const_iterator R;
+            V ar[] =
+            {
+                5,
+                6,
+                7,
+                8,
+                9,
+                10,
+                11,
+                12
+            };
+            const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.find(5);
+            assert(r == m.begin());
+            r = m.find(6);
+            assert(r == next(m.begin()));
+            r = m.find(7);
+            assert(r == next(m.begin(), 2));
+            r = m.find(8);
+            assert(r == next(m.begin(), 3));
+            r = m.find(9);
+            assert(r == next(m.begin(), 4));
+            r = m.find(10);
+            assert(r == next(m.begin(), 5));
+            r = m.find(11);
+            assert(r == next(m.begin(), 6));
+            r = m.find(12);
+            assert(r == next(m.begin(), 7));
+            r = m.find(4);
+            assert(r == next(m.begin(), 8));
+        }
+    }
+#if __cplusplus >= 201103L
+    {
+        typedef int V;
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        {
+            typedef M::iterator R;
+            V ar[] =
+            {
+                5,
+                6,
+                7,
+                8,
+                9,
+                10,
+                11,
+                12
+            };
+            M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.find(5);
+            assert(r == m.begin());
+            r = m.find(6);
+            assert(r == next(m.begin()));
+            r = m.find(7);
+            assert(r == next(m.begin(), 2));
+            r = m.find(8);
+            assert(r == next(m.begin(), 3));
+            r = m.find(9);
+            assert(r == next(m.begin(), 4));
+            r = m.find(10);
+            assert(r == next(m.begin(), 5));
+            r = m.find(11);
+            assert(r == next(m.begin(), 6));
+            r = m.find(12);
+            assert(r == next(m.begin(), 7));
+            r = m.find(4);
+            assert(r == next(m.begin(), 8));
+        }
+        {
+            typedef M::const_iterator R;
+            V ar[] =
+            {
+                5,
+                6,
+                7,
+                8,
+                9,
+                10,
+                11,
+                12
+            };
+            const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.find(5);
+            assert(r == m.begin());
+            r = m.find(6);
+            assert(r == next(m.begin()));
+            r = m.find(7);
+            assert(r == next(m.begin(), 2));
+            r = m.find(8);
+            assert(r == next(m.begin(), 3));
+            r = m.find(9);
+            assert(r == next(m.begin(), 4));
+            r = m.find(10);
+            assert(r == next(m.begin(), 5));
+            r = m.find(11);
+            assert(r == next(m.begin(), 6));
+            r = m.find(12);
+            assert(r == next(m.begin(), 7));
+            r = m.find(4);
+            assert(r == next(m.begin(), 8));
+        }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
     typedef int V;
-    typedef std::multiset<int> M;
+    typedef std::multiset<V, std::less<>> M;
+    typedef M::iterator R;
+
+    V ar[] =
     {
-        typedef M::iterator R;
-        V ar[] =
-        {
-            5,
-            6,
-            7,
-            8,
-            9,
-            10,
-            11,
-            12
-        };
-        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
-        R r = m.find(5);
-        assert(r == m.begin());
-        r = m.find(6);
-        assert(r == next(m.begin()));
-        r = m.find(7);
-        assert(r == next(m.begin(), 2));
-        r = m.find(8);
-        assert(r == next(m.begin(), 3));
-        r = m.find(9);
-        assert(r == next(m.begin(), 4));
-        r = m.find(10);
-        assert(r == next(m.begin(), 5));
-        r = m.find(11);
-        assert(r == next(m.begin(), 6));
-        r = m.find(12);
-        assert(r == next(m.begin(), 7));
-        r = m.find(4);
-        assert(r == next(m.begin(), 8));
+        5,
+        6,
+        7,
+        8,
+        9,
+        10,
+        11,
+        12
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.find(5);
+    assert(r == m.begin());
+    r = m.find(6);
+    assert(r == next(m.begin()));
+    r = m.find(7);
+    assert(r == next(m.begin(), 2));
+    r = m.find(8);
+    assert(r == next(m.begin(), 3));
+    r = m.find(9);
+    assert(r == next(m.begin(), 4));
+    r = m.find(10);
+    assert(r == next(m.begin(), 5));
+    r = m.find(11);
+    assert(r == next(m.begin(), 6));
+    r = m.find(12);
+    assert(r == next(m.begin(), 7));
+    r = m.find(4);
+    assert(r == next(m.begin(), 8));
     }
+
     {
-        typedef M::const_iterator R;
-        V ar[] =
-        {
-            5,
-            6,
-            7,
-            8,
-            9,
-            10,
-            11,
-            12
-        };
-        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
-        R r = m.find(5);
-        assert(r == m.begin());
-        r = m.find(6);
-        assert(r == next(m.begin()));
-        r = m.find(7);
-        assert(r == next(m.begin(), 2));
-        r = m.find(8);
-        assert(r == next(m.begin(), 3));
-        r = m.find(9);
-        assert(r == next(m.begin(), 4));
-        r = m.find(10);
-        assert(r == next(m.begin(), 5));
-        r = m.find(11);
-        assert(r == next(m.begin(), 6));
-        r = m.find(12);
-        assert(r == next(m.begin(), 7));
-        r = m.find(4);
-        assert(r == next(m.begin(), 8));
+    typedef PrivateConstructor V;
+    typedef std::multiset<V, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 6 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 8 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 10 ));
+    m.insert ( V::make ( 11 ));
+    m.insert ( V::make ( 12 ));
+
+    R r = m.find(5);
+    assert(r == m.begin());
+    r = m.find(6);
+    assert(r == next(m.begin()));
+    r = m.find(7);
+    assert(r == next(m.begin(), 2));
+    r = m.find(8);
+    assert(r == next(m.begin(), 3));
+    r = m.find(9);
+    assert(r == next(m.begin(), 4));
+    r = m.find(10);
+    assert(r == next(m.begin(), 5));
+    r = m.find(11);
+    assert(r == next(m.begin(), 6));
+    r = m.find(12);
+    assert(r == next(m.begin(), 7));
+    r = m.find(4);
+    assert(r == next(m.begin(), 8));
     }
+#endif
 }
diff --git a/test/containers/associative/multiset/insert_cv.pass.cpp b/test/containers/associative/multiset/insert_cv.pass.cpp
index 2673ae7..57e1e98 100644
--- a/test/containers/associative/multiset/insert_cv.pass.cpp
+++ b/test/containers/associative/multiset/insert_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,30 @@
         assert(m.size() == 4);
         assert(*r == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+
+        r = m.insert(M::value_type(1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(*r == 1);
+
+        r = m.insert(M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+
+        r = m.insert(M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 4);
+        assert(*r == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/insert_initializer_list.pass.cpp b/test/containers/associative/multiset/insert_initializer_list.pass.cpp
index 4f5691b..c609d24 100644
--- a/test/containers/associative/multiset/insert_initializer_list.pass.cpp
+++ b/test/containers/associative/multiset/insert_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::multiset<int> C;
     typedef C::value_type V;
     C m = {10, 8};
@@ -34,5 +37,25 @@
     assert(*++i == V(6));
     assert(*++i == V(8));
     assert(*++i == V(10));
+    }
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if __cplusplus >= 201103L
+    {
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> C;
+    typedef C::value_type V;
+    C m = {10, 8};
+    m.insert({1, 2, 3, 4, 5, 6});
+    assert(m.size() == 8);
+    assert(distance(m.begin(), m.end()) == m.size());
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    assert(*++i == V(8));
+    assert(*++i == V(10));
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/insert_iter_cv.pass.cpp b/test/containers/associative/multiset/insert_iter_cv.pass.cpp
index 6e49862..fccc2b7 100644
--- a/test/containers/associative/multiset/insert_iter_cv.pass.cpp
+++ b/test/containers/associative/multiset/insert_iter_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,30 @@
         assert(m.size() == 4);
         assert(*r == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.cend(), M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+
+        r = m.insert(m.cend(), M::value_type(1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(*r == 1);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 4);
+        assert(*r == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/insert_iter_iter.pass.cpp b/test/containers/associative/multiset/insert_iter_iter.pass.cpp
index 231e0c5..3cfa9dd 100644
--- a/test/containers/associative/multiset/insert_iter_iter.pass.cpp
+++ b/test/containers/associative/multiset/insert_iter_iter.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -50,4 +51,35 @@
         assert(*next(m.begin(), 7) == 3);
         assert(*next(m.begin(), 8) == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3
+        };
+        M m;
+        m.insert(input_iterator<const V*>(ar),
+                 input_iterator<const V*>(ar + sizeof(ar)/sizeof(ar[0])));
+        assert(m.size() == 9);
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 1);
+        assert(*next(m.begin(), 2) == 1);
+        assert(*next(m.begin(), 3) == 2);
+        assert(*next(m.begin(), 4) == 2);
+        assert(*next(m.begin(), 5) == 2);
+        assert(*next(m.begin(), 6) == 3);
+        assert(*next(m.begin(), 7) == 3);
+        assert(*next(m.begin(), 8) == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/insert_iter_rv.pass.cpp b/test/containers/associative/multiset/insert_iter_rv.pass.cpp
index 3700dd1..f09d97d 100644
--- a/test/containers/associative/multiset/insert_iter_rv.pass.cpp
+++ b/test/containers/associative/multiset/insert_iter_rv.pass.cpp
@@ -17,6 +17,7 @@
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,30 @@
         assert(*r == 3);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.cend(), M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+
+        r = m.insert(m.cend(), M::value_type(1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(*r == 1);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 4);
+        assert(*r == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/insert_rv.pass.cpp b/test/containers/associative/multiset/insert_rv.pass.cpp
index a65b67a..e9e773c 100644
--- a/test/containers/associative/multiset/insert_rv.pass.cpp
+++ b/test/containers/associative/multiset/insert_rv.pass.cpp
@@ -17,6 +17,7 @@
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,30 @@
         assert(*r == 3);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::multiset<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+
+        r = m.insert(M::value_type(1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(*r == 1);
+
+        r = m.insert(M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+
+        r = m.insert(M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 4);
+        assert(*r == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/iterator.pass.cpp b/test/containers/associative/multiset/iterator.pass.cpp
index 1b20219..f801de7 100644
--- a/test/containers/associative/multiset/iterator.pass.cpp
+++ b/test/containers/associative/multiset/iterator.pass.cpp
@@ -29,6 +29,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -105,10 +107,106 @@
         assert(std::distance(m.cbegin(), m.cend()) == m.size());
         assert(std::distance(m.rbegin(), m.rend()) == m.size());
         assert(std::distance(m.crbegin(), m.crend()) == m.size());
-        std::multiset<int, double>::const_iterator i;
+        std::multiset<int>::const_iterator i;
         i = m.begin();
         for (int j = 1; j <= 8; ++j)
             for (int k = 0; k < 3; ++k, ++i)
                 assert(*i == j);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3,
+            4,
+            4,
+            4,
+            5,
+            5,
+            5,
+            6,
+            6,
+            6,
+            7,
+            7,
+            7,
+            8,
+            8,
+            8
+        };
+        std::multiset<int, std::less<int>, min_allocator<int>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        std::multiset<int, std::less<int>, min_allocator<int>>::iterator i;
+        i = m.begin();
+        std::multiset<int, std::less<int>, min_allocator<int>>::const_iterator k = i;
+        assert(i == k);
+        for (int j = 1; j <= 8; ++j)
+            for (int k = 0; k < 3; ++k, ++i)
+                assert(*i == j);
+    }
+    {
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3,
+            4,
+            4,
+            4,
+            5,
+            5,
+            5,
+            6,
+            6,
+            6,
+            7,
+            7,
+            7,
+            8,
+            8,
+            8
+        };
+        const std::multiset<int, std::less<int>, min_allocator<int>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.cbegin(), m.cend()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        assert(std::distance(m.crbegin(), m.crend()) == m.size());
+        std::multiset<int, std::less<int>, min_allocator<int>>::const_iterator i;
+        i = m.begin();
+        for (int j = 1; j <= 8; ++j)
+            for (int k = 0; k < 3; ++k, ++i)
+                assert(*i == j);
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::multiset<int> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/lower_bound.pass.cpp b/test/containers/associative/multiset/lower_bound.pass.cpp
index 585c341..48e297a 100644
--- a/test/containers/associative/multiset/lower_bound.pass.cpp
+++ b/test/containers/associative/multiset/lower_bound.pass.cpp
@@ -17,68 +17,207 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
+        typedef int V;
+        typedef std::multiset<int> M;
+        {
+            typedef M::iterator R;
+            V ar[] =
+            {
+                5,
+                5,
+                5,
+                7,
+                7,
+                7,
+                9,
+                9,
+                9
+            };
+            M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.lower_bound(4);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(5);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(6);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(7);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(8);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(9);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(11);
+            assert(r == next(m.begin(), 9));
+        }
+        {
+            typedef M::const_iterator R;
+            V ar[] =
+            {
+                5,
+                5,
+                5,
+                7,
+                7,
+                7,
+                9,
+                9,
+                9
+            };
+            const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.lower_bound(4);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(5);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(6);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(7);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(8);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(9);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(11);
+            assert(r == next(m.begin(), 9));
+        }
+    }
+#if __cplusplus >= 201103L
+    {
+        typedef int V;
+        typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+        {
+            typedef M::iterator R;
+            V ar[] =
+            {
+                5,
+                5,
+                5,
+                7,
+                7,
+                7,
+                9,
+                9,
+                9
+            };
+            M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.lower_bound(4);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(5);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(6);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(7);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(8);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(9);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(11);
+            assert(r == next(m.begin(), 9));
+        }
+        {
+            typedef M::const_iterator R;
+            V ar[] =
+            {
+                5,
+                5,
+                5,
+                7,
+                7,
+                7,
+                9,
+                9,
+                9
+            };
+            const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+            R r = m.lower_bound(4);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(5);
+            assert(r == next(m.begin(), 0));
+            r = m.lower_bound(6);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(7);
+            assert(r == next(m.begin(), 3));
+            r = m.lower_bound(8);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(9);
+            assert(r == next(m.begin(), 6));
+            r = m.lower_bound(11);
+            assert(r == next(m.begin(), 9));
+        }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
     typedef int V;
-    typedef std::multiset<int> M;
+    typedef std::multiset<V, std::less<>> M;
+
+    typedef M::iterator R;
+    V ar[] =
     {
-        typedef M::iterator R;
-        V ar[] =
-        {
-            5,
-            5,
-            5,
-            7,
-            7,
-            7,
-            9,
-            9,
-            9
-        };
-        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
-        R r = m.lower_bound(4);
-        assert(r == next(m.begin(), 0));
-        r = m.lower_bound(5);
-        assert(r == next(m.begin(), 0));
-        r = m.lower_bound(6);
-        assert(r == next(m.begin(), 3));
-        r = m.lower_bound(7);
-        assert(r == next(m.begin(), 3));
-        r = m.lower_bound(8);
-        assert(r == next(m.begin(), 6));
-        r = m.lower_bound(9);
-        assert(r == next(m.begin(), 6));
-        r = m.lower_bound(11);
-        assert(r == next(m.begin(), 9));
+        5,
+        5,
+        5,
+        7,
+        7,
+        7,
+        9,
+        9,
+        9
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+
+    R r = m.lower_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(5);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(7);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(11);
+    assert(r == next(m.begin(), 9));
     }
+
     {
-        typedef M::const_iterator R;
-        V ar[] =
-        {
-            5,
-            5,
-            5,
-            7,
-            7,
-            7,
-            9,
-            9,
-            9
-        };
-        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
-        R r = m.lower_bound(4);
-        assert(r == next(m.begin(), 0));
-        r = m.lower_bound(5);
-        assert(r == next(m.begin(), 0));
-        r = m.lower_bound(6);
-        assert(r == next(m.begin(), 3));
-        r = m.lower_bound(7);
-        assert(r == next(m.begin(), 3));
-        r = m.lower_bound(8);
-        assert(r == next(m.begin(), 6));
-        r = m.lower_bound(9);
-        assert(r == next(m.begin(), 6));
-        r = m.lower_bound(11);
-        assert(r == next(m.begin(), 9));
+    typedef PrivateConstructor V;
+    typedef std::multiset<V, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 9 ));
+
+    R r = m.lower_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(5);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(7);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(11);
+    assert(r == next(m.begin(), 9));
     }
+#endif
 }
diff --git a/test/containers/associative/multiset/max_size.pass.cpp b/test/containers/associative/multiset/max_size.pass.cpp
index cf3581e..a209d70 100644
--- a/test/containers/associative/multiset/max_size.pass.cpp
+++ b/test/containers/associative/multiset/max_size.pass.cpp
@@ -16,9 +16,20 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::multiset<int> M;
     M m;
     assert(m.max_size() != 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+    M m;
+    assert(m.max_size() != 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp b/test/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp
index a6834af..16ba28a 100644
--- a/test/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/associative/multiset/multiset.cons/assign_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::multiset<int> C;
     typedef C::value_type V;
     C m = {10, 8};
@@ -32,5 +35,23 @@
     assert(*++i == V(4));
     assert(*++i == V(5));
     assert(*++i == V(6));
+    }
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if __cplusplus >= 201103L
+    {
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> C;
+    typedef C::value_type V;
+    C m = {10, 8};
+    m = {1, 2, 3, 4, 5, 6};
+    assert(m.size() == 6);
+    assert(distance(m.begin(), m.end()) == 6);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.cons/default.pass.cpp b/test/containers/associative/multiset/multiset.cons/default.pass.cpp
index 72fd822..cf24bf7 100644
--- a/test/containers/associative/multiset/multiset.cons/default.pass.cpp
+++ b/test/containers/associative/multiset/multiset.cons/default.pass.cpp
@@ -16,9 +16,20 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     std::multiset<int> m;
     assert(m.empty());
     assert(m.begin() == m.end());
+    }
+#if __cplusplus >= 201103L
+    {
+    std::multiset<int, std::less<int>, min_allocator<int>> m;
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp b/test/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp
index 4ee2b4d..60e6940 100644
--- a/test/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp
+++ b/test/containers/associative/multiset/multiset.cons/initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::multiset<int> C;
     typedef C::value_type V;
     C m = {1, 2, 3, 4, 5, 6};
@@ -31,5 +34,40 @@
     assert(*++i == V(4));
     assert(*++i == V(5));
     assert(*++i == V(6));
+    }
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if __cplusplus >= 201103L
+    {
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> C;
+    typedef C::value_type V;
+    C m = {1, 2, 3, 4, 5, 6};
+    assert(m.size() == 6);
+    assert(distance(m.begin(), m.end()) == 6);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> C;
+    typedef C::value_type V;
+    min_allocator<int> a;
+    C m ({1, 2, 3, 4, 5, 6}, a);
+    assert(m.size() == 6);
+    assert(distance(m.begin(), m.end()) == 6);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    assert(m.get_allocator() == a);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp b/test/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp
index d8a3c14..3f00539 100644
--- a/test/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp
+++ b/test/containers/associative/multiset/multiset.cons/iter_iter.pass.cpp
@@ -18,9 +18,11 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef int V;
     V ar[] =
     {
@@ -47,4 +49,35 @@
     assert(*next(m.begin(), 6) == 3);
     assert(*next(m.begin(), 7) == 3);
     assert(*next(m.begin(), 8) == 3);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    V ar[] =
+    {
+        1,
+        1,
+        1,
+        2,
+        2,
+        2,
+        3,
+        3,
+        3
+    };
+    std::multiset<V, std::less<V>, min_allocator<V>> m(input_iterator<const int*>(ar),
+                  input_iterator<const int*>(ar+sizeof(ar)/sizeof(ar[0])));
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    assert(*next(m.begin(), 0) == 1);
+    assert(*next(m.begin(), 1) == 1);
+    assert(*next(m.begin(), 2) == 1);
+    assert(*next(m.begin(), 3) == 2);
+    assert(*next(m.begin(), 4) == 2);
+    assert(*next(m.begin(), 5) == 2);
+    assert(*next(m.begin(), 6) == 3);
+    assert(*next(m.begin(), 7) == 3);
+    assert(*next(m.begin(), 8) == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp b/test/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp
index a83e2ae..b6d25d6 100644
--- a/test/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp
+++ b/test/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp
@@ -55,4 +55,38 @@
     assert(*next(m.begin(), 6) == 3);
     assert(*next(m.begin(), 7) == 3);
     assert(*next(m.begin(), 8) == 3);
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    V ar[] =
+    {
+        1,
+        1,
+        1,
+        2,
+        2,
+        2,
+        3,
+        3,
+        3
+    };
+    typedef test_allocator<V> A;
+    typedef test_compare<std::less<int> > C;
+    A a;
+    std::multiset<V, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), a);
+
+    assert(m.size() == 9);
+    assert(distance(m.begin(), m.end()) == 9);
+    assert(*next(m.begin(), 0) == 1);
+    assert(*next(m.begin(), 1) == 1);
+    assert(*next(m.begin(), 2) == 1);
+    assert(*next(m.begin(), 3) == 2);
+    assert(*next(m.begin(), 4) == 2);
+    assert(*next(m.begin(), 5) == 2);
+    assert(*next(m.begin(), 6) == 3);
+    assert(*next(m.begin(), 7) == 3);
+    assert(*next(m.begin(), 8) == 3);
+    assert(m.get_allocator() == a);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.cons/move.pass.cpp b/test/containers/associative/multiset/multiset.cons/move.pass.cpp
index dee53d9..97f593b 100644
--- a/test/containers/associative/multiset/multiset.cons/move.pass.cpp
+++ b/test/containers/associative/multiset/multiset.cons/move.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -76,4 +77,43 @@
         assert(distance(mo.begin(), mo.end()) == 0);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::multiset<int, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::multiset<int, C, A> m = std::move(mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 9);
+        assert(distance(m.begin(), m.end()) == 9);
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 1);
+        assert(*next(m.begin(), 2) == 1);
+        assert(*next(m.begin(), 3) == 2);
+        assert(*next(m.begin(), 4) == 2);
+        assert(*next(m.begin(), 5) == 2);
+        assert(*next(m.begin(), 6) == 3);
+        assert(*next(m.begin(), 7) == 3);
+        assert(*next(m.begin(), 8) == 3);
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 0);
+        assert(distance(mo.begin(), mo.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.cons/move_assign.pass.cpp b/test/containers/associative/multiset/multiset.cons/move_assign.pass.cpp
index f17d29b..e02942f 100644
--- a/test/containers/associative/multiset/multiset.cons/move_assign.pass.cpp
+++ b/test/containers/associative/multiset/multiset.cons/move_assign.pass.cpp
@@ -19,6 +19,7 @@
 #include "../../../MoveOnly.h"
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -141,4 +142,45 @@
         assert(m1.empty());
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef MoveOnly V;
+        typedef test_compare<std::less<MoveOnly> > C;
+        typedef min_allocator<V> A;
+        typedef std::multiset<MoveOnly, C, A> M;
+        typedef std::move_iterator<V*> I;
+        V a1[] =
+        {
+            V(1),
+            V(1),
+            V(1),
+            V(2),
+            V(2),
+            V(2),
+            V(3),
+            V(3),
+            V(3)
+        };
+        M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A());
+        V a2[] =
+        {
+            V(1),
+            V(1),
+            V(1),
+            V(2),
+            V(2),
+            V(2),
+            V(3),
+            V(3),
+            V(3)
+        };
+        M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A());
+        M m3(C(3), A());
+        m3 = std::move(m1);
+        assert(m3 == m2);
+        assert(m3.get_allocator() == A());
+        assert(m3.key_comp() == C(5));
+        assert(m1.empty());
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/multiset.special/member_swap.pass.cpp b/test/containers/associative/multiset/multiset.special/member_swap.pass.cpp
index db6ab15..8d5b1e8 100644
--- a/test/containers/associative/multiset/multiset.special/member_swap.pass.cpp
+++ b/test/containers/associative/multiset/multiset.special/member_swap.pass.cpp
@@ -16,8 +16,11 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::multiset<int> M;
     {
@@ -104,4 +107,95 @@
         assert(m1 == m2_save);
         assert(m2 == m1_save);
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+            5,
+            6,
+            7,
+            8,
+            9,
+            10,
+            11,
+            12
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            1,
+            2,
+            3,
+            4
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            1,
+            2,
+            3,
+            4
+        };
+        V ar2[] =
+        {
+            5,
+            6,
+            7,
+            8,
+            9,
+            10,
+            11,
+            12
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/scary.pass.cpp b/test/containers/associative/multiset/scary.pass.cpp
new file mode 100644
index 0000000..f5ee327
--- /dev/null
+++ b/test/containers/associative/multiset/scary.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <set>
+
+// class set class multiset
+
+// Extension:  SCARY/N2913 iterator compatibility between set and multiset
+
+#include <set>
+
+int main()
+{
+    typedef std::set<int> M1;
+    typedef std::multiset<int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}
diff --git a/test/containers/associative/multiset/size.pass.cpp b/test/containers/associative/multiset/size.pass.cpp
index f7b1238..8129a9c 100644
--- a/test/containers/associative/multiset/size.pass.cpp
+++ b/test/containers/associative/multiset/size.pass.cpp
@@ -16,8 +16,11 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::multiset<int> M;
     M m;
     assert(m.size() == 0);
@@ -33,4 +36,24 @@
     assert(m.size() == 1);
     m.erase(m.begin());
     assert(m.size() == 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+    M m;
+    assert(m.size() == 0);
+    m.insert(M::value_type(2));
+    assert(m.size() == 1);
+    m.insert(M::value_type(1));
+    assert(m.size() == 2);
+    m.insert(M::value_type(2));
+    assert(m.size() == 3);
+    m.erase(m.begin());
+    assert(m.size() == 2);
+    m.erase(m.begin());
+    assert(m.size() == 1);
+    m.erase(m.begin());
+    assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/types.pass.cpp b/test/containers/associative/multiset/types.pass.cpp
index de5ee69..e3331cd 100644
--- a/test/containers/associative/multiset/types.pass.cpp
+++ b/test/containers/associative/multiset/types.pass.cpp
@@ -32,8 +32,11 @@
 #include <set>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     static_assert((std::is_same<std::multiset<int>::key_type, int>::value), "");
     static_assert((std::is_same<std::multiset<int>::value_type, int>::value), "");
     static_assert((std::is_same<std::multiset<int>::key_compare, std::less<int> >::value), "");
@@ -45,4 +48,20 @@
     static_assert((std::is_same<std::multiset<int>::const_pointer, const int*>::value), "");
     static_assert((std::is_same<std::multiset<int>::size_type, std::size_t>::value), "");
     static_assert((std::is_same<std::multiset<int>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#if __cplusplus >= 201103L
+    {
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::key_type, int>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::value_type, int>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::key_compare, std::less<int> >::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::value_compare, std::less<int> >::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::allocator_type, min_allocator<int>>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::reference, int&>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::const_reference, const int&>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::pointer, min_pointer<int>>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::const_pointer, min_pointer<const int>>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::size_type, std::size_t>::value), "");
+    static_assert((std::is_same<std::multiset<int, std::less<int>, min_allocator<int>>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/associative/multiset/upper_bound.pass.cpp b/test/containers/associative/multiset/upper_bound.pass.cpp
index 592a3fc..932ab0b 100644
--- a/test/containers/associative/multiset/upper_bound.pass.cpp
+++ b/test/containers/associative/multiset/upper_bound.pass.cpp
@@ -17,8 +17,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::multiset<int> M;
     {
@@ -81,4 +85,138 @@
         r = m.upper_bound(11);
         assert(r == next(m.begin(), 9));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::multiset<int, std::less<int>, min_allocator<int>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            5,
+            5,
+            5,
+            7,
+            7,
+            7,
+            9,
+            9,
+            9
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.upper_bound(5);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 9));
+        r = m.upper_bound(11);
+        assert(r == next(m.begin(), 9));
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            5,
+            5,
+            5,
+            7,
+            7,
+            7,
+            9,
+            9,
+            9
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.upper_bound(5);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 9));
+        r = m.upper_bound(11);
+        assert(r == next(m.begin(), 9));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    typedef std::multiset<V, std::less<>> M;
+
+    typedef M::iterator R;
+    V ar[] =
+    {
+        5,
+        5,
+        5,
+        7,
+        7,
+        7,
+        9,
+        9,
+        9
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.upper_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.upper_bound(5);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 9));
+    r = m.upper_bound(11);
+    assert(r == next(m.begin(), 9));
+    }
+
+    {
+    typedef PrivateConstructor V;
+    typedef std::multiset<V, std::less<>> M;
+
+    typedef M::iterator R;
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 9 ));
+
+    R r = m.upper_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.upper_bound(5);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 9));
+    r = m.upper_bound(11);
+    assert(r == next(m.begin(), 9));
+    }
+#endif
 }
diff --git a/test/containers/associative/set/clear.pass.cpp b/test/containers/associative/set/clear.pass.cpp
index aa632c7..c6e0102 100644
--- a/test/containers/associative/set/clear.pass.cpp
+++ b/test/containers/associative/set/clear.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -37,4 +39,25 @@
         m.clear();
         assert(m.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+            7,
+            8
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        m.clear();
+        assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/count.pass.cpp b/test/containers/associative/set/count.pass.cpp
index 4a678a1..7d7a31a 100644
--- a/test/containers/associative/set/count.pass.cpp
+++ b/test/containers/associative/set/count.pass.cpp
@@ -16,11 +16,13 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
-    typedef int V;
-    typedef std::set<int> M;
     {
+        typedef int V;
+        typedef std::set<int> M;
         typedef M::size_type R;
         V ar[] =
         {
@@ -53,4 +55,41 @@
         r = m.count(4);
         assert(r == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int V;
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef M::size_type R;
+        V ar[] =
+        {
+            5,
+            6,
+            7,
+            8,
+            9,
+            10,
+            11,
+            12
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.count(5);
+        assert(r == 1);
+        r = m.count(6);
+        assert(r == 1);
+        r = m.count(7);
+        assert(r == 1);
+        r = m.count(8);
+        assert(r == 1);
+        r = m.count(9);
+        assert(r == 1);
+        r = m.count(10);
+        assert(r == 1);
+        r = m.count(11);
+        assert(r == 1);
+        r = m.count(12);
+        assert(r == 1);
+        r = m.count(4);
+        assert(r == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/emplace.pass.cpp b/test/containers/associative/set/emplace.pass.cpp
index e322ff1..69fdbee 100644
--- a/test/containers/associative/set/emplace.pass.cpp
+++ b/test/containers/associative/set/emplace.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../Emplaceable.h"
 #include "../../DefaultOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -73,5 +74,17 @@
         assert(m.size() == 1);
         assert(*r.first == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        R r = m.emplace(M::value_type(2));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(*r.first == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/set/emplace_hint.pass.cpp b/test/containers/associative/set/emplace_hint.pass.cpp
index be5d73d..8e7fbbc 100644
--- a/test/containers/associative/set/emplace_hint.pass.cpp
+++ b/test/containers/associative/set/emplace_hint.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../Emplaceable.h"
 #include "../../DefaultOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -67,5 +68,16 @@
         assert(m.size() == 1);
         assert(*r == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.emplace_hint(m.cend(), M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/set/empty.pass.cpp b/test/containers/associative/set/empty.pass.cpp
index 615bc61..305ae39 100644
--- a/test/containers/associative/set/empty.pass.cpp
+++ b/test/containers/associative/set/empty.pass.cpp
@@ -16,8 +16,11 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::set<int> M;
     M m;
     assert(m.empty());
@@ -25,4 +28,16 @@
     assert(!m.empty());
     m.clear();
     assert(m.empty());
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    M m;
+    assert(m.empty());
+    m.insert(M::value_type(1));
+    assert(!m.empty());
+    m.clear();
+    assert(m.empty());
+    }
+#endif
 }
diff --git a/test/containers/associative/set/equal_range.pass.cpp b/test/containers/associative/set/equal_range.pass.cpp
index 7b17a47..5b83887 100644
--- a/test/containers/associative/set/equal_range.pass.cpp
+++ b/test/containers/associative/set/equal_range.pass.cpp
@@ -17,8 +17,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::set<int> M;
     {
@@ -153,4 +157,214 @@
         assert(r.first == next(m.begin(), 8));
         assert(r.second == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    typedef std::pair<M::iterator, M::iterator> R;
+    V ar[] =
+    {
+        5,
+        7,
+        9,
+        11,
+        13,
+        15,
+        17,
+        19
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.equal_range(5);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(7);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(9);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(11);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(13);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(15);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(17);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(19);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 8));
+    r = m.equal_range(4);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 0));
+    r = m.equal_range(6);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(8);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(10);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(12);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(14);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(16);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(18);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(20);
+    assert(r.first == next(m.begin(), 8));
+    assert(r.second == next(m.begin(), 8));
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    typedef std::set<V, std::less<>> M;
+    {
+        typedef std::pair<M::iterator, M::iterator> R;
+        V ar[] =
+        {
+            5,
+            7,
+            9,
+            11,
+            13,
+            15,
+            17,
+            19
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.equal_range(5);
+        assert(r.first == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 1));
+        r = m.equal_range(7);
+        assert(r.first == next(m.begin(), 1));
+        assert(r.second == next(m.begin(), 2));
+        r = m.equal_range(9);
+        assert(r.first == next(m.begin(), 2));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(11);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 4));
+        r = m.equal_range(13);
+        assert(r.first == next(m.begin(), 4));
+        assert(r.second == next(m.begin(), 5));
+        r = m.equal_range(15);
+        assert(r.first == next(m.begin(), 5));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(17);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 7));
+        r = m.equal_range(19);
+        assert(r.first == next(m.begin(), 7));
+        assert(r.second == next(m.begin(), 8));
+        r = m.equal_range(4);
+        assert(r.first == next(m.begin(), 0));
+        assert(r.second == next(m.begin(), 0));
+        r = m.equal_range(6);
+        assert(r.first == next(m.begin(), 1));
+        assert(r.second == next(m.begin(), 1));
+        r = m.equal_range(8);
+        assert(r.first == next(m.begin(), 2));
+        assert(r.second == next(m.begin(), 2));
+        r = m.equal_range(10);
+        assert(r.first == next(m.begin(), 3));
+        assert(r.second == next(m.begin(), 3));
+        r = m.equal_range(12);
+        assert(r.first == next(m.begin(), 4));
+        assert(r.second == next(m.begin(), 4));
+        r = m.equal_range(14);
+        assert(r.first == next(m.begin(), 5));
+        assert(r.second == next(m.begin(), 5));
+        r = m.equal_range(16);
+        assert(r.first == next(m.begin(), 6));
+        assert(r.second == next(m.begin(), 6));
+        r = m.equal_range(18);
+        assert(r.first == next(m.begin(), 7));
+        assert(r.second == next(m.begin(), 7));
+        r = m.equal_range(20);
+        assert(r.first == next(m.begin(), 8));
+        assert(r.second == next(m.begin(), 8));
+        }
+    }
+    {
+    typedef PrivateConstructor V;
+    typedef std::set<V, std::less<>> M;
+    typedef std::pair<M::iterator, M::iterator> R;
+
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 11 ));
+    m.insert ( V::make ( 13 ));
+    m.insert ( V::make ( 15 ));
+    m.insert ( V::make ( 17 ));
+    m.insert ( V::make ( 19 ));
+
+    R r = m.equal_range(5);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(7);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(9);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(11);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(13);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(15);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(17);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(19);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 8));
+    r = m.equal_range(4);
+    assert(r.first == next(m.begin(), 0));
+    assert(r.second == next(m.begin(), 0));
+    r = m.equal_range(6);
+    assert(r.first == next(m.begin(), 1));
+    assert(r.second == next(m.begin(), 1));
+    r = m.equal_range(8);
+    assert(r.first == next(m.begin(), 2));
+    assert(r.second == next(m.begin(), 2));
+    r = m.equal_range(10);
+    assert(r.first == next(m.begin(), 3));
+    assert(r.second == next(m.begin(), 3));
+    r = m.equal_range(12);
+    assert(r.first == next(m.begin(), 4));
+    assert(r.second == next(m.begin(), 4));
+    r = m.equal_range(14);
+    assert(r.first == next(m.begin(), 5));
+    assert(r.second == next(m.begin(), 5));
+    r = m.equal_range(16);
+    assert(r.first == next(m.begin(), 6));
+    assert(r.second == next(m.begin(), 6));
+    r = m.equal_range(18);
+    assert(r.first == next(m.begin(), 7));
+    assert(r.second == next(m.begin(), 7));
+    r = m.equal_range(20);
+    assert(r.first == next(m.begin(), 8));
+    assert(r.second == next(m.begin(), 8));
+    }
+#endif
 }
diff --git a/test/containers/associative/set/erase_iter.pass.cpp b/test/containers/associative/set/erase_iter.pass.cpp
index 949e973..f05d481 100644
--- a/test/containers/associative/set/erase_iter.pass.cpp
+++ b/test/containers/associative/set/erase_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -96,4 +98,84 @@
         assert(i == m.begin());
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        typedef M::iterator I;
+        V ar[] =
+        {
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+            7,
+            8
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(next(m.cbegin(), 3));
+        assert(m.size() == 7);
+        assert(i == next(m.begin(), 3));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 5);
+        assert(*next(m.begin(), 4) == 6);
+        assert(*next(m.begin(), 5) == 7);
+        assert(*next(m.begin(), 6) == 8);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 6);
+        assert(i == m.begin());
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 5);
+        assert(*next(m.begin(), 3) == 6);
+        assert(*next(m.begin(), 4) == 7);
+        assert(*next(m.begin(), 5) == 8);
+
+        i = m.erase(next(m.cbegin(), 5));
+        assert(m.size() == 5);
+        assert(i == m.end());
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 5);
+        assert(*next(m.begin(), 3) == 6);
+        assert(*next(m.begin(), 4) == 7);
+
+        i = m.erase(next(m.cbegin(), 1));
+        assert(m.size() == 4);
+        assert(i == next(m.begin()));
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+        assert(*next(m.begin(), 2) == 6);
+        assert(*next(m.begin(), 3) == 7);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 3);
+        assert(i == next(m.begin(), 2));
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+        assert(*next(m.begin(), 2) == 7);
+
+        i = m.erase(next(m.cbegin(), 2));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 2));
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+
+        i = m.erase(next(m.cbegin(), 0));
+        assert(m.size() == 1);
+        assert(i == next(m.begin(), 0));
+        assert(*next(m.begin(), 0) == 5);
+
+        i = m.erase(m.cbegin());
+        assert(m.size() == 0);
+        assert(i == m.begin());
+        assert(i == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/set/erase_iter_iter.pass.cpp b/test/containers/associative/set/erase_iter_iter.pass.cpp
index 283b8b5..953d1be 100644
--- a/test/containers/associative/set/erase_iter_iter.pass.cpp
+++ b/test/containers/associative/set/erase_iter_iter.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -76,4 +78,64 @@
         assert(m.size() == 0);
         assert(i == m.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        typedef M::iterator I;
+        V ar[] =
+        {
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+            7,
+            8
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(next(m.cbegin(), 5), next(m.cbegin(), 5));
+        assert(m.size() == 8);
+        assert(i == next(m.begin(), 5));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 4);
+        assert(*next(m.begin(), 4) == 5);
+        assert(*next(m.begin(), 5) == 6);
+        assert(*next(m.begin(), 6) == 7);
+        assert(*next(m.begin(), 7) == 8);
+
+        i = m.erase(next(m.cbegin(), 3), next(m.cbegin(), 4));
+        assert(m.size() == 7);
+        assert(i == next(m.begin(), 3));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 5);
+        assert(*next(m.begin(), 4) == 6);
+        assert(*next(m.begin(), 5) == 7);
+        assert(*next(m.begin(), 6) == 8);
+
+        i = m.erase(next(m.cbegin(), 2), next(m.cbegin(), 5));
+        assert(m.size() == 4);
+        assert(i == next(m.begin(), 2));
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 7);
+        assert(*next(m.begin(), 3) == 8);
+
+        i = m.erase(next(m.cbegin(), 0), next(m.cbegin(), 2));
+        assert(m.size() == 2);
+        assert(i == next(m.begin(), 0));
+        assert(*next(m.begin(), 0) == 7);
+        assert(*next(m.begin(), 1) == 8);
+
+        i = m.erase(m.cbegin(), m.cend());
+        assert(m.size() == 0);
+        assert(i == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/set/erase_key.pass.cpp b/test/containers/associative/set/erase_key.pass.cpp
index 61455b6..12ee0af 100644
--- a/test/containers/associative/set/erase_key.pass.cpp
+++ b/test/containers/associative/set/erase_key.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -107,4 +109,95 @@
         assert(m.size() == 0);
         assert(i == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        typedef M::size_type I;
+        V ar[] =
+        {
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+            7,
+            8
+        };
+        M m(ar, ar + sizeof(ar)/sizeof(ar[0]));
+        assert(m.size() == 8);
+        I i = m.erase(9);
+        assert(m.size() == 8);
+        assert(i == 0);
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 4);
+        assert(*next(m.begin(), 4) == 5);
+        assert(*next(m.begin(), 5) == 6);
+        assert(*next(m.begin(), 6) == 7);
+        assert(*next(m.begin(), 7) == 8);
+
+        i = m.erase(4);
+        assert(m.size() == 7);
+        assert(i == 1);
+        assert(*next(m.begin(), 0) == 1);
+        assert(*next(m.begin(), 1) == 2);
+        assert(*next(m.begin(), 2) == 3);
+        assert(*next(m.begin(), 3) == 5);
+        assert(*next(m.begin(), 4) == 6);
+        assert(*next(m.begin(), 5) == 7);
+        assert(*next(m.begin(), 6) == 8);
+
+        i = m.erase(1);
+        assert(m.size() == 6);
+        assert(i == 1);
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 5);
+        assert(*next(m.begin(), 3) == 6);
+        assert(*next(m.begin(), 4) == 7);
+        assert(*next(m.begin(), 5) == 8);
+
+        i = m.erase(8);
+        assert(m.size() == 5);
+        assert(i == 1);
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 3);
+        assert(*next(m.begin(), 2) == 5);
+        assert(*next(m.begin(), 3) == 6);
+        assert(*next(m.begin(), 4) == 7);
+
+        i = m.erase(3);
+        assert(m.size() == 4);
+        assert(i == 1);
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+        assert(*next(m.begin(), 2) == 6);
+        assert(*next(m.begin(), 3) == 7);
+
+        i = m.erase(6);
+        assert(m.size() == 3);
+        assert(i == 1);
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+        assert(*next(m.begin(), 2) == 7);
+
+        i = m.erase(7);
+        assert(m.size() == 2);
+        assert(i == 1);
+        assert(*next(m.begin(), 0) == 2);
+        assert(*next(m.begin(), 1) == 5);
+
+        i = m.erase(2);
+        assert(m.size() == 1);
+        assert(i == 1);
+        assert(*next(m.begin(), 0) == 5);
+
+        i = m.erase(5);
+        assert(m.size() == 0);
+        assert(i == 1);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/find.pass.cpp b/test/containers/associative/set/find.pass.cpp
index 96ab73b..6ce47f8 100644
--- a/test/containers/associative/set/find.pass.cpp
+++ b/test/containers/associative/set/find.pass.cpp
@@ -17,8 +17,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::set<int> M;
     {
@@ -87,4 +91,150 @@
         r = m.find(4);
         assert(r == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            5,
+            6,
+            7,
+            8,
+            9,
+            10,
+            11,
+            12
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.find(5);
+        assert(r == m.begin());
+        r = m.find(6);
+        assert(r == next(m.begin()));
+        r = m.find(7);
+        assert(r == next(m.begin(), 2));
+        r = m.find(8);
+        assert(r == next(m.begin(), 3));
+        r = m.find(9);
+        assert(r == next(m.begin(), 4));
+        r = m.find(10);
+        assert(r == next(m.begin(), 5));
+        r = m.find(11);
+        assert(r == next(m.begin(), 6));
+        r = m.find(12);
+        assert(r == next(m.begin(), 7));
+        r = m.find(4);
+        assert(r == next(m.begin(), 8));
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            5,
+            6,
+            7,
+            8,
+            9,
+            10,
+            11,
+            12
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.find(5);
+        assert(r == m.begin());
+        r = m.find(6);
+        assert(r == next(m.begin()));
+        r = m.find(7);
+        assert(r == next(m.begin(), 2));
+        r = m.find(8);
+        assert(r == next(m.begin(), 3));
+        r = m.find(9);
+        assert(r == next(m.begin(), 4));
+        r = m.find(10);
+        assert(r == next(m.begin(), 5));
+        r = m.find(11);
+        assert(r == next(m.begin(), 6));
+        r = m.find(12);
+        assert(r == next(m.begin(), 7));
+        r = m.find(4);
+        assert(r == next(m.begin(), 8));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    typedef std::set<V, std::less<>> M;
+    typedef M::iterator R;
+
+    V ar[] =
+    {
+        5,
+        6,
+        7,
+        8,
+        9,
+        10,
+        11,
+        12
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.find(5);
+    assert(r == m.begin());
+    r = m.find(6);
+    assert(r == next(m.begin()));
+    r = m.find(7);
+    assert(r == next(m.begin(), 2));
+    r = m.find(8);
+    assert(r == next(m.begin(), 3));
+    r = m.find(9);
+    assert(r == next(m.begin(), 4));
+    r = m.find(10);
+    assert(r == next(m.begin(), 5));
+    r = m.find(11);
+    assert(r == next(m.begin(), 6));
+    r = m.find(12);
+    assert(r == next(m.begin(), 7));
+    r = m.find(4);
+    assert(r == next(m.begin(), 8));
+    }
+
+    {
+    typedef PrivateConstructor V;
+    typedef std::set<V, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 6 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 8 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 10 ));
+    m.insert ( V::make ( 11 ));
+    m.insert ( V::make ( 12 ));
+
+    R r = m.find(5);
+    assert(r == m.begin());
+    r = m.find(6);
+    assert(r == next(m.begin()));
+    r = m.find(7);
+    assert(r == next(m.begin(), 2));
+    r = m.find(8);
+    assert(r == next(m.begin(), 3));
+    r = m.find(9);
+    assert(r == next(m.begin(), 4));
+    r = m.find(10);
+    assert(r == next(m.begin(), 5));
+    r = m.find(11);
+    assert(r == next(m.begin(), 6));
+    r = m.find(12);
+    assert(r == next(m.begin(), 7));
+    r = m.find(4);
+    assert(r == next(m.begin(), 8));
+    }
+#endif
 }
diff --git a/test/containers/associative/set/insert_cv.pass.cpp b/test/containers/associative/set/insert_cv.pass.cpp
index 9cbb616..eabd1a8 100644
--- a/test/containers/associative/set/insert_cv.pass.cpp
+++ b/test/containers/associative/set/insert_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -46,4 +48,34 @@
         assert(m.size() == 3);
         assert(*r.first == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        R r = m.insert(M::value_type(2));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(*r.first == 2);
+
+        r = m.insert(M::value_type(1));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 2);
+        assert(*r.first == 1);
+
+        r = m.insert(M::value_type(3));
+        assert(r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r.first == 3);
+
+        r = m.insert(M::value_type(3));
+        assert(!r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r.first == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/insert_initializer_list.pass.cpp b/test/containers/associative/set/insert_initializer_list.pass.cpp
index e9245cd..d75e8a8 100644
--- a/test/containers/associative/set/insert_initializer_list.pass.cpp
+++ b/test/containers/associative/set/insert_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::set<int> C;
     typedef C::value_type V;
     C m = {10, 8};
@@ -34,5 +37,25 @@
     assert(*++i == V(6));
     assert(*++i == V(8));
     assert(*++i == V(10));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::set<int, std::less<int>, min_allocator<int>> C;
+    typedef C::value_type V;
+    C m = {10, 8};
+    m.insert({1, 2, 3, 4, 5, 6});
+    assert(m.size() == 8);
+    assert(distance(m.begin(), m.end()) == m.size());
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    assert(*++i == V(8));
+    assert(*++i == V(10));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/set/insert_iter_cv.pass.cpp b/test/containers/associative/set/insert_iter_cv.pass.cpp
index 78ce183..d86d40e 100644
--- a/test/containers/associative/set/insert_iter_cv.pass.cpp
+++ b/test/containers/associative/set/insert_iter_cv.pass.cpp
@@ -16,6 +16,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,30 @@
         assert(m.size() == 3);
         assert(*r == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.cend(), M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+
+        r = m.insert(m.cend(), M::value_type(1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(*r == 1);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/insert_iter_iter.pass.cpp b/test/containers/associative/set/insert_iter_iter.pass.cpp
index 3bc3a61..d99dbe3 100644
--- a/test/containers/associative/set/insert_iter_iter.pass.cpp
+++ b/test/containers/associative/set/insert_iter_iter.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,29 @@
         assert(*next(m.begin()) == 2);
         assert(*next(m.begin(), 2) == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<int, std::less<int>, min_allocator<int>> M;
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3
+        };
+        M m;
+        m.insert(input_iterator<const V*>(ar),
+                 input_iterator<const V*>(ar + sizeof(ar)/sizeof(ar[0])));
+        assert(m.size() == 3);
+        assert(*m.begin() == 1);
+        assert(*next(m.begin()) == 2);
+        assert(*next(m.begin(), 2) == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/insert_iter_rv.pass.cpp b/test/containers/associative/set/insert_iter_rv.pass.cpp
index fdf9f05..cf2dcbf 100644
--- a/test/containers/associative/set/insert_iter_rv.pass.cpp
+++ b/test/containers/associative/set/insert_iter_rv.pass.cpp
@@ -17,6 +17,7 @@
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -45,5 +46,31 @@
         assert(m.size() == 3);
         assert(*r == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M;
+        typedef M::iterator R;
+        M m;
+        R r = m.insert(m.cend(), M::value_type(2));
+        assert(r == m.begin());
+        assert(m.size() == 1);
+        assert(*r == 2);
+
+        r = m.insert(m.cend(), M::value_type(1));
+        assert(r == m.begin());
+        assert(m.size() == 2);
+        assert(*r == 1);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+
+        r = m.insert(m.cend(), M::value_type(3));
+        assert(r == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r == 3);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/set/insert_rv.pass.cpp b/test/containers/associative/set/insert_rv.pass.cpp
index c7e868d..0b58af6 100644
--- a/test/containers/associative/set/insert_rv.pass.cpp
+++ b/test/containers/associative/set/insert_rv.pass.cpp
@@ -17,6 +17,7 @@
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -49,5 +50,35 @@
         assert(m.size() == 3);
         assert(*r.first == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::set<MoveOnly, std::less<MoveOnly>, min_allocator<MoveOnly>> M;
+        typedef std::pair<M::iterator, bool> R;
+        M m;
+        R r = m.insert(M::value_type(2));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 1);
+        assert(*r.first == 2);
+
+        r = m.insert(M::value_type(1));
+        assert(r.second);
+        assert(r.first == m.begin());
+        assert(m.size() == 2);
+        assert(*r.first == 1);
+
+        r = m.insert(M::value_type(3));
+        assert(r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r.first == 3);
+
+        r = m.insert(M::value_type(3));
+        assert(!r.second);
+        assert(r.first == prev(m.end()));
+        assert(m.size() == 3);
+        assert(*r.first == 3);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/set/iterator.pass.cpp b/test/containers/associative/set/iterator.pass.cpp
index eb40195..f52e845 100644
--- a/test/containers/associative/set/iterator.pass.cpp
+++ b/test/containers/associative/set/iterator.pass.cpp
@@ -29,6 +29,8 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -104,9 +106,103 @@
         assert(std::distance(m.cbegin(), m.cend()) == m.size());
         assert(std::distance(m.rbegin(), m.rend()) == m.size());
         assert(std::distance(m.crbegin(), m.crend()) == m.size());
-        std::set<int, double>::const_iterator i;
+        std::set<int>::const_iterator i;
         i = m.begin();
         for (int j = 1; j <= m.size(); ++j, ++i)
             assert(*i == j);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3,
+            4,
+            4,
+            4,
+            5,
+            5,
+            5,
+            6,
+            6,
+            6,
+            7,
+            7,
+            7,
+            8,
+            8,
+            8
+        };
+        std::set<int, std::less<int>, min_allocator<int>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        std::set<int, std::less<int>, min_allocator<int>>::iterator i;
+        i = m.begin();
+        std::set<int, std::less<int>, min_allocator<int>>::const_iterator k = i;
+        assert(i == k);
+        for (int j = 1; j <= m.size(); ++j, ++i)
+            assert(*i == j);
+    }
+    {
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3,
+            4,
+            4,
+            4,
+            5,
+            5,
+            5,
+            6,
+            6,
+            6,
+            7,
+            7,
+            7,
+            8,
+            8,
+            8
+        };
+        const std::set<int, std::less<int>, min_allocator<int>> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        assert(std::distance(m.begin(), m.end()) == m.size());
+        assert(std::distance(m.cbegin(), m.cend()) == m.size());
+        assert(std::distance(m.rbegin(), m.rend()) == m.size());
+        assert(std::distance(m.crbegin(), m.crend()) == m.size());
+        std::set<int, std::less<int>, min_allocator<int>>::const_iterator i;
+        i = m.begin();
+        for (int j = 1; j <= m.size(); ++j, ++i)
+            assert(*i == j);
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::set<int> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/associative/set/lower_bound.pass.cpp b/test/containers/associative/set/lower_bound.pass.cpp
index 8703c8a..1562dfa 100644
--- a/test/containers/associative/set/lower_bound.pass.cpp
+++ b/test/containers/associative/set/lower_bound.pass.cpp
@@ -17,8 +17,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::set<int> M;
     {
@@ -119,4 +123,215 @@
         r = m.lower_bound(20);
         assert(r == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            5,
+            7,
+            9,
+            11,
+            13,
+            15,
+            17,
+            19
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.lower_bound(5);
+        assert(r == m.begin());
+        r = m.lower_bound(7);
+        assert(r == next(m.begin()));
+        r = m.lower_bound(9);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(11);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(13);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(15);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(17);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(19);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.lower_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.lower_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            5,
+            7,
+            9,
+            11,
+            13,
+            15,
+            17,
+            19
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.lower_bound(5);
+        assert(r == m.begin());
+        r = m.lower_bound(7);
+        assert(r == next(m.begin()));
+        r = m.lower_bound(9);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(11);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(13);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(15);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(17);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(19);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.lower_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.lower_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.lower_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.lower_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.lower_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.lower_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.lower_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.lower_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    typedef std::set<V, std::less<>> M;
+    typedef M::iterator R;
+
+    V ar[] =
+    {
+        5,
+        7,
+        9,
+        11,
+        13,
+        15,
+        17,
+        19
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.lower_bound(5);
+    assert(r == m.begin());
+    r = m.lower_bound(7);
+    assert(r == next(m.begin()));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(11);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(13);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(15);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(17);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(19);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+    
+    {
+    typedef PrivateConstructor V;
+    typedef std::set<V, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 11 ));
+    m.insert ( V::make ( 13 ));
+    m.insert ( V::make ( 15 ));
+    m.insert ( V::make ( 17 ));
+    m.insert ( V::make ( 19 ));
+
+    R r = m.lower_bound(5);
+    assert(r == m.begin());
+    r = m.lower_bound(7);
+    assert(r == next(m.begin()));
+    r = m.lower_bound(9);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(11);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(13);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(15);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(17);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(19);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.lower_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.lower_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.lower_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.lower_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.lower_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.lower_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.lower_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.lower_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+#endif
+
 }
diff --git a/test/containers/associative/set/max_size.pass.cpp b/test/containers/associative/set/max_size.pass.cpp
index 493c785..b744b9e 100644
--- a/test/containers/associative/set/max_size.pass.cpp
+++ b/test/containers/associative/set/max_size.pass.cpp
@@ -16,9 +16,20 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::set<int> M;
     M m;
     assert(m.max_size() != 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    M m;
+    assert(m.max_size() != 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/set.cons/assign_initializer_list.pass.cpp b/test/containers/associative/set/set.cons/assign_initializer_list.pass.cpp
index b37e0d4..26f38e9 100644
--- a/test/containers/associative/set/set.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/associative/set/set.cons/assign_initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::set<int> C;
     typedef C::value_type V;
     C m = {10, 8};
@@ -32,5 +35,23 @@
     assert(*++i == V(4));
     assert(*++i == V(5));
     assert(*++i == V(6));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::set<int, std::less<int>, min_allocator<int>> C;
+    typedef C::value_type V;
+    C m = {10, 8};
+    m = {1, 2, 3, 4, 5, 6};
+    assert(m.size() == 6);
+    assert(distance(m.begin(), m.end()) == 6);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/set/set.cons/default.pass.cpp b/test/containers/associative/set/set.cons/default.pass.cpp
index 955a0d3..300b4fc 100644
--- a/test/containers/associative/set/set.cons/default.pass.cpp
+++ b/test/containers/associative/set/set.cons/default.pass.cpp
@@ -16,9 +16,20 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     std::set<int> m;
     assert(m.empty());
     assert(m.begin() == m.end());
+    }
+#if __cplusplus >= 201103L
+    {
+    std::set<int, std::less<int>, min_allocator<int>> m;
+    assert(m.empty());
+    assert(m.begin() == m.end());
+    }
+#endif
 }
diff --git a/test/containers/associative/set/set.cons/initializer_list.pass.cpp b/test/containers/associative/set/set.cons/initializer_list.pass.cpp
index badb107..7d981a1 100644
--- a/test/containers/associative/set/set.cons/initializer_list.pass.cpp
+++ b/test/containers/associative/set/set.cons/initializer_list.pass.cpp
@@ -16,9 +16,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef std::set<int> C;
     typedef C::value_type V;
     C m = {1, 2, 3, 4, 5, 6};
@@ -31,5 +34,22 @@
     assert(*++i == V(4));
     assert(*++i == V(5));
     assert(*++i == V(6));
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::set<int, std::less<int>, min_allocator<int>> C;
+    typedef C::value_type V;
+    C m = {1, 2, 3, 4, 5, 6};
+    assert(m.size() == 6);
+    assert(distance(m.begin(), m.end()) == 6);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/set/set.cons/initializer_list_compare_alloc.pass.cpp b/test/containers/associative/set/set.cons/initializer_list_compare_alloc.pass.cpp
index c180915..d4021ac 100644
--- a/test/containers/associative/set/set.cons/initializer_list_compare_alloc.pass.cpp
+++ b/test/containers/associative/set/set.cons/initializer_list_compare_alloc.pass.cpp
@@ -12,6 +12,7 @@
 // class set
 
 // set(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
+// set(initializer_list<value_type> il, const allocator_type& a);
 
 #include <set>
 #include <cassert>
@@ -21,6 +22,7 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     typedef test_compare<std::less<int> > Cmp;
     typedef test_allocator<int> A;
     typedef std::set<int, Cmp, A> C;
@@ -37,5 +39,25 @@
     assert(*++i == V(6));
     assert(m.key_comp() == Cmp(10));
     assert(m.get_allocator() == A(4));
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef test_compare<std::less<int> > Cmp;
+    typedef test_allocator<int> A;
+    typedef std::set<int, Cmp, A> C;
+    typedef C::value_type V;
+    C m({1, 2, 3, 4, 5, 6}, A(4));
+    assert(m.size() == 6);
+    assert(distance(m.begin(), m.end()) == 6);
+    C::const_iterator i = m.cbegin();
+    assert(*i == V(1));
+    assert(*++i == V(2));
+    assert(*++i == V(3));
+    assert(*++i == V(4));
+    assert(*++i == V(5));
+    assert(*++i == V(6));
+    assert(m.get_allocator() == A(4));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/associative/set/set.cons/iter_iter.pass.cpp b/test/containers/associative/set/set.cons/iter_iter.pass.cpp
index ff06850..3248257 100644
--- a/test/containers/associative/set/set.cons/iter_iter.pass.cpp
+++ b/test/containers/associative/set/set.cons/iter_iter.pass.cpp
@@ -18,9 +18,11 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
+    {
     typedef int V;
     V ar[] =
     {
@@ -41,4 +43,29 @@
     assert(*m.begin() == 1);
     assert(*next(m.begin()) == 2);
     assert(*next(m.begin(), 2) == 3);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    V ar[] =
+    {
+        1,
+        1,
+        1,
+        2,
+        2,
+        2,
+        3,
+        3,
+        3
+    };
+    std::set<V, std::less<int>, min_allocator<int>> m(input_iterator<const int*>(ar),
+                  input_iterator<const int*>(ar+sizeof(ar)/sizeof(ar[0])));
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == 1);
+    assert(*next(m.begin()) == 2);
+    assert(*next(m.begin(), 2) == 3);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp b/test/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp
index 9b4992b..1ae4634 100644
--- a/test/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp
+++ b/test/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp
@@ -14,6 +14,10 @@
 // template <class InputIterator>
 //     set(InputIterator first, InputIterator last,
 //         const value_compare& comp, const allocator_type& a);
+//
+// template <class InputIterator>
+//     set(InputIterator first, InputIterator last,
+//         const allocator_type& a);
 
 #include <set>
 #include <cassert>
@@ -49,4 +53,32 @@
     assert(*m.begin() == 1);
     assert(*next(m.begin()) == 2);
     assert(*next(m.begin(), 2) == 3);
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    V ar[] =
+    {
+        1,
+        1,
+        1,
+        2,
+        2,
+        2,
+        3,
+        3,
+        3
+    };
+    typedef test_allocator<V> A;
+    typedef test_compare<std::less<int> > C;
+    A a(7);
+    std::set<V, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0]), a);
+
+    assert(m.size() == 3);
+    assert(distance(m.begin(), m.end()) == 3);
+    assert(*m.begin() == 1);
+    assert(*next(m.begin()) == 2);
+    assert(*next(m.begin(), 2) == 3);
+    assert(m.get_allocator() == a);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/set.cons/move.pass.cpp b/test/containers/associative/set/set.cons/move.pass.cpp
index 350513a..2d1b37f 100644
--- a/test/containers/associative/set/set.cons/move.pass.cpp
+++ b/test/containers/associative/set/set.cons/move.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -69,5 +70,38 @@
         assert(mo.size() == 0);
         assert(distance(mo.begin(), mo.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int V;
+        V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3
+        };
+        typedef test_compare<std::less<int> > C;
+        typedef min_allocator<V> A;
+        std::set<int, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
+        std::set<int, C, A> m = std::move(mo);
+        assert(m.get_allocator() == A());
+        assert(m.key_comp() == C(5));
+        assert(m.size() == 3);
+        assert(distance(m.begin(), m.end()) == 3);
+        assert(*m.begin() == 1);
+        assert(*next(m.begin()) == 2);
+        assert(*next(m.begin(), 2) == 3);
+
+        assert(mo.get_allocator() == A());
+        assert(mo.key_comp() == C(5));
+        assert(mo.size() == 0);
+        assert(distance(mo.begin(), mo.end()) == 0);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/set/set.cons/move_assign.pass.cpp b/test/containers/associative/set/set.cons/move_assign.pass.cpp
index 15bcb6d..3e82e28 100644
--- a/test/containers/associative/set/set.cons/move_assign.pass.cpp
+++ b/test/containers/associative/set/set.cons/move_assign.pass.cpp
@@ -19,6 +19,7 @@
 #include "../../../MoveOnly.h"
 #include "../../../test_compare.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -140,5 +141,46 @@
         assert(m3.key_comp() == C(5));
         assert(m1.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef MoveOnly V;
+        typedef test_compare<std::less<MoveOnly> > C;
+        typedef min_allocator<V> A;
+        typedef std::set<MoveOnly, C, A> M;
+        typedef std::move_iterator<V*> I;
+        V a1[] =
+        {
+            V(1),
+            V(1),
+            V(1),
+            V(2),
+            V(2),
+            V(2),
+            V(3),
+            V(3),
+            V(3)
+        };
+        M m1(I(a1), I(a1+sizeof(a1)/sizeof(a1[0])), C(5), A());
+        V a2[] =
+        {
+            V(1),
+            V(1),
+            V(1),
+            V(2),
+            V(2),
+            V(2),
+            V(3),
+            V(3),
+            V(3)
+        };
+        M m2(I(a2), I(a2+sizeof(a2)/sizeof(a2[0])), C(5), A());
+        M m3(C(3), A());
+        m3 = std::move(m1);
+        assert(m3 == m2);
+        assert(m3.get_allocator() == A());
+        assert(m3.key_comp() == C(5));
+        assert(m1.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/associative/set/set.special/member_swap.pass.cpp b/test/containers/associative/set/set.special/member_swap.pass.cpp
index 0ac2837..aa38fe0 100644
--- a/test/containers/associative/set/set.special/member_swap.pass.cpp
+++ b/test/containers/associative/set/set.special/member_swap.pass.cpp
@@ -16,8 +16,11 @@
 #include <set>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::set<int> M;
     {
@@ -104,4 +107,95 @@
         assert(m1 == m2_save);
         assert(m2 == m1_save);
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+        };
+        V ar2[] =
+        {
+            5,
+            6,
+            7,
+            8,
+            9,
+            10,
+            11,
+            12
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            1,
+            2,
+            3,
+            4
+        };
+        V ar2[] =
+        {
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    {
+        V ar1[] =
+        {
+            1,
+            2,
+            3,
+            4
+        };
+        V ar2[] =
+        {
+            5,
+            6,
+            7,
+            8,
+            9,
+            10,
+            11,
+            12
+        };
+        M m1(ar1, ar1+sizeof(ar1)/sizeof(ar1[0]));
+        M m2(ar2, ar2+sizeof(ar2)/sizeof(ar2[0]));
+        M m1_save = m1;
+        M m2_save = m2;
+        m1.swap(m2);
+        assert(m1 == m2_save);
+        assert(m2 == m1_save);
+    }
+    }
+#endif
 }
diff --git a/test/containers/associative/set/size.pass.cpp b/test/containers/associative/set/size.pass.cpp
index e208303..e1b6b6c 100644
--- a/test/containers/associative/set/size.pass.cpp
+++ b/test/containers/associative/set/size.pass.cpp
@@ -16,8 +16,11 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::set<int> M;
     M m;
     assert(m.size() == 0);
@@ -33,4 +36,24 @@
     assert(m.size() == 1);
     m.erase(m.begin());
     assert(m.size() == 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    M m;
+    assert(m.size() == 0);
+    m.insert(M::value_type(2));
+    assert(m.size() == 1);
+    m.insert(M::value_type(1));
+    assert(m.size() == 2);
+    m.insert(M::value_type(3));
+    assert(m.size() == 3);
+    m.erase(m.begin());
+    assert(m.size() == 2);
+    m.erase(m.begin());
+    assert(m.size() == 1);
+    m.erase(m.begin());
+    assert(m.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/associative/set/types.pass.cpp b/test/containers/associative/set/types.pass.cpp
index 5a6b2c3..04b9ead 100644
--- a/test/containers/associative/set/types.pass.cpp
+++ b/test/containers/associative/set/types.pass.cpp
@@ -32,8 +32,11 @@
 #include <set>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     static_assert((std::is_same<std::set<int>::key_type, int>::value), "");
     static_assert((std::is_same<std::set<int>::value_type, int>::value), "");
     static_assert((std::is_same<std::set<int>::key_compare, std::less<int> >::value), "");
@@ -45,4 +48,20 @@
     static_assert((std::is_same<std::set<int>::const_pointer, const int*>::value), "");
     static_assert((std::is_same<std::set<int>::size_type, std::size_t>::value), "");
     static_assert((std::is_same<std::set<int>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#if __cplusplus >= 201103L
+    {
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::key_type, int>::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::value_type, int>::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::key_compare, std::less<int> >::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::value_compare, std::less<int> >::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::allocator_type, min_allocator<int> >::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::reference, int&>::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::const_reference, const int&>::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::pointer, min_pointer<int>>::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::const_pointer, min_pointer<const int>>::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::size_type, std::size_t>::value), "");
+    static_assert((std::is_same<std::set<int, std::less<int>, min_allocator<int>>::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/associative/set/upper_bound.pass.cpp b/test/containers/associative/set/upper_bound.pass.cpp
index 8f57133..5e889d2 100644
--- a/test/containers/associative/set/upper_bound.pass.cpp
+++ b/test/containers/associative/set/upper_bound.pass.cpp
@@ -17,8 +17,12 @@
 #include <set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "private_constructor.hpp"
+
 int main()
 {
+    {
     typedef int V;
     typedef std::set<int> M;
     {
@@ -119,4 +123,214 @@
         r = m.upper_bound(20);
         assert(r == next(m.begin(), 8));
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int V;
+    typedef std::set<int, std::less<int>, min_allocator<int>> M;
+    {
+        typedef M::iterator R;
+        V ar[] =
+        {
+            5,
+            7,
+            9,
+            11,
+            13,
+            15,
+            17,
+            19
+        };
+        M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(5);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(11);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(13);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(15);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(17);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(19);
+        assert(r == next(m.begin(), 8));
+        r = m.upper_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    {
+        typedef M::const_iterator R;
+        V ar[] =
+        {
+            5,
+            7,
+            9,
+            11,
+            13,
+            15,
+            17,
+            19
+        };
+        const M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        R r = m.upper_bound(5);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(7);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(9);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(11);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(13);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(15);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(17);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(19);
+        assert(r == next(m.begin(), 8));
+        r = m.upper_bound(4);
+        assert(r == next(m.begin(), 0));
+        r = m.upper_bound(6);
+        assert(r == next(m.begin(), 1));
+        r = m.upper_bound(8);
+        assert(r == next(m.begin(), 2));
+        r = m.upper_bound(10);
+        assert(r == next(m.begin(), 3));
+        r = m.upper_bound(12);
+        assert(r == next(m.begin(), 4));
+        r = m.upper_bound(14);
+        assert(r == next(m.begin(), 5));
+        r = m.upper_bound(16);
+        assert(r == next(m.begin(), 6));
+        r = m.upper_bound(18);
+        assert(r == next(m.begin(), 7));
+        r = m.upper_bound(20);
+        assert(r == next(m.begin(), 8));
+    }
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+    typedef int V;
+    typedef std::set<V, std::less<>> M;
+    typedef M::iterator R;
+
+    V ar[] =
+    {
+        5,
+        7,
+        9,
+        11,
+        13,
+        15,
+        17,
+        19
+    };
+    M m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+    R r = m.upper_bound(5);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(11);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(13);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(15);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(17);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(19);
+    assert(r == next(m.begin(), 8));
+    r = m.upper_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+    
+    {
+    typedef PrivateConstructor V;
+    typedef std::set<V, std::less<>> M;
+    typedef M::iterator R;
+
+    M m;
+    m.insert ( V::make ( 5 ));
+    m.insert ( V::make ( 7 ));
+    m.insert ( V::make ( 9 ));
+    m.insert ( V::make ( 11 ));
+    m.insert ( V::make ( 13 ));
+    m.insert ( V::make ( 15 ));
+    m.insert ( V::make ( 17 ));
+    m.insert ( V::make ( 19 ));
+
+    R r = m.upper_bound(5);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(7);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(9);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(11);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(13);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(15);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(17);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(19);
+    assert(r == next(m.begin(), 8));
+    r = m.upper_bound(4);
+    assert(r == next(m.begin(), 0));
+    r = m.upper_bound(6);
+    assert(r == next(m.begin(), 1));
+    r = m.upper_bound(8);
+    assert(r == next(m.begin(), 2));
+    r = m.upper_bound(10);
+    assert(r == next(m.begin(), 3));
+    r = m.upper_bound(12);
+    assert(r == next(m.begin(), 4));
+    r = m.upper_bound(14);
+    assert(r == next(m.begin(), 5));
+    r = m.upper_bound(16);
+    assert(r == next(m.begin(), 6));
+    r = m.upper_bound(18);
+    assert(r == next(m.begin(), 7));
+    r = m.upper_bound(20);
+    assert(r == next(m.begin(), 8));
+    }
+#endif
 }
diff --git a/test/containers/min_allocator.h b/test/containers/min_allocator.h
new file mode 100644
index 0000000..c0d28e5
--- /dev/null
+++ b/test/containers/min_allocator.h
@@ -0,0 +1,252 @@
+#ifndef MIN_ALLOCATOR_H
+#define MIN_ALLOCATOR_H
+
+#if __cplusplus >= 201103L
+
+#include <memory>
+
+template <class T> class min_pointer;
+template <class T> class min_pointer<const T>;
+template <> class min_pointer<void>;
+template <> class min_pointer<const void>;
+template <class T> class min_allocator;
+
+template <>
+class min_pointer<const void>
+{
+    const void* ptr_;
+public:
+    min_pointer() noexcept = default;
+    min_pointer(std::nullptr_t) : ptr_(nullptr) {}
+    template <class T>
+    min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
+
+    explicit operator bool() const {return ptr_ != nullptr;}
+
+    friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+    friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+    template <class U> friend class min_pointer;
+};
+
+template <>
+class min_pointer<void>
+{
+    void* ptr_;
+public:
+    min_pointer() noexcept = default;
+    min_pointer(std::nullptr_t) : ptr_(nullptr) {}
+    template <class T,
+              class = typename std::enable_if
+                       <
+                            !std::is_const<T>::value
+                       >::type
+             >
+    min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
+
+    explicit operator bool() const {return ptr_ != nullptr;}
+
+    friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+    friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+    template <class U> friend class min_pointer;
+};
+
+template <class T>
+class min_pointer
+{
+    T* ptr_;
+
+    explicit min_pointer(T* p) : ptr_(p) {}
+public:
+    min_pointer() noexcept = default;
+    min_pointer(std::nullptr_t) : ptr_(nullptr) {}
+    explicit min_pointer(min_pointer<void> p) : ptr_(static_cast<T*>(p.ptr_)) {}
+
+    explicit operator bool() const {return ptr_ != nullptr;}
+    
+    typedef std::ptrdiff_t difference_type;
+    typedef T& reference;
+    typedef T* pointer;
+    typedef T value_type;
+    typedef std::random_access_iterator_tag iterator_category;
+
+    reference operator*() const {return *ptr_;}
+    pointer operator->() const {return ptr_;}
+
+    min_pointer& operator++() {++ptr_; return *this;}
+    min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
+
+    min_pointer& operator--() {--ptr_; return *this;}
+    min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
+
+    min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
+    min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
+
+    min_pointer operator+(difference_type n) const
+    {
+        min_pointer tmp(*this);
+        tmp += n;
+        return tmp;
+    }
+
+    friend min_pointer operator+(difference_type n, min_pointer x)
+    {
+        return x + n;
+    }
+
+    min_pointer operator-(difference_type n) const
+    {
+        min_pointer tmp(*this);
+        tmp -= n;
+        return tmp;
+    }
+
+    friend difference_type operator-(min_pointer x, min_pointer y)
+    {
+        return x.ptr_ - y.ptr_;
+    }
+
+    reference operator[](difference_type n) const {return ptr_[n];}
+
+    friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
+    friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
+    friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
+    friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
+
+    static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));}
+
+    friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+    friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+    template <class U> friend class min_pointer;
+    template <class U> friend class min_allocator;
+};
+
+template <class T>
+class min_pointer<const T>
+{
+    const T* ptr_;
+
+    explicit min_pointer(const T* p) : ptr_(p) {}
+public:
+    min_pointer() noexcept = default;
+    min_pointer(std::nullptr_t) : ptr_(nullptr) {}
+    min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
+    explicit min_pointer(min_pointer<const void> p) : ptr_(static_cast<const T*>(p.ptr_)) {}
+
+    explicit operator bool() const {return ptr_ != nullptr;}
+
+    typedef std::ptrdiff_t difference_type;
+    typedef const T& reference;
+    typedef const T* pointer;
+    typedef const T value_type;
+    typedef std::random_access_iterator_tag iterator_category;
+
+    reference operator*() const {return *ptr_;}
+    pointer operator->() const {return ptr_;}
+
+    min_pointer& operator++() {++ptr_; return *this;}
+    min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
+
+    min_pointer& operator--() {--ptr_; return *this;}
+    min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
+
+    min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
+    min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
+
+    min_pointer operator+(difference_type n) const
+    {
+        min_pointer tmp(*this);
+        tmp += n;
+        return tmp;
+    }
+
+    friend min_pointer operator+(difference_type n, min_pointer x)
+    {
+        return x + n;
+    }
+
+    min_pointer operator-(difference_type n) const
+    {
+        min_pointer tmp(*this);
+        tmp -= n;
+        return tmp;
+    }
+
+    friend difference_type operator-(min_pointer x, min_pointer y)
+    {
+        return x.ptr_ - y.ptr_;
+    }
+
+    reference operator[](difference_type n) const {return ptr_[n];}
+
+    friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
+    friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
+    friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
+    friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
+
+    static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));}
+
+    friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
+    friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
+    template <class U> friend class min_pointer;
+};
+
+template <class T>
+inline
+bool
+operator==(min_pointer<T> x, std::nullptr_t)
+{
+    return !static_cast<bool>(x);
+}
+
+template <class T>
+inline
+bool
+operator==(std::nullptr_t, min_pointer<T> x)
+{
+    return !static_cast<bool>(x);
+}
+
+template <class T>
+inline
+bool
+operator!=(min_pointer<T> x, std::nullptr_t)
+{
+    return static_cast<bool>(x);
+}
+
+template <class T>
+inline
+bool
+operator!=(std::nullptr_t, min_pointer<T> x)
+{
+    return static_cast<bool>(x);
+}
+
+template <class T>
+class min_allocator
+{
+public:
+    typedef T value_type;
+    typedef min_pointer<T> pointer;
+
+    min_allocator() = default;
+    template <class U>
+    min_allocator(min_allocator<U>) {}
+
+    pointer allocate(std::ptrdiff_t n)
+    {
+        return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
+    }
+
+    void deallocate(pointer p, std::ptrdiff_t)
+    {
+        return ::operator delete(p.ptr_);
+    }
+
+    friend bool operator==(min_allocator, min_allocator) {return true;}
+    friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);}
+};
+
+#endif  // __cplusplus >= 201103L
+
+#endif  // MIN_ALLOCATOR_H
diff --git a/test/containers/sequences/array/array.size/size.pass.cpp b/test/containers/sequences/array/array.size/size.pass.cpp
index 4078fd5..fe5a0d5 100644
--- a/test/containers/sequences/array/array.size/size.pass.cpp
+++ b/test/containers/sequences/array/array.size/size.pass.cpp
@@ -21,12 +21,16 @@
         typedef std::array<T, 3> C;
         C c = {1, 2, 3.5};
         assert(c.size() == 3);
+        assert(c.max_size() == 3);
+        assert(!c.empty());
     }
     {
         typedef double T;
         typedef std::array<T, 0> C;
         C c = {};
         assert(c.size() == 0);
+        assert(c.max_size() == 0);
+        assert(c.empty());
     }
 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
     {
@@ -34,12 +38,16 @@
         typedef std::array<T, 3> C;
         constexpr C c = {1, 2, 3.5};
         static_assert(c.size() == 3, "");
+        static_assert(c.max_size() == 3, "");
+        static_assert(!c.empty(), "");
     }
     {
         typedef double T;
         typedef std::array<T, 0> C;
         constexpr C c = {};
         static_assert(c.size() == 0, "");
+        static_assert(c.max_size() == 0, "");
+        static_assert(c.empty(), "");
     }
 #endif
 }
diff --git a/test/containers/sequences/array/array.tuple/get.fail.cpp b/test/containers/sequences/array/array.tuple/get.fail.cpp
index 26aa5c7..4f4fbcf 100644
--- a/test/containers/sequences/array/array.tuple/get.fail.cpp
+++ b/test/containers/sequences/array/array.tuple/get.fail.cpp
@@ -20,6 +20,6 @@
         typedef double T;
         typedef std::array<T, 3> C;
         C c = {1, 2, 3.5};
-        std::get<3>(c) = 5.5;	// Can't get element 3!
+        std::get<3>(c) = 5.5;    // Can't get element 3!
     }
 }
diff --git a/test/containers/sequences/array/array.tuple/get.pass.cpp b/test/containers/sequences/array/array.tuple/get.pass.cpp
index 9820bab..d9e242c 100644
--- a/test/containers/sequences/array/array.tuple/get.pass.cpp
+++ b/test/containers/sequences/array/array.tuple/get.pass.cpp
@@ -14,6 +14,16 @@
 #include <array>
 #include <cassert>
 
+#if __cplusplus > 201103L
+struct S {
+   std::array<int, 3> a;
+   int k;
+   constexpr S() : a{1,2,3}, k(std::get<2>(a)) {}
+   };
+
+constexpr std::array<int, 2> getArr () { return { 3, 4 }; }
+#endif
+
 int main()
 {
     {
@@ -25,4 +35,18 @@
         assert(c[1] == 5.5);
         assert(c[2] == 3.5);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        constexpr C c = {1, 2, 3.5};
+        static_assert(std::get<0>(c) == 1, "");
+        static_assert(std::get<1>(c) == 2, "");
+        static_assert(std::get<2>(c) == 3.5, "");
+    }
+    {
+        static_assert(S().k == 3, "");
+        static_assert(std::get<1>(getArr()) == 4, "");
+    }
+#endif
 }
diff --git a/test/containers/sequences/array/array.tuple/get_const.pass.cpp b/test/containers/sequences/array/array.tuple/get_const.pass.cpp
index 6ede8f0..1cbdfa4 100644
--- a/test/containers/sequences/array/array.tuple/get_const.pass.cpp
+++ b/test/containers/sequences/array/array.tuple/get_const.pass.cpp
@@ -24,4 +24,14 @@
         assert(std::get<1>(c) == 2);
         assert(std::get<2>(c) == 3.5);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        constexpr const C c = {1, 2, 3.5};
+        static_assert(std::get<0>(c) == 1, "");
+        static_assert(std::get<1>(c) == 2, "");
+        static_assert(std::get<2>(c) == 3.5, "");
+    }
+#endif
 }
diff --git a/test/containers/sequences/array/at.pass.cpp b/test/containers/sequences/array/at.pass.cpp
new file mode 100644
index 0000000..b5cf8a5
--- /dev/null
+++ b/test/containers/sequences/array/at.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// reference operator[] (size_type)
+// const_reference operator[] (size_type); // constexpr in C++14
+// reference at (size_type)
+// const_reference at (size_type); // constexpr in C++14
+
+#include <array>
+#include <cassert>
+
+int main()
+{
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        C c = {1, 2, 3.5};
+        C::reference r1 = c.at(0);
+        assert(r1 == 1);
+        r1 = 5.5;
+        assert(c.front() == 5.5);
+        
+        C::reference r2 = c.at(2);
+        assert(r2 == 3.5);
+        r2 = 7.5;
+        assert(c.back() == 7.5);
+
+        try { (void) c.at(3); }
+        catch (const std::out_of_range &) {}
+    }
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        const C c = {1, 2, 3.5};
+        C::const_reference r1 = c.at(0);
+        assert(r1 == 1);
+        
+        C::const_reference r2 = c.at(2);
+        assert(r2 == 3.5);
+
+        try { (void) c.at(3); }
+        catch (const std::out_of_range &) {}
+    }
+    
+#if _LIBCPP_STD_VER > 11 
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        constexpr C c = {1, 2, 3.5};
+
+        constexpr T t1 = c.at(0);
+        static_assert (t1 == 1, "");
+
+        constexpr T t2 = c.at(2);
+        static_assert (t2 == 3.5, "");
+    }
+#endif
+
+}
diff --git a/test/containers/sequences/array/front_back.pass.cpp b/test/containers/sequences/array/front_back.pass.cpp
new file mode 100644
index 0000000..45a963b
--- /dev/null
+++ b/test/containers/sequences/array/front_back.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// reference front();
+// reference back();
+// const_reference front(); // constexpr in C++14
+// const_reference back(); // constexpr in C++14
+
+#include <array>
+#include <cassert>
+
+int main()
+{
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        C c = {1, 2, 3.5};
+
+        C::reference r1 = c.front();
+        assert(r1 == 1);
+        r1 = 5.5;
+        assert(c[0] == 5.5);
+        
+        C::reference r2 = c.back();
+        assert(r2 == 3.5);
+        r2 = 7.5;
+        assert(c[2] == 7.5);
+    }
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        const C c = {1, 2, 3.5};
+        C::const_reference r1 = c.front();
+        assert(r1 == 1);
+
+        C::const_reference r2 = c.back();
+        assert(r2 == 3.5);
+    }
+
+#if _LIBCPP_STD_VER > 11 
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        constexpr C c = {1, 2, 3.5};
+        
+        constexpr T t1 = c.front();
+        static_assert (t1 == 1, "");
+
+        constexpr T t2 = c.back();
+        static_assert (t2 == 3.5, "");
+    }
+#endif
+
+}
diff --git a/test/containers/sequences/array/indexing.pass.cpp b/test/containers/sequences/array/indexing.pass.cpp
new file mode 100644
index 0000000..e4dda0d
--- /dev/null
+++ b/test/containers/sequences/array/indexing.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// reference operator[] (size_type)
+// const_reference operator[] (size_type); // constexpr in C++14
+// reference at (size_type)
+// const_reference at (size_type); // constexpr in C++14
+
+#include <array>
+#include <cassert>
+
+int main()
+{
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        C c = {1, 2, 3.5};
+        C::reference r1 = c[0];
+        assert(r1 == 1);
+        r1 = 5.5;
+        assert(c.front() == 5.5);
+        
+        C::reference r2 = c[2];
+        assert(r2 == 3.5);
+        r2 = 7.5;
+        assert(c.back() == 7.5);
+    }
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        const C c = {1, 2, 3.5};
+        C::const_reference r1 = c[0];
+        assert(r1 == 1);
+        C::const_reference r2 = c[2];
+        assert(r2 == 3.5);
+    }
+    
+#if _LIBCPP_STD_VER > 11 
+    {
+        typedef double T;
+        typedef std::array<T, 3> C;
+        constexpr C c = {1, 2, 3.5};
+        
+        constexpr T t1 = c[0];
+        static_assert (t1 == 1, "");
+
+        constexpr T t2 = c[2];
+        static_assert (t2 == 3.5, "");
+    }
+#endif
+
+}
diff --git a/test/containers/sequences/array/iterators.pass.cpp b/test/containers/sequences/array/iterators.pass.cpp
new file mode 100644
index 0000000..8da3803
--- /dev/null
+++ b/test/containers/sequences/array/iterators.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// iterator, const_iterator
+
+#include <array>
+#include <iterator>
+#include <cassert>
+
+int main()
+{
+    {
+    typedef std::array<int, 5> C;
+    C c;
+    C::iterator i;
+    i = c.begin();
+    C::const_iterator j;
+    j = c.cbegin();
+    assert(i == j);
+    }
+    {
+    typedef std::array<int, 0> C;
+    C c;
+    C::iterator i;
+    i = c.begin();
+    C::const_iterator j;
+    j = c.cbegin();
+    assert(i == j);
+    }
+
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        {
+        typedef std::array<int, 5> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+
+//         C c;
+//         assert ( ii1 != c.cbegin());
+//         assert ( cii != c.begin());
+//         assert ( cii != c.cend());
+//         assert ( ii1 != c.end());
+        }
+        {
+        typedef std::array<int, 0> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+
+//         C c;
+//         assert ( ii1 != c.cbegin());
+//         assert ( cii != c.begin());
+//         assert ( cii != c.cend());
+//         assert ( ii1 != c.end());
+        }
+    }
+#endif
+}
diff --git a/test/containers/sequences/deque/deque.capacity/access.pass.cpp b/test/containers/sequences/deque/deque.capacity/access.pass.cpp
index 5fa1687..1215f95 100644
--- a/test/containers/sequences/deque/deque.capacity/access.pass.cpp
+++ b/test/containers/sequences/deque/deque.capacity/access.pass.cpp
@@ -24,7 +24,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -35,7 +38,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -48,7 +51,7 @@
 int main()
 {
     {
-        std::deque<int> c = make(10);
+        std::deque<int> c = make<std::deque<int> >(10);
         for (unsigned i = 0; i < 10; ++i)
             assert(c[i] == i);
         for (unsigned i = 0; i < 10; ++i)
@@ -57,7 +60,7 @@
         assert(c.back() == 9);
     }
     {
-        const std::deque<int> c = make(10);
+        const std::deque<int> c = make<std::deque<int> >(10);
         for (unsigned i = 0; i < 10; ++i)
             assert(c[i] == i);
         for (unsigned i = 0; i < 10; ++i)
@@ -65,4 +68,24 @@
         assert(c.front() == 0);
         assert(c.back() == 9);
     }
+#if __cplusplus >= 201103L
+    {
+        std::deque<int, min_allocator<int>> c = make<std::deque<int, min_allocator<int>> >(10);
+        for (unsigned i = 0; i < 10; ++i)
+            assert(c[i] == i);
+        for (unsigned i = 0; i < 10; ++i)
+            assert(c.at(i) == i);
+        assert(c.front() == 0);
+        assert(c.back() == 9);
+    }
+    {
+        const std::deque<int, min_allocator<int>> c = make<std::deque<int, min_allocator<int>> >(10);
+        for (unsigned i = 0; i < 10; ++i)
+            assert(c[i] == i);
+        for (unsigned i = 0; i < 10; ++i)
+            assert(c.at(i) == i);
+        assert(c.front() == 0);
+        assert(c.back() == 9);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.capacity/resize_size.pass.cpp b/test/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
index 0043c60..fee4a89 100644
--- a/test/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
+++ b/test/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,11 +38,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1, int size)
+test(C& c1, int size)
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
+    typedef typename C::const_iterator CI;
     std::size_t c1_osize = c1.size();
     c1.resize(size);
     assert(c1.size() == size);
@@ -51,21 +54,33 @@
         assert(*i == 0);
 }
 
+template <class C>
 void
 testN(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
-    C c1 = make(N, start);
+    typedef typename C::const_iterator CI;
+    C c1 = make<C>(N, start);
     test(c1, M);
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
             for (int k = 0; k < N; ++k)
-                testN(rng[i], rng[j], rng[k]);
+                testN<std::deque<int> >(rng[i], rng[j], rng[k]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            for (int k = 0; k < N; ++k)
+                testN<std::deque<int, min_allocator<int>>>(rng[i], rng[j], rng[k]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp b/test/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
index fbc62e3..b05bffa 100644
--- a/test/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
+++ b/test/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,11 +38,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1, int size, int x)
+test(C& c1, int size, int x)
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
+    typedef typename C::const_iterator CI;
     std::size_t c1_osize = c1.size();
     c1.resize(size, x);
     assert(c1.size() == size);
@@ -51,21 +54,33 @@
         assert(*i == x);
 }
 
+template <class C>
 void
 testN(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
-    C c1 = make(N, start);
+    typedef typename C::const_iterator CI;
+    C c1 = make<C>(N, start);
     test(c1, M, -10);
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
             for (int k = 0; k < N; ++k)
-                testN(rng[i], rng[j], rng[k]);
+                testN<std::deque<int> >(rng[i], rng[j], rng[k]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            for (int k = 0; k < N; ++k)
+                testN<std::deque<int, min_allocator<int>>>(rng[i], rng[j], rng[k]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp b/test/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
index 8e24047..b823ace 100644
--- a/test/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
+++ b/test/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,28 +38,40 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1)
+test(C& c1)
 {
-    std::deque<int> s = c1;
+    C s = c1;
     c1.shrink_to_fit();
     assert(c1 == s);
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
-    C c1 = make(N, start);
+    typedef typename C::const_iterator CI;
+    C c1 = make<C>(N, start);
     test(c1);
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/alloc.pass.cpp b/test/containers/sequences/deque/deque.cons/alloc.pass.cpp
index 3e635b1..e23e500 100644
--- a/test/containers/sequences/deque/deque.cons/alloc.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/alloc.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../test_allocator.h"
 #include "../../../NotConstructible.h"
+#include "../../../min_allocator.h"
 
 template <class T, class Allocator>
 void
@@ -30,4 +31,8 @@
 {
     test<int>(std::allocator<int>());
     test<NotConstructible>(test_allocator<NotConstructible>(3));
+#if __cplusplus >= 201103L
+    test<int>(min_allocator<int>());
+    test<NotConstructible>(min_allocator<NotConstructible>{});
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp b/test/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp
index 9788c6f..27b8bbb 100644
--- a/test/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/assign_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <deque>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::deque<int> d;
     d.assign({3, 4, 5, 6});
     assert(d.size() == 4);
@@ -24,5 +27,17 @@
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::deque<int, min_allocator<int>> d;
+    d.assign({3, 4, 5, 6});
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp b/test/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
index da5a616..0c60d75 100644
--- a/test/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
@@ -16,8 +16,10 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -28,7 +30,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -38,8 +40,9 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1, const std::deque<int>& c2)
+test(C& c1, const C& c2)
 {
     std::size_t c1_osize = c1.size();
     c1.assign(c2.begin(), c2.end());
@@ -47,22 +50,22 @@
     assert(c1 == c2);
 }
 
+template <class C>
 void
 testN(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
-    C c1 = make(N, start);
-    C c2 = make(M);
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
+    C c1 = make<C>(N, start);
+    C c2 = make<C>(M);
     test(c1, c2);
 }
 
+template <class C>
 void
-testI(std::deque<int>& c1, const std::deque<int>& c2)
+testI(C& c1, const C& c2)
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
+    typedef typename C::const_iterator CI;
     typedef input_iterator<CI> ICI;
     std::size_t c1_osize = c1.size();
     c1.assign(ICI(c2.begin()), ICI(c2.end()));
@@ -70,24 +73,37 @@
     assert(c1 == c2);
 }
 
+template <class C>
 void
 testNI(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
-    C c1 = make(N, start);
-    C c2 = make(M);
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
+    C c1 = make<C>(N, start);
+    C c2 = make<C>(M);
     testI(c1, c2);
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
             for (int k = 0; k < N; ++k)
-                testN(rng[i], rng[j], rng[k]);
-    testNI(1500, 2000, 1000);
+                testN<std::deque<int> >(rng[i], rng[j], rng[k]);
+    testNI<std::deque<int> >(1500, 2000, 1000);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            for (int k = 0; k < N; ++k)
+                testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
+    testNI<std::deque<int, min_allocator<int>> >(1500, 2000, 1000);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp b/test/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
index b92ba13..7401f04 100644
--- a/test/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
@@ -15,8 +15,10 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -27,7 +29,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -37,11 +39,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1, int size, int v)
+test(C& c1, int size, int v)
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
+    typedef typename C::const_iterator CI;
     std::size_t c1_osize = c1.size();
     c1.assign(size, v);
     assert(c1.size() == size);
@@ -50,22 +52,34 @@
         assert(*i == v);
 }
 
+template <class C>
 void
 testN(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
-    C c1 = make(N, start);
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
+    C c1 = make<C>(N, start);
     test(c1, M, -10);
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
             for (int k = 0; k < N; ++k)
-                testN(rng[i], rng[j], rng[k]);
+                testN<std::deque<int> >(rng[i], rng[j], rng[k]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            for (int k = 0; k < N; ++k)
+                testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/copy.pass.cpp b/test/containers/sequences/deque/deque.cons/copy.pass.cpp
index b986f59..4029bcc 100644
--- a/test/containers/sequences/deque/deque.cons/copy.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/copy.pass.cpp
@@ -14,6 +14,7 @@
 #include <deque>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -44,4 +45,17 @@
         assert(v2.get_allocator() == other_allocator<int>(-2));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
+        int* an = ab + sizeof(ab)/sizeof(ab[0]);
+        test(std::deque<int, min_allocator<int>>(ab, an));
+    }
+    {
+        std::deque<int, min_allocator<int> > v(3, 2, min_allocator<int>());
+        std::deque<int, min_allocator<int> > v2 = v;
+        assert(v2 == v);
+        assert(v2.get_allocator() == v.get_allocator());
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp b/test/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp
index c5b20bf..156e011 100644
--- a/test/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/copy_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -39,4 +40,12 @@
         test(std::deque<int, other_allocator<int> >(ab, an, other_allocator<int>(3)),
                                                             other_allocator<int>(4));
     }
+#if __cplusplus >= 201103L
+    {
+        int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
+        int* an = ab + sizeof(ab)/sizeof(ab[0]);
+        test(std::deque<int, min_allocator<int> >(ab, an, min_allocator<int>()),
+                                                          min_allocator<int>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/default.pass.cpp b/test/containers/sequences/deque/deque.cons/default.pass.cpp
index 4ee40bc..910421c 100644
--- a/test/containers/sequences/deque/deque.cons/default.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/default.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../stack_allocator.h"
 #include "../../../NotConstructible.h"
+#include "../../../min_allocator.h"
 
 template <class T, class Allocator>
 void
@@ -29,4 +30,8 @@
 {
     test<int, std::allocator<int> >();
     test<NotConstructible, stack_allocator<NotConstructible, 1> >();
+#if __cplusplus >= 201103L
+    test<int, min_allocator<int> >();
+    test<NotConstructible, min_allocator<NotConstructible> >();
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/initializer_list.pass.cpp b/test/containers/sequences/deque/deque.cons/initializer_list.pass.cpp
index 2681909..537ded5 100644
--- a/test/containers/sequences/deque/deque.cons/initializer_list.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/initializer_list.pass.cpp
@@ -14,14 +14,28 @@
 #include <deque>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::deque<int> d = {3, 4, 5, 6};
     assert(d.size() == 4);
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::deque<int, min_allocator<int>> d = {3, 4, 5, 6};
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp b/test/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp
index 0b5fc02..66ee3ab 100644
--- a/test/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/initializer_list_alloc.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::deque<int, test_allocator<int>> d({3, 4, 5, 6}, test_allocator<int>(3));
     assert(d.get_allocator() == test_allocator<int>(3));
     assert(d.size() == 4);
@@ -26,5 +28,17 @@
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::deque<int, min_allocator<int>> d({3, 4, 5, 6}, min_allocator<int>());
+    assert(d.get_allocator() == min_allocator<int>());
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/deque/deque.cons/iter_iter.pass.cpp b/test/containers/sequences/deque/deque.cons/iter_iter.pass.cpp
index a43c344..1a85871 100644
--- a/test/containers/sequences/deque/deque.cons/iter_iter.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/iter_iter.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../stack_allocator.h"
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 template <class InputIterator>
 void
@@ -55,4 +56,7 @@
     test(bidirectional_iterator<const int*>(ab), bidirectional_iterator<const int*>(an));
     test(random_access_iterator<const int*>(ab), random_access_iterator<const int*>(an));
     test<stack_allocator<int, 4096> >(ab, an);
+#if __cplusplus >= 201103L
+    test<min_allocator<int> >(ab, an);
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp b/test/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp
index cfa86a9..2070f4a 100644
--- a/test/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/iter_iter_alloc.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_iterators.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class InputIterator, class Allocator>
 void
@@ -41,4 +42,10 @@
     test(forward_iterator<const int*>(ab), forward_iterator<const int*>(an), test_allocator<int>(4));
     test(bidirectional_iterator<const int*>(ab), bidirectional_iterator<const int*>(an), test_allocator<int>(5));
     test(random_access_iterator<const int*>(ab), random_access_iterator<const int*>(an), test_allocator<int>(6));
+#if __cplusplus >= 201103L
+    test(input_iterator<const int*>(ab), input_iterator<const int*>(an), min_allocator<int>());
+    test(forward_iterator<const int*>(ab), forward_iterator<const int*>(an), min_allocator<int>());
+    test(bidirectional_iterator<const int*>(ab), bidirectional_iterator<const int*>(an), min_allocator<int>());
+    test(random_access_iterator<const int*>(ab), random_access_iterator<const int*>(an), min_allocator<int>());
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/move.pass.cpp b/test/containers/sequences/deque/deque.cons/move.pass.cpp
index 67a515b..5764c61 100644
--- a/test/containers/sequences/deque/deque.cons/move.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/move.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -50,5 +51,22 @@
         assert(c1.size() == 0);
         assert(c3.get_allocator() == c1.get_allocator());
     }
+#if __cplusplus >= 201103L
+    {
+        int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
+        int* an = ab + sizeof(ab)/sizeof(ab[0]);
+        typedef min_allocator<MoveOnly> A;
+        std::deque<MoveOnly, A> c1(A{});
+        for (int* p = ab; p < an; ++p)
+            c1.push_back(MoveOnly(*p));
+        std::deque<MoveOnly, A> c2(A{});
+        for (int* p = ab; p < an; ++p)
+            c2.push_back(MoveOnly(*p));
+        std::deque<MoveOnly, A> c3 = std::move(c1);
+        assert(c2 == c3);
+        assert(c1.size() == 0);
+        assert(c3.get_allocator() == c1.get_allocator());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.cons/move_alloc.pass.cpp b/test/containers/sequences/deque/deque.cons/move_alloc.pass.cpp
index 0d6ca26..def1fc3 100644
--- a/test/containers/sequences/deque/deque.cons/move_alloc.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/move_alloc.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -65,5 +66,22 @@
         assert(c3.get_allocator() == A(3));
         assert(c1.size() != 0);
     }
+#if __cplusplus >= 201103L
+    {
+        int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
+        int* an = ab + sizeof(ab)/sizeof(ab[0]);
+        typedef min_allocator<MoveOnly> A;
+        std::deque<MoveOnly, A> c1(A{});
+        for (int* p = ab; p < an; ++p)
+            c1.push_back(MoveOnly(*p));
+        std::deque<MoveOnly, A> c2(A{});
+        for (int* p = ab; p < an; ++p)
+            c2.push_back(MoveOnly(*p));
+        std::deque<MoveOnly, A> c3(std::move(c1), A());
+        assert(c2 == c3);
+        assert(c3.get_allocator() == A());
+        assert(c1.size() == 0);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.cons/move_assign.pass.cpp b/test/containers/sequences/deque/deque.cons/move_assign.pass.cpp
index 3990af3..a9e760f 100644
--- a/test/containers/sequences/deque/deque.cons/move_assign.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/move_assign.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -68,5 +69,23 @@
         assert(c1.size() == 0);
         assert(c3.get_allocator() == A(5));
     }
+#if __cplusplus >= 201103L
+    {
+        int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
+        int* an = ab + sizeof(ab)/sizeof(ab[0]);
+        typedef min_allocator<MoveOnly> A;
+        std::deque<MoveOnly, A> c1(A{});
+        for (int* p = ab; p < an; ++p)
+            c1.push_back(MoveOnly(*p));
+        std::deque<MoveOnly, A> c2(A{});
+        for (int* p = ab; p < an; ++p)
+            c2.push_back(MoveOnly(*p));
+        std::deque<MoveOnly, A> c3(A{});
+        c3 = std::move(c1);
+        assert(c2 == c3);
+        assert(c1.size() == 0);
+        assert(c3.get_allocator() == A());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.cons/op_equal.pass.cpp b/test/containers/sequences/deque/deque.cons/op_equal.pass.cpp
index 9c7561a..bb169c1 100644
--- a/test/containers/sequences/deque/deque.cons/op_equal.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/op_equal.pass.cpp
@@ -14,6 +14,7 @@
 #include <deque>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -45,4 +46,18 @@
         assert(l2 == l);
         assert(l2.get_allocator() == other_allocator<int>(5));
     }
+#if __cplusplus >= 201103L
+    {
+        int ab[] = {3, 4, 2, 8, 0, 1, 44, 34, 45, 96, 80, 1, 13, 31, 45};
+        int* an = ab + sizeof(ab)/sizeof(ab[0]);
+        test(std::deque<int, min_allocator<int>>(ab, an));
+    }
+    {
+        std::deque<int, min_allocator<int> > l(3, 2, min_allocator<int>());
+        std::deque<int, min_allocator<int> > l2(l, min_allocator<int>());
+        l2 = l;
+        assert(l2 == l);
+        assert(l2.get_allocator() == min_allocator<int>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp b/test/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp
index 7ba826b..577b51c 100644
--- a/test/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/op_equal_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <deque>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::deque<int> d;
     d = {3, 4, 5, 6};
     assert(d.size() == 4);
@@ -24,5 +27,17 @@
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::deque<int, min_allocator<int>> d;
+    d = {3, 4, 5, 6};
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/deque/deque.cons/size.pass.cpp b/test/containers/sequences/deque/deque.cons/size.pass.cpp
index af8e8b8..1f07caf 100644
--- a/test/containers/sequences/deque/deque.cons/size.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/size.pass.cpp
@@ -16,10 +16,33 @@
 
 #include "../../../stack_allocator.h"
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 template <class T, class Allocator>
 void
-test(unsigned n)
+test2(unsigned n)
+{
+#if _LIBCPP_STD_VER > 11
+    typedef std::deque<T, Allocator> C;
+    typedef typename C::const_iterator const_iterator;
+    assert(DefaultOnly::count == 0);
+    {
+    C d(n, Allocator());
+    assert(DefaultOnly::count == n);
+    assert(d.size() == n);
+    assert(distance(d.begin(), d.end()) == d.size());
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    for (const_iterator i = d.begin(), e = d.end(); i != e; ++i)
+        assert(*i == T());
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    }
+    assert(DefaultOnly::count == 0);
+#endif
+}
+
+template <class T, class Allocator>
+void
+test1(unsigned n)
 {
     typedef std::deque<T, Allocator> C;
     typedef typename C::const_iterator const_iterator;
@@ -37,6 +60,29 @@
     assert(DefaultOnly::count == 0);
 }
 
+template <class T, class Allocator>
+void
+test3(unsigned n, Allocator const &alloc = Allocator())
+{
+#if _LIBCPP_STD_VER > 11
+    typedef std::deque<T, Allocator> C;
+    typedef typename C::const_iterator const_iterator;
+    {
+    C d(n, alloc);
+    assert(d.size() == n);
+    assert(d.get_allocator() == alloc);
+    }
+#endif
+}
+
+template <class T, class Allocator>
+void
+test(unsigned n)
+{
+    test1<T, Allocator> ( n );
+    test2<T, Allocator> ( n );
+}
+
 int main()
 {
     test<DefaultOnly, std::allocator<DefaultOnly> >(0);
@@ -51,5 +97,17 @@
     test<DefaultOnly, std::allocator<DefaultOnly> >(4095);
     test<DefaultOnly, std::allocator<DefaultOnly> >(4096);
     test<DefaultOnly, std::allocator<DefaultOnly> >(4097);
-    test<DefaultOnly, stack_allocator<DefaultOnly, 4096> >(4095);
+
+    test1<DefaultOnly, stack_allocator<DefaultOnly, 4096> >(4095);
+
+#if __cplusplus >= 201103L
+    test<DefaultOnly, min_allocator<DefaultOnly> >(4095);
+#endif
+
+#if _LIBCPP_STD_VER > 11
+    test3<DefaultOnly, std::allocator<DefaultOnly>> (1023);
+    test3<int, std::allocator<int>>(1);
+    test3<int, min_allocator<int>> (3);
+#endif
+
 }
diff --git a/test/containers/sequences/deque/deque.cons/size_value.pass.cpp b/test/containers/sequences/deque/deque.cons/size_value.pass.cpp
index 7a4df26..782c0ed 100644
--- a/test/containers/sequences/deque/deque.cons/size_value.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/size_value.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class T, class Allocator>
 void
@@ -44,4 +45,7 @@
     test<int, std::allocator<int> >(4096, 1165);
     test<int, std::allocator<int> >(4097, 157);
     test<int, stack_allocator<int, 4096> >(4095, 90);
+#if __cplusplus >= 201103L
+    test<int, min_allocator<int> >(4095, 90);
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp b/test/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp
index 49cc9b5..c61ce15 100644
--- a/test/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp
+++ b/test/containers/sequences/deque/deque.cons/size_value_alloc.pass.cpp
@@ -14,6 +14,8 @@
 #include <deque>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 template <class T, class Allocator>
 void
 test(unsigned n, const T& x, const Allocator& a)
@@ -30,6 +32,7 @@
 
 int main()
 {
+    {
     std::allocator<int> a;
     test(0, 5, a);
     test(1, 10, a);
@@ -43,4 +46,22 @@
     test(4095, 78, a);
     test(4096, 1165, a);
     test(4097, 157, a);
+    }
+#if __cplusplus >= 201103L
+    {
+    min_allocator<int> a;
+    test(0, 5, a);
+    test(1, 10, a);
+    test(10, 11, a);
+    test(1023, -11, a);
+    test(1024, 25, a);
+    test(1025, 0, a);
+    test(2047, 110, a);
+    test(2048, -500, a);
+    test(2049, 654, a);
+    test(4095, 78, a);
+    test(4096, 1165, a);
+    test(4097, 157, a);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/emplace.pass.cpp b/test/containers/sequences/deque/deque.modifiers/emplace.pass.cpp
index a829e88..d332bb4 100644
--- a/test/containers/sequences/deque/deque.modifiers/emplace.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/emplace.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-std::deque<Emplaceable>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -29,7 +31,7 @@
         init *= b;
         --init;
     }
-    std::deque<Emplaceable> c(init);
+    C c(init);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -39,12 +41,12 @@
     return c;
 };
 
+template <class C>
 void
-test(int P, std::deque<Emplaceable>& c1)
+test(int P, C& c1)
 {
-    typedef std::deque<Emplaceable> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     std::size_t c1_osize = c1.size();
     CI i = c1.emplace(c1.begin() + P, Emplaceable(1, 2.5));
     assert(i == c1.begin() + P);
@@ -53,17 +55,17 @@
     assert(*i == Emplaceable(1, 2.5));
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<Emplaceable> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i <= 3; ++i)
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1);
         }
     }
@@ -71,7 +73,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1);
         }
     }
@@ -79,7 +81,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1);
         }
     }
@@ -90,10 +92,21 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<Emplaceable> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<Emplaceable, min_allocator<Emplaceable>> >(rng[i], rng[j]);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp b/test/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp
index 633cbf9..892418e 100644
--- a/test/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/emplace_back.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-std::deque<Emplaceable>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -29,7 +31,7 @@
         init *= b;
         --init;
     }
-    std::deque<Emplaceable> c(init);
+    C c(init);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -39,11 +41,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<Emplaceable>& c1)
+test(C& c1)
 {
-    typedef std::deque<Emplaceable> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     std::size_t c1_osize = c1.size();
     c1.emplace_back(Emplaceable(1, 2.5));
     assert(c1.size() == c1_osize + 1);
@@ -52,11 +54,11 @@
     assert(*--i == Emplaceable(1, 2.5));
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<Emplaceable> C;
-    C c1 = make(N, start);
+    C c1 = make<C>(N, start);
     test(c1);
 }
 
@@ -65,10 +67,21 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<Emplaceable> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<Emplaceable, min_allocator<Emplaceable>> >(rng[i], rng[j]);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp b/test/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp
index d007734..6eebfa8 100644
--- a/test/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/emplace_front.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-std::deque<Emplaceable>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -29,7 +31,7 @@
         init *= b;
         --init;
     }
-    std::deque<Emplaceable> c(init);
+    C c(init);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -39,11 +41,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<Emplaceable>& c1)
+test(C& c1)
 {
-    typedef std::deque<Emplaceable> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     std::size_t c1_osize = c1.size();
     c1.emplace_front(Emplaceable(1, 2.5));
     assert(c1.size() == c1_osize + 1);
@@ -52,11 +54,11 @@
     assert(*i == Emplaceable(1, 2.5));
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<Emplaceable> C;
-    C c1 = make(N, start);
+    C c1 = make<C>(N, start);
     test(c1);
 }
 
@@ -65,10 +67,21 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<Emplaceable> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<Emplaceable, min_allocator<Emplaceable>> >(rng[i], rng[j]);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp b/test/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
index 1cec030..1b4da3f 100644
--- a/test/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/erase_iter.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,11 +38,11 @@
     return c;
 };
 
+template <class C>
 void
-test(int P, std::deque<int>& c1)
+test(int P, C& c1)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     assert(P < c1.size());
     std::size_t c1_osize = c1.size();
     I i = c1.erase(c1.cbegin() + P);
@@ -54,23 +57,34 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<int> C;
     int pstep = std::max(N / std::max(std::min(N, 10), 1), 1);
     for (int p = 0; p < N; p += pstep)
     {
-        C c1 = make(N, start);
+        C c1 = make<C>(N, start);
         test(p, c1);
     }
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp b/test/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp
index 20d03f2..37b6c1c 100644
--- a/test/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/erase_iter_iter.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,11 +38,11 @@
     return c;
 };
 
+template <class C>
 void
-test(int P, std::deque<int>& c1, int size)
+test(int P, C& c1, int size)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     assert(P + size <= c1.size());
     std::size_t c1_osize = c1.size();
     I i = c1.erase(c1.cbegin() + P, c1.cbegin() + (P + size));
@@ -54,17 +57,17 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<int> C;
     int pstep = std::max(N / std::max(std::min(N, 10), 1), 1);
     for (int p = 0; p <= N; p += pstep)
     {
         int sstep = std::max((N - p) / std::max(std::min(N - p, 10), 1), 1);
         for (int s = 0; s <= N - p; s += sstep)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(p, c1, s);
         }
     }
@@ -72,9 +75,20 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/insert_iter_initializer_list.pass.cpp b/test/containers/sequences/deque/deque.modifiers/insert_iter_initializer_list.pass.cpp
index 7696553..487db6b 100644
--- a/test/containers/sequences/deque/deque.modifiers/insert_iter_initializer_list.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/insert_iter_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <deque>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::deque<int> d(10, 1);
     std::deque<int>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6});
     assert(d.size() == 14);
@@ -35,5 +38,26 @@
     assert(d[11] == 1);
     assert(d[12] == 1);
     assert(d[13] == 1);
+    }
+    {
+    std::deque<int, min_allocator<int>> d(10, 1);
+    std::deque<int, min_allocator<int>>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6});
+    assert(d.size() == 14);
+    assert(i == d.begin() + 2);
+    assert(d[0] == 1);
+    assert(d[1] == 1);
+    assert(d[2] == 3);
+    assert(d[3] == 4);
+    assert(d[4] == 5);
+    assert(d[5] == 6);
+    assert(d[6] == 1);
+    assert(d[7] == 1);
+    assert(d[8] == 1);
+    assert(d[9] == 1);
+    assert(d[10] == 1);
+    assert(d[11] == 1);
+    assert(d[12] == 1);
+    assert(d[13] == 1);
+    }
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp b/test/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp
index 7132ff4..1cf507c 100644
--- a/test/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp
@@ -18,8 +18,10 @@
 #include "test_iterators.h"
 #include "../../../MoveOnly.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -30,7 +32,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -40,12 +42,12 @@
     return c;
 };
 
+template <class C>
 void
-test(int P, std::deque<int>& c1, const std::deque<int>& c2)
+test(int P, C& c1, const C& c2)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     typedef bidirectional_iterator<CI> BCI;
     std::size_t c1_osize = c1.size();
     CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end()));
@@ -61,18 +63,18 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i <= 3; ++i)
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             test(i, c1, c2);
         }
     }
@@ -80,8 +82,8 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             test(i, c1, c2);
         }
     }
@@ -89,8 +91,8 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             test(i, c1, c2);
         }
     }
@@ -98,8 +100,8 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             test(i, c1, c2);
         }
     }
@@ -107,8 +109,8 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             test(i, c1, c2);
         }
     }
@@ -116,19 +118,19 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             test(i, c1, c2);
         }
     }
 }
 
+template <class C>
 void
-testI(int P, std::deque<int>& c1, const std::deque<int>& c2)
+testI(int P, C& c1, const C& c2)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     typedef input_iterator<CI> ICI;
     std::size_t c1_osize = c1.size();
     CI i = c1.insert(c1.begin() + P, ICI(c2.begin()), ICI(c2.end()));
@@ -144,18 +146,18 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testNI(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i <= 3; ++i)
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             testI(i, c1, c2);
         }
     }
@@ -163,8 +165,8 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             testI(i, c1, c2);
         }
     }
@@ -172,8 +174,8 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             testI(i, c1, c2);
         }
     }
@@ -181,8 +183,8 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             testI(i, c1, c2);
         }
     }
@@ -190,19 +192,20 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
-            C c2 = make(M);
+            C c1 = make<C>(N, start);
+            C c2 = make<C>(M);
             testI(i, c1, c2);
         }
     }
 }
 
+template <class C>
 void
 test_move()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    std::deque<MoveOnly, stack_allocator<MoveOnly, 2000> > c;
-    typedef std::deque<MoveOnly>::const_iterator CI;
+    C c;
+    typedef typename C::const_iterator CI;
     {
         MoveOnly mo(0);
         typedef MoveOnly* I;
@@ -224,12 +227,28 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
             for (int k = 0; k < N; ++k)
-                testN(rng[i], rng[j], rng[k]);
-    testNI(1500, 2000, 1000);
-    test_move();
+                testN<std::deque<int> >(rng[i], rng[j], rng[k]);
+    testNI<std::deque<int> >(1500, 2000, 1000);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    test_move<std::deque<MoveOnly, stack_allocator<MoveOnly, 2000> > >();
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            for (int k = 0; k < N; ++k)
+                testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
+    testNI<std::deque<int> >(1500, 2000, 1000);
+    test_move<std::deque<MoveOnly, min_allocator<MoveOnly> > >();
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp b/test/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp
index 0369384..e1cac32 100644
--- a/test/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-std::deque<MoveOnly>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -29,7 +31,7 @@
         init *= b;
         --init;
     }
-    std::deque<MoveOnly> c(init);
+    C c(init);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -39,12 +41,12 @@
     return c;
 };
 
+template <class C>
 void
-test(int P, std::deque<MoveOnly>& c1, int x)
+test(int P, C& c1, int x)
 {
-    typedef std::deque<MoveOnly> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     std::size_t c1_osize = c1.size();
     CI i = c1.insert(c1.begin() + P, MoveOnly(x));
     assert(i == c1.begin() + P);
@@ -59,17 +61,17 @@
         assert(*i == MoveOnly(j));
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<MoveOnly> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i <= 3; ++i)
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, -10);
         }
     }
@@ -77,7 +79,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, -10);
         }
     }
@@ -85,7 +87,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, -10);
         }
     }
@@ -96,10 +98,21 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<MoveOnly> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<MoveOnly, min_allocator<MoveOnly>> >(rng[i], rng[j]);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp b/test/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp
index 633055c..71129bf 100644
--- a/test/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,12 +38,12 @@
     return c;
 };
 
+template <class C>
 void
-test(int P, std::deque<int>& c1, int size, int x)
+test(int P, C& c1, int size, int x)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     std::size_t c1_osize = c1.size();
     CI i = c1.insert(c1.begin() + P, size, x);
     assert(i == c1.begin() + P);
@@ -55,17 +58,17 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i <= 3; ++i)
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, M, -10);
         }
     }
@@ -73,7 +76,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, M, -10);
         }
     }
@@ -81,7 +84,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, M, -10);
         }
     }
@@ -89,7 +92,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, M, -10);
         }
     }
@@ -97,22 +100,22 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, M, -10);
         }
     }
 }
 
+template <class C>
 void
 self_reference_test()
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i < 20; ++i)
     {
         for (int j = 0; j < 20; ++j)
         {
-            C c = make(20);
+            C c = make<C>(20);
             CI it = c.cbegin() + i;
             CI jt = c.cbegin() + j;
             c.insert(it, 5, *jt);
@@ -131,11 +134,24 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
             for (int k = 0; k < N; ++k)
-                testN(rng[i], rng[j], rng[k]);
-    self_reference_test();
+                testN<std::deque<int> >(rng[i], rng[j], rng[k]);
+    self_reference_test<std::deque<int> >();
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            for (int k = 0; k < N; ++k)
+                testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
+    self_reference_test<std::deque<int, min_allocator<int>> >();
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp b/test/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp
index cc9791c..87be595 100644
--- a/test/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,12 +38,12 @@
     return c;
 };
 
+template <class C>
 void
-test(int P, std::deque<int>& c1, int x)
+test(int P, C& c1, int x)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     std::size_t c1_osize = c1.size();
     CI i = c1.insert(c1.begin() + P, x);
     assert(i == c1.begin() + P);
@@ -55,17 +58,17 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i <= 3; ++i)
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, -10);
         }
     }
@@ -73,7 +76,7 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, -10);
         }
     }
@@ -81,22 +84,22 @@
     {
         if (0 <= i && i <= N)
         {
-            C c1 = make(N, start);
+            C c1 = make<C>(N, start);
             test(i, c1, -10);
         }
     }
 }
 
+template <class C>
 void
 self_reference_test()
 {
-    typedef std::deque<int> C;
-    typedef C::const_iterator CI;
+    typedef typename C::const_iterator CI;
     for (int i = 0; i < 20; ++i)
     {
         for (int j = 0; j < 20; ++j)
         {
-            C c = make(20);
+            C c = make<C>(20);
             CI it = c.cbegin() + i;
             CI jt = c.cbegin() + j;
             c.insert(it, *jt);
@@ -115,10 +118,22 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
-    self_reference_test();
+            testN<std::deque<int> >(rng[i], rng[j]);
+    self_reference_test<std::deque<int> >();
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    self_reference_test<std::deque<int, min_allocator<int>> >();
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp b/test/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp
index 289264b..51812cf 100644
--- a/test/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/pop_back.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,11 +38,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1)
+test(C& c1)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     std::size_t c1_osize = c1.size();
     c1.pop_back();
     assert(c1.size() == c1_osize - 1);
@@ -49,22 +52,33 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
     if (N != 0)
     {
-        typedef std::deque<int> C;
-        C c1 = make(N, start);
+        C c1 = make<C>(N, start);
         test(c1);
     }
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp b/test/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp
index b359a54..17597ab 100644
--- a/test/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/pop_front.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,11 +38,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1)
+test(C& c1)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     std::size_t c1_osize = c1.size();
     c1.pop_front();
     assert(c1.size() == c1_osize - 1);
@@ -49,22 +52,33 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
     if (N != 0)
     {
-        typedef std::deque<int> C;
-        C c1 = make(N, start);
+        C c1 = make<C>(N, start);
         test(c1);
     }
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/push_back.pass.cpp b/test/containers/sequences/deque/deque.modifiers/push_back.pass.cpp
index 056ee55..cb7155a 100644
--- a/test/containers/sequences/deque/deque.modifiers/push_back.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/push_back.pass.cpp
@@ -16,7 +16,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -27,7 +30,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -37,14 +40,15 @@
     return c;
 };
 
+template <class C>
 void test(int size)
 {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int j = 0; j < N; ++j)
     {
-        std::deque<int> c = make(size, rng[j]);
-        std::deque<int>::const_iterator it = c.begin();
+        C c = make<C>(size, rng[j]);
+        typename C::const_iterator it = c.begin();
         for (int i = 0; i < size; ++i, ++it)
             assert(*it == i);
     }
@@ -52,8 +56,18 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049, 4094, 4095, 4096};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int j = 0; j < N; ++j)
-        test(rng[j]);
+        test<std::deque<int> >(rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049, 4094, 4095, 4096};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int j = 0; j < N; ++j)
+        test<std::deque<int, min_allocator<int>> >(rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp b/test/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
index d1aeee6..0aee63e 100644
--- a/test/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
@@ -19,14 +19,14 @@
 
 
 class CMyClass {
-	public: CMyClass();
-	public: CMyClass(const CMyClass& iOther);
-	public: ~CMyClass();
+    public: CMyClass();
+    public: CMyClass(const CMyClass& iOther);
+    public: ~CMyClass();
 
-	private: int fMagicValue;
+    private: int fMagicValue;
 
-	private: static int kStartedConstructionMagicValue;
-	private: static int kFinishedConstructionMagicValue;
+    private: static int kStartedConstructionMagicValue;
+    private: static int kFinishedConstructionMagicValue;
 };
 
 // Value for fMagicValue when the constructor has started running, but not yet finished
@@ -35,39 +35,39 @@
 int CMyClass::kFinishedConstructionMagicValue = 12345;
 
 CMyClass::CMyClass() :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::CMyClass(const CMyClass& /*iOther*/) :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
-	if (gCopyConstructorShouldThow) {
-		throw std::exception();
-	}
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
+    if (gCopyConstructorShouldThow) {
+        throw std::exception();
+    }
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::~CMyClass() {
-	// Only instances for which the constructor has finished running should be destructed
-	assert(fMagicValue == kFinishedConstructionMagicValue);
+    // Only instances for which the constructor has finished running should be destructed
+    assert(fMagicValue == kFinishedConstructionMagicValue);
 }
 
 int main()
 {
-	CMyClass instance;
-	std::deque<CMyClass> vec;
+    CMyClass instance;
+    std::deque<CMyClass> vec;
 
-	vec.push_back(instance);
+    vec.push_back(instance);
 
-	gCopyConstructorShouldThow = true;
-	try {
-		vec.push_back(instance);
-	}
-	catch (...) {
-	}
+    gCopyConstructorShouldThow = true;
+    try {
+        vec.push_back(instance);
+    }
+    catch (...) {
+    }
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp b/test/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp
index c6dab90..c60fdfc 100644
--- a/test/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/push_back_rvalue.pass.cpp
@@ -17,10 +17,12 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-std::deque<MoveOnly>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -31,7 +33,7 @@
         init *= b;
         --init;
     }
-    std::deque<MoveOnly> c(init);
+    C c(init);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -41,14 +43,15 @@
     return c;
 };
 
+template <class C>
 void test(int size)
 {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int j = 0; j < N; ++j)
     {
-        std::deque<MoveOnly> c = make(size, rng[j]);
-        std::deque<MoveOnly>::const_iterator it = c.begin();
+        C c = make<C>(size, rng[j]);
+        typename C::const_iterator it = c.begin();
         for (int i = 0; i < size; ++i, ++it)
             assert(*it == MoveOnly(i));
     }
@@ -59,9 +62,19 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049, 4094, 4095, 4096};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int j = 0; j < N; ++j)
-        test(rng[j]);
+        test<std::deque<MoveOnly> >(rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2046, 2047, 2048, 2049, 4094, 4095, 4096};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int j = 0; j < N; ++j)
+        test<std::deque<MoveOnly, min_allocator<MoveOnly>> >(rng[j]);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/push_front.pass.cpp b/test/containers/sequences/deque/deque.modifiers/push_front.pass.cpp
index d5604d9..e3b2d98 100644
--- a/test/containers/sequences/deque/deque.modifiers/push_front.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/push_front.pass.cpp
@@ -14,7 +14,10 @@
 #include <deque>
 #include <cassert>
 
-std::deque<int>
+#include "../../../min_allocator.h"
+
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -25,7 +28,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -35,11 +38,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<int>& c1, int x)
+test(C& c1, int x)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     std::size_t c1_osize = c1.size();
     c1.push_front(x);
     assert(c1.size() == c1_osize + 1);
@@ -51,19 +54,30 @@
         assert(*i == j);
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<int> C;
-    C c1 = make(N, start);
+    C c1 = make<C>(N, start);
     test(c1, -10);
 }
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+   {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp b/test/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
index aa1d354..662f9a4 100644
--- a/test/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
@@ -19,14 +19,14 @@
 
 
 class CMyClass {
-	public: CMyClass();
-	public: CMyClass(const CMyClass& iOther);
-	public: ~CMyClass();
+    public: CMyClass();
+    public: CMyClass(const CMyClass& iOther);
+    public: ~CMyClass();
 
-	private: int fMagicValue;
+    private: int fMagicValue;
 
-	private: static int kStartedConstructionMagicValue;
-	private: static int kFinishedConstructionMagicValue;
+    private: static int kStartedConstructionMagicValue;
+    private: static int kFinishedConstructionMagicValue;
 };
 
 // Value for fMagicValue when the constructor has started running, but not yet finished
@@ -35,39 +35,39 @@
 int CMyClass::kFinishedConstructionMagicValue = 12345;
 
 CMyClass::CMyClass() :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::CMyClass(const CMyClass& /*iOther*/) :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
-	if (gCopyConstructorShouldThow) {
-		throw std::exception();
-	}
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
+    if (gCopyConstructorShouldThow) {
+        throw std::exception();
+    }
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::~CMyClass() {
-	// Only instances for which the constructor has finished running should be destructed
-	assert(fMagicValue == kFinishedConstructionMagicValue);
+    // Only instances for which the constructor has finished running should be destructed
+    assert(fMagicValue == kFinishedConstructionMagicValue);
 }
 
 int main()
 {
-	CMyClass instance;
-	std::deque<CMyClass> vec;
+    CMyClass instance;
+    std::deque<CMyClass> vec;
 
-	vec.push_front(instance);
+    vec.push_front(instance);
 
-	gCopyConstructorShouldThow = true;
-	try {
-		vec.push_front(instance);
-	}
-	catch (...) {
-	}
+    gCopyConstructorShouldThow = true;
+    try {
+        vec.push_front(instance);
+    }
+    catch (...) {
+    }
 }
diff --git a/test/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp b/test/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp
index 435de48..650a9b8 100644
--- a/test/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp
+++ b/test/containers/sequences/deque/deque.modifiers/push_front_rvalue.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-std::deque<MoveOnly>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -29,7 +31,7 @@
         init *= b;
         --init;
     }
-    std::deque<MoveOnly> c(init);
+    C c(init);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -39,11 +41,11 @@
     return c;
 };
 
+template <class C>
 void
-test(std::deque<MoveOnly>& c1, int x)
+test(C& c1, int x)
 {
-    typedef std::deque<MoveOnly> C;
-    typedef C::iterator I;
+    typedef typename C::iterator I;
     std::size_t c1_osize = c1.size();
     c1.push_front(MoveOnly(x));
     assert(c1.size() == c1_osize + 1);
@@ -55,11 +57,11 @@
         assert(*i == MoveOnly(j));
 }
 
+template <class C>
 void
 testN(int start, int N)
 {
-    typedef std::deque<MoveOnly> C;
-    C c1 = make(N, start);
+    C c1 = make<C>(N, start);
     test(c1, -10);
 }
 
@@ -68,10 +70,21 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<MoveOnly> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<MoveOnly, min_allocator<MoveOnly>> >(rng[i], rng[j]);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/deque/deque.special/copy.pass.cpp b/test/containers/sequences/deque/deque.special/copy.pass.cpp
index c5ef688..e8bf4da 100644
--- a/test/containers/sequences/deque/deque.special/copy.pass.cpp
+++ b/test/containers/sequences/deque/deque.special/copy.pass.cpp
@@ -19,8 +19,10 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -31,7 +33,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -41,16 +43,16 @@
     return c;
 };
 
+template <class C>
 void testN(int start, int N)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     typedef random_access_iterator<I> RAI;
     typedef random_access_iterator<CI> RACI;
     typedef input_iterator<CI> ICI;
-    C c1 = make(N, start);
-    C c2 = make(N);
+    C c1 = make<C>(N, start);
+    C c2 = make<C>(N);
     assert(std::copy(c1.cbegin(), c1.cend(), c2.begin()) == c2.end());
     assert(c1 == c2);
     assert(std::copy(c2.cbegin(), c2.cend(), c1.begin()) == c1.end());
@@ -67,9 +69,20 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.special/copy_backward.pass.cpp b/test/containers/sequences/deque/deque.special/copy_backward.pass.cpp
index 7544ba8..6168126 100644
--- a/test/containers/sequences/deque/deque.special/copy_backward.pass.cpp
+++ b/test/containers/sequences/deque/deque.special/copy_backward.pass.cpp
@@ -19,8 +19,10 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -31,7 +33,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -41,15 +43,15 @@
     return c;
 };
 
+template <class C>
 void testN(int start, int N)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     typedef random_access_iterator<I> RAI;
     typedef random_access_iterator<CI> RACI;
-    C c1 = make(N, start);
-    C c2 = make(N);
+    C c1 = make<C>(N, start);
+    C c2 = make<C>(N);
     assert(std::copy_backward(c1.cbegin(), c1.cend(), c2.end()) == c2.begin());
     assert(c1 == c2);
     assert(std::copy_backward(c2.cbegin(), c2.cend(), c1.end()) == c1.begin());
@@ -66,9 +68,20 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.special/move.pass.cpp b/test/containers/sequences/deque/deque.special/move.pass.cpp
index c4d3651..2da742f 100644
--- a/test/containers/sequences/deque/deque.special/move.pass.cpp
+++ b/test/containers/sequences/deque/deque.special/move.pass.cpp
@@ -19,8 +19,10 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -31,7 +33,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -41,15 +43,15 @@
     return c;
 };
 
+template <class C>
 void testN(int start, int N)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     typedef random_access_iterator<I> RAI;
     typedef random_access_iterator<CI> RACI;
-    C c1 = make(N, start);
-    C c2 = make(N);
+    C c1 = make<C>(N, start);
+    C c2 = make<C>(N);
     assert(std::move(c1.cbegin(), c1.cend(), c2.begin()) == c2.end());
     assert(c1 == c2);
     assert(std::move(c2.cbegin(), c2.cend(), c1.begin()) == c1.end());
@@ -66,9 +68,20 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.special/move_backward.pass.cpp b/test/containers/sequences/deque/deque.special/move_backward.pass.cpp
index b56bf72..6fe094f 100644
--- a/test/containers/sequences/deque/deque.special/move_backward.pass.cpp
+++ b/test/containers/sequences/deque/deque.special/move_backward.pass.cpp
@@ -19,8 +19,10 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -31,7 +33,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -41,15 +43,15 @@
     return c;
 };
 
+template <class C>
 void testN(int start, int N)
 {
-    typedef std::deque<int> C;
-    typedef C::iterator I;
-    typedef C::const_iterator CI;
+    typedef typename C::iterator I;
+    typedef typename C::const_iterator CI;
     typedef random_access_iterator<I> RAI;
     typedef random_access_iterator<CI> RACI;
-    C c1 = make(N, start);
-    C c2 = make(N);
+    C c1 = make<C>(N, start);
+    C c2 = make<C>(N);
     assert(std::move_backward(c1.cbegin(), c1.cend(), c2.end()) == c2.begin());
     assert(c1 == c2);
     assert(std::move_backward(c2.cbegin(), c2.cend(), c1.end()) == c1.begin());
@@ -66,9 +68,20 @@
 
 int main()
 {
+    {
     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
     const int N = sizeof(rng)/sizeof(rng[0]);
     for (int i = 0; i < N; ++i)
         for (int j = 0; j < N; ++j)
-            testN(rng[i], rng[j]);
+            testN<std::deque<int> >(rng[i], rng[j]);
+    }
+#if __cplusplus >= 201103L
+    {
+    int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+    const int N = sizeof(rng)/sizeof(rng[0]);
+    for (int i = 0; i < N; ++i)
+        for (int j = 0; j < N; ++j)
+            testN<std::deque<int, min_allocator<int> > >(rng[i], rng[j]);
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/deque.special/swap.pass.cpp b/test/containers/sequences/deque/deque.special/swap.pass.cpp
index 795ab01..d4da735 100644
--- a/test/containers/sequences/deque/deque.special/swap.pass.cpp
+++ b/test/containers/sequences/deque/deque.special/swap.pass.cpp
@@ -15,8 +15,10 @@
 #include <deque>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
-std::deque<int>
+template <class C>
+C
 make(int size, int start = 0 )
 {
     const int b = 4096 / sizeof(int);
@@ -27,7 +29,7 @@
         init *= b;
         --init;
     }
-    std::deque<int> c(init, 0);
+    C c(init, 0);
     for (int i = 0; i < init-start; ++i)
         c.pop_back();
     for (int i = 0; i < size; ++i)
@@ -37,11 +39,11 @@
     return c;
 };
 
+template <class C>
 void testN(int start, int N, int M)
 {
-    typedef std::deque<int> C;
-    C c1 = make(N, start);
-    C c2 = make(M);
+    C c1 = make<C>(N, start);
+    C c2 = make<C>(M);
     C c1_save = c1;
     C c2_save = c2;
     swap(c1, c2);
@@ -57,7 +59,7 @@
         for (int i = 0; i < N; ++i)
             for (int j = 0; j < N; ++j)
                 for (int k = 0; k < N; ++k)
-                    testN(rng[i], rng[j], rng[k]);
+                    testN<std::deque<int> >(rng[i], rng[j], rng[k]);
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
@@ -83,4 +85,26 @@
         assert((c2 == std::deque<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
         assert(c2.get_allocator() == A(1));
     }
+#if __cplusplus >= 201103L
+    {
+        int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
+        const int N = sizeof(rng)/sizeof(rng[0]);
+        for (int i = 0; i < N; ++i)
+            for (int j = 0; j < N; ++j)
+                for (int k = 0; k < N; ++k)
+                    testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        typedef min_allocator<int> A;
+        std::deque<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A());
+        std::deque<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A());
+        swap(c1, c2);
+        assert((c1 == std::deque<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+        assert(c1.get_allocator() == A());
+        assert((c2 == std::deque<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+        assert(c2.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/iterators.pass.cpp b/test/containers/sequences/deque/iterators.pass.cpp
index 7e38b86..a83a16b 100644
--- a/test/containers/sequences/deque/iterators.pass.cpp
+++ b/test/containers/sequences/deque/iterators.pass.cpp
@@ -20,8 +20,11 @@
 #include <iterator>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::deque<int> C;
     C c;
     C::iterator i;
@@ -29,4 +32,35 @@
     C::const_iterator j;
     j = c.cbegin();
     assert(i == j);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::deque<int, min_allocator<int>> C;
+    C c;
+    C::iterator i;
+    i = c.begin();
+    C::const_iterator j;
+    j = c.cbegin();
+    assert(i == j);
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        std::deque<int>::iterator ii1{}, ii2{};
+        std::deque<int>::iterator ii4 = ii1;
+        std::deque<int>::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+
+//         std::deque<int> c;
+//         assert ( ii1 != c.cbegin());
+//         assert ( cii != c.begin());
+//         assert ( cii != c.cend());
+//         assert ( ii1 != c.end());
+    }
+#endif
 }
diff --git a/test/containers/sequences/deque/types.pass.cpp b/test/containers/sequences/deque/types.pass.cpp
index b9958c9..9e70299 100644
--- a/test/containers/sequences/deque/types.pass.cpp
+++ b/test/containers/sequences/deque/types.pass.cpp
@@ -35,6 +35,7 @@
 
 #include "../../test_allocator.h"
 #include "../../Copyable.h"
+#include "../../min_allocator.h"
 
 template <class T, class Allocator>
 void
@@ -72,4 +73,17 @@
     test<Copyable, test_allocator<Copyable> >();
     static_assert((std::is_same<std::deque<char>::allocator_type,
                                 std::allocator<char> >::value), "");
+#if __cplusplus >= 201103L
+    {
+        typedef std::deque<short, min_allocator<short>> C;
+        static_assert((std::is_same<C::value_type, short>::value), "");
+        static_assert((std::is_same<C::allocator_type, min_allocator<C::value_type> >::value), "");
+        static_assert((std::is_same<C::reference, C::value_type&>::value), "");
+        static_assert((std::is_same<C::const_reference, const C::value_type&>::value), "");
+        static_assert((std::is_same<C::pointer, min_pointer<C::value_type>>::value), "");
+        static_assert((std::is_same<C::const_pointer, min_pointer<const C::value_type>>::value), "");
+        static_assert((std::is_same<C::size_type, std::size_t>::value), "");
+        static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp b/test/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
new file mode 100644
index 0000000..d9cedc4
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.cons
+
+// template <class Alloc>
+//   dynarray(size_type c, const Alloc& alloc);
+// template <class Alloc>
+//   dynarray(size_type c, const T& v, const Alloc& alloc);
+// template <class Alloc>
+//   dynarray(const dynarray& d, const Alloc& alloc);
+// template <class Alloc>
+//   dynarray(initializer_list<T>, const Alloc& alloc);
+
+// ~dynarray();
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+#include "../../../test_allocator.h"
+
+using std::experimental::dynarray;
+
+template <class T, class Allocator>
+void check_allocator ( const dynarray<T> &dyn, const Allocator &alloc ) {
+    for ( int i = 0; i < dyn.size (); ++i )
+        assert ( dyn[i].get_allocator() == alloc );
+}
+
+template <class T, class Allocator>
+void test ( const std::initializer_list<T> &vals, const Allocator &alloc ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( vals, alloc );
+    assert ( d1.size () == vals.size() );
+    assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ()));
+    check_allocator ( d1, alloc );
+    }
+
+
+template <class T, class Allocator>
+void test ( const T &val, const Allocator &alloc1, const Allocator &alloc2 ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( 4, alloc1 );
+    assert ( d1.size () == 4 );
+    assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
+    check_allocator ( d1, alloc1 );
+
+    dynA d2 ( 7, val, alloc1 );
+    assert ( d2.size () == 7 );
+    assert ( std::all_of ( d2.begin (), d2.end (), [&val]( const T &item ){ return item == val; } ));
+    check_allocator ( d2, alloc1 );
+
+    dynA d3 ( d2, alloc2 );
+    assert ( d3.size () == 7 );
+    assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } ));   
+    check_allocator ( d3, alloc2 );
+    }
+
+int main()
+{
+//  This test is waiting on the resolution of LWG issue #2235 
+//     typedef test_allocator<char> Alloc;
+//     typedef std::basic_string<char, std::char_traits<char>, Alloc> nstr;
+// 
+//     test ( nstr("fourteen"), Alloc(3), Alloc(4) );
+//     test ( { nstr("1"), nstr("1"), nstr("2"), nstr("3"), nstr("5"), nstr("8")}, Alloc(6));
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.cons/default.pass.cpp b/test/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
new file mode 100644
index 0000000..0effac2
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.cons
+
+// explicit dynarray(size_type c);
+// dynarray(size_type c, const T& v);
+// dynarray(initializer_list<T>);
+// dynarray(const dynarray& d);
+
+// ~dynarray();
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void test ( const std::initializer_list<T> &vals ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( vals );
+    assert ( d1.size () == vals.size() );
+    assert ( std::equal ( vals.begin (), vals.end (), d1.begin (), d1.end ()));
+    }
+
+
+template <class T>
+void test ( const T &val ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( 4 );
+    assert ( d1.size () == 4 );
+    assert ( std::all_of ( d1.begin (), d1.end (), []( const T &item ){ return item == T(); } ));
+
+    dynA d2 ( 7, val );
+    assert ( d2.size () == 7 );
+    assert ( std::all_of ( d2.begin (), d2.end (), [&val]( const T &item ){ return item == val; } ));
+
+    dynA d3 ( d2 );
+    assert ( d3.size () == 7 );
+    assert ( std::all_of ( d3.begin (), d3.end (), [&val]( const T &item ){ return item == val; } ));   
+    }
+
+void test_bad_length () {
+    try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) + 1 ); }
+    catch ( std::bad_array_length & ) { return ; }
+    assert ( false );
+    }
+
+void test_bad_alloc () {
+    try { dynarray<int> ( std::numeric_limits<size_t>::max() / sizeof ( int ) - 1 ); }
+    catch ( std::bad_alloc & ) { return ; }
+    assert ( false );
+    }
+
+int main()
+{
+//  test<int> ( 14 );       // ints don't get default initialized
+    test<long> ( 0 );
+    test<double> ( 14.0 );
+    test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+    test<std::string> ( "fourteen" );
+    
+    test ( { 1, 1, 2, 3, 5, 8 } );
+    test ( { 1., 1., 2., 3., 5., 8. } );
+    test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), 
+                std::string("5"), std::string("8")} );
+    
+//  Make sure we don't pick up the Allocator version here
+    dynarray<long> d1 ( 20, 3 );
+    assert ( d1.size() == 20 );
+    assert ( std::all_of ( d1.begin (), d1.end (), []( long item ){ return item == 3L; } ));
+
+    test_bad_length ();
+    test_bad_alloc ();
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.data/default.pass.cpp b/test/containers/sequences/dynarray/dynarray.data/default.pass.cpp
new file mode 100644
index 0000000..b669f25
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.data/default.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.data
+
+// T* data() noexcept;
+// const T* data() const noexcept;
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn ) {
+    const T *data = dyn.data ();
+    assert ( data != NULL );
+    assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+    }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn ) {
+    T *data = dyn.data ();
+    assert ( data != NULL );
+    assert ( std::equal ( dyn.begin(), dyn.end(), data ));
+    }
+
+    
+
+template <class T>
+void test ( const T &val ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( 4 );
+    dyn_test ( d1 );
+    dyn_test_const ( d1 );
+    
+    dynA d2 ( 7, val );
+    dyn_test ( d2 );
+    dyn_test_const ( d2 );
+    }
+
+int main()
+{
+    test<int> ( 14 );
+    test<double> ( 14.0 );
+    test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+    test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp b/test/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
new file mode 100644
index 0000000..c57887d
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.data
+
+// void fill(const T& v);
+// const T* data() const noexcept;
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void test ( const T &val ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( 4 );
+    d1.fill ( val );
+    assert ( std::all_of ( d1.begin (), d1.end (), 
+                    [&val]( const T &item ){ return item == val; } ));  
+    }
+
+int main()
+{
+    test<int> ( 14 );
+    test<double> ( 14.0 );
+    test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+    test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.overview/at.pass.cpp b/test/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
new file mode 100644
index 0000000..4d77cf7
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// const_reference at(size_type n) const;
+//       reference at(size_type n);
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_at_fail ( dynarray<T> &dyn, size_t sz ) {
+    try { dyn.at (sz); }
+    catch (const std::out_of_range &) { return; }
+    assert ( false );
+    }
+
+template <class T>
+void dyn_at_fail_const ( const dynarray<T> &dyn, size_t sz ) {
+    try { dyn.at (sz); }
+    catch (const std::out_of_range &) { return; }
+    assert ( false );
+    }
+
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+    const T *data = dyn.data ();
+    auto it = vals.begin ();
+    for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+        assert ( data + i == &dyn.at(i));
+        assert ( *it == dyn.at(i));
+        }
+
+    dyn_at_fail_const ( dyn, dyn.size ());
+    dyn_at_fail_const ( dyn, 2*dyn.size ());
+    dyn_at_fail_const ( dyn, size_t (-1));
+    }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+    T *data = dyn.data ();
+    auto it = vals.begin ();
+    for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+        assert ( data + i == &dyn.at(i));
+        assert ( *it == dyn.at(i));
+        }
+
+    dyn_at_fail ( dyn, dyn.size ());
+    dyn_at_fail ( dyn, 2*dyn.size ());
+    dyn_at_fail ( dyn, size_t (-1));
+    }
+
+
+template <class T>
+void test ( std::initializer_list<T> vals ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( vals );
+    dyn_test ( d1, vals );
+    dyn_test_const ( d1, vals );
+    }
+
+int main()
+{
+    test ( { 1, 1, 2, 3, 5, 8 } );
+    test ( { 1., 1., 2., 3., 5., 8. } );
+    test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), 
+                std::string("5"), std::string("8")} );
+
+    test<int> ( {} );
+    test<std::complex<double>> ( {} );
+    test<std::string> ( {} );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp b/test/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
new file mode 100644
index 0000000..695e1aa
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+
+// iterator       begin()        noexcept;
+// const_iterator begin()  const noexcept;
+// const_iterator cbegin() const noexcept;
+// iterator       end()          noexcept;
+// const_iterator end()    const noexcept;
+// const_iterator cend()   const noexcept;
+// 
+// reverse_iterator       rbegin()        noexcept;
+// const_reverse_iterator rbegin()  const noexcept;
+// const_reverse_iterator crbegin() const noexcept;
+// reverse_iterator       rend()          noexcept;
+// const_reverse_iterator rend()    const noexcept;
+// const_reverse_iterator crend()   const noexcept;
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn ) {
+    const T *data = dyn.data ();
+    assert ( data == &*dyn.begin ());
+    assert ( data == &*dyn.cbegin ());
+
+    assert ( data + dyn.size() - 1 == &*dyn.rbegin ());
+    assert ( data + dyn.size() - 1 == &*dyn.crbegin ());
+
+    assert ( dyn.size () == std::distance ( dyn.begin(), dyn.end()));
+    assert ( dyn.size () == std::distance ( dyn.cbegin(), dyn.cend()));
+    assert ( dyn.size () == std::distance ( dyn.rbegin(), dyn.rend()));
+    assert ( dyn.size () == std::distance ( dyn.crbegin(), dyn.crend()));
+
+    assert (   dyn.begin ()  ==   dyn.cbegin ());
+    assert ( &*dyn.begin ()  == &*dyn.cbegin ());
+    assert (   dyn.rbegin () ==   dyn.crbegin ());
+    assert ( &*dyn.rbegin () == &*dyn.crbegin ());
+    assert (   dyn.end ()    ==   dyn.cend ());
+    assert (   dyn.rend ()   ==   dyn.crend ());
+    }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn ) {
+    T *data = dyn.data ();
+    assert ( data == &*dyn.begin ());
+    assert ( data == &*dyn.cbegin ());
+
+    assert ( data + dyn.size() - 1 == &*dyn.rbegin ());
+    assert ( data + dyn.size() - 1 == &*dyn.crbegin ());
+
+    assert ( dyn.size () == std::distance ( dyn.begin(), dyn.end()));
+    assert ( dyn.size () == std::distance ( dyn.cbegin(), dyn.cend()));
+    assert ( dyn.size () == std::distance ( dyn.rbegin(), dyn.rend()));
+    assert ( dyn.size () == std::distance ( dyn.crbegin(), dyn.crend()));
+
+    assert (   dyn.begin ()  ==   dyn.cbegin ());
+    assert ( &*dyn.begin ()  == &*dyn.cbegin ());
+    assert (   dyn.rbegin () ==   dyn.crbegin ());
+    assert ( &*dyn.rbegin () == &*dyn.crbegin ());
+    assert (   dyn.end ()    ==   dyn.cend ());
+    assert (   dyn.rend ()   ==   dyn.crend ());
+    }
+
+
+template <class T>
+void test ( const T &val ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( 4 );
+    dyn_test ( d1 );
+    dyn_test_const ( d1 );
+    
+    dynA d2 ( 7, val );
+    dyn_test ( d2 );
+    dyn_test_const ( d2 );
+    }
+
+int main()
+{
+    test<int> ( 14 );
+    test<double> ( 14.0 );
+    test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+    test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp b/test/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
new file mode 100644
index 0000000..6d28eef
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// size_type size()     const noexcept;
+// size_type max_size() const noexcept;
+// bool      empty()    const noexcept;  
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test ( const dynarray<T> &dyn, size_t sz ) {
+    assert ( dyn.size ()     == sz );
+    assert ( dyn.max_size () == sz );
+    assert ( dyn.empty () == ( sz == 0 ));
+    }
+
+template <class T>
+void test ( std::initializer_list<T> vals ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( vals );
+    dyn_test ( d1, vals.size ());
+    }
+
+int main()
+{
+    test ( { 1, 1, 2, 3, 5, 8 } );
+    test ( { 1., 1., 2., 3., 5., 8. } );
+    test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), 
+                std::string("5"), std::string("8")} );
+
+    test<int> ( {} );
+    test<std::complex<double>> ( {} );
+    test<std::string> ( {} );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp b/test/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
new file mode 100644
index 0000000..e82aa64
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.overview/front_back.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.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// reference       front();
+// const_reference front() const;
+// reference       back();
+// const_reference back()  const;
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn ) {
+    const T *data = dyn.data ();
+    assert ( *data == dyn.front ());
+    assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+    }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn ) {
+    T *data = dyn.data ();
+    assert ( *data == dyn.front ());
+    assert ( *(data + dyn.size() - 1 ) == dyn.back ());
+    }
+
+
+template <class T>
+void test ( const T &val ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( 4 );
+    dyn_test ( d1 );
+    dyn_test_const ( d1 );
+    
+    dynA d2 ( 7, val );
+    dyn_test ( d2 );
+    dyn_test_const ( d2 );
+    }
+
+int main()
+{
+    test<int> ( 14 );
+    test<double> ( 14.0 );
+    test<std::complex<double>> ( std::complex<double> ( 14, 0 ));
+    test<std::string> ( "fourteen" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp b/test/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
new file mode 100644
index 0000000..7317a20
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.overview/indexing.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.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.overview
+
+// const_reference at(size_type n) const;
+//       reference at(size_type n);
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void dyn_test_const ( const dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+    const T *data = dyn.data ();
+    auto it = vals.begin ();
+    for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+        assert ( data + i == &dyn[i]);
+        assert ( *it == dyn[i]);
+        }
+    }
+
+template <class T>
+void dyn_test ( dynarray<T> &dyn, const std::initializer_list<T> &vals ) {
+    T *data = dyn.data ();
+    auto it = vals.begin ();
+    for ( size_t i = 0; i < dyn.size(); ++i, ++it ) {
+        assert ( data + i == &dyn[i]);
+        assert ( *it == dyn[i]);
+        }
+    }
+
+
+template <class T>
+void test ( std::initializer_list<T> vals ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( vals );
+    dyn_test ( d1, vals );
+    dyn_test_const ( d1, vals );
+    }
+
+int main()
+{
+    test ( { 1, 1, 2, 3, 5, 8 } );
+    test ( { 1., 1., 2., 3., 5., 8. } );
+    test ( { std::string("1"), std::string("1"), std::string("2"), std::string("3"), 
+                std::string("5"), std::string("8")} );
+
+    test<int> ( {} );
+    test<std::complex<double>> ( {} );
+    test<std::string> ( {} );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.traits/default.pass.cpp b/test/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
new file mode 100644
index 0000000..f0cd784
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.data
+
+// template <class Type, class Alloc>
+//   struct uses_allocator<dynarray<Type>, Alloc> : true_type { };
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include "../../../test_allocator.h"
+
+using std::experimental::dynarray;
+
+int main()
+{
+    static_assert ( std::uses_allocator<dynarray<int>, test_allocator<int>>::value, "" );
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/dynarray.zero/default.pass.cpp b/test/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
new file mode 100644
index 0000000..93f3b18
--- /dev/null
+++ b/test/containers/sequences/dynarray/dynarray.zero/default.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.
+//
+//===----------------------------------------------------------------------===//
+
+// dynarray.zero
+
+// dynarray shall provide support for the special case of construction with a size of zero.
+// In the case that the size is zero, begin() == end() == unique value. 
+// The return value of data() is unspecified. 
+// The effect of calling front() or back() for a zero-sized dynarray is undefined.
+
+
+  
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11
+
+#include <experimental/dynarray>
+#include <cassert>
+
+#include <algorithm>
+#include <complex>
+#include <string>
+
+using std::experimental::dynarray;
+
+template <class T>
+void test ( ) {
+    typedef dynarray<T> dynA;
+    
+    dynA d1 ( 0 );
+    assert ( d1.size() == 0 );
+    assert ( d1.begin() == d1.end ());
+    }
+
+int main()
+{
+    test<int> ();
+    test<double> ();
+    test<std::complex<double>> ();
+    test<std::string> ();
+}
+#else
+int main() {}
+#endif
diff --git a/test/containers/sequences/dynarray/nothing_to_do.pass.cpp b/test/containers/sequences/dynarray/nothing_to_do.pass.cpp
new file mode 100644
index 0000000..b58f5c5
--- /dev/null
+++ b/test/containers/sequences/dynarray/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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp
index 5f9d701..9a201aa 100644
--- a/test/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.access/front.pass.cpp
@@ -16,6 +16,8 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -36,4 +38,24 @@
         assert(c.front() == 0);
         assert(*c.begin() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        assert(c.front() == 0);
+        c.front() = 10;
+        assert(c.front() == 10);
+        assert(*c.begin() == 10);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        const C c(std::begin(t), std::end(t));
+        assert(c.front() == 0);
+        assert(*c.begin() == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp
index 380d3c1..3183287 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/alloc.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../test_allocator.h"
 #include "../../../NotConstructible.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -27,4 +28,14 @@
         assert(c.get_allocator() == A(12));
         assert(c.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<NotConstructible> A;
+        typedef A::value_type T;
+        typedef std::forward_list<T, A> C;
+        C c(A{});
+        assert(c.get_allocator() == A());
+        assert(c.empty());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp
index 82e1454..0379e47 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/assign_copy.pass.cpp
@@ -16,6 +16,7 @@
 #include <iterator>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -116,4 +117,30 @@
         assert(c1 == c0);
         assert(c1.get_allocator() == A(10));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef min_allocator<int> A;
+        typedef std::forward_list<T, A> C;
+        const T t0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        const T t1[] = {10, 11, 12, 13};
+        C c0(std::begin(t0), std::end(t0), A());
+        C c1(std::begin(t1), std::end(t1), A());
+        c1 = c0;
+        assert(c1 == c0);
+        assert(c1.get_allocator() == A());
+    }
+    {
+        typedef int T;
+        typedef min_allocator<int> A;
+        typedef std::forward_list<T, A> C;
+        const T t0[] = {10, 11, 12, 13};
+        const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c0(std::begin(t0), std::end(t0), A());
+        C c1(std::begin(t1), std::end(t1), A());
+        c1 = c0;
+        assert(c1 == c0);
+        assert(c1.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp
index d79c503..088ed6d 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/assign_init.pass.cpp
@@ -15,6 +15,8 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -40,5 +42,29 @@
             assert(*i == 10+n);
         assert(n == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {10, 11, 12, 13};
+        C c(std::begin(t1), std::end(t1));
+        c.assign({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
+        int n = 0;
+        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, ++n)
+            assert(*i == n);
+        assert(n == 10);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t1), std::end(t1));
+        c.assign({10, 11, 12, 13});
+        int n = 0;
+        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, ++n)
+            assert(*i == 10+n);
+        assert(n == 4);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp
index 5ac81ee..480350b 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/assign_move.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "../../../test_allocator.h"
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -158,5 +159,41 @@
         assert(c1.get_allocator() == A(10));
         assert(c0.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef MoveOnly T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        T t0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        T t1[] = {10, 11, 12, 13};
+        typedef std::move_iterator<T*> I;
+        C c0(I(std::begin(t0)), I(std::end(t0)), A());
+        C c1(I(std::begin(t1)), I(std::end(t1)), A());
+        c1 = std::move(c0);
+        int n = 0;
+        for (C::const_iterator i = c1.cbegin(); i != c1.cend(); ++i, ++n)
+            assert(*i == n);
+        assert(n == 10);
+        assert(c1.get_allocator() == A());
+        assert(c0.empty());
+    }
+    {
+        typedef MoveOnly T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        T t0[] = {10, 11, 12, 13};
+        T t1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        typedef std::move_iterator<T*> I;
+        C c0(I(std::begin(t0)), I(std::end(t0)), A());
+        C c1(I(std::begin(t1)), I(std::end(t1)), A());
+        c1 = std::move(c0);
+        int n = 0;
+        for (C::const_iterator i = c1.cbegin(); i != c1.cend(); ++i, ++n)
+            assert(*i == 10+n);
+        assert(n == 4);
+        assert(c1.get_allocator() == A());
+        assert(c0.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp
index b880bc2..5efe79f 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/assign_op_init.pass.cpp
@@ -15,6 +15,8 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -40,5 +42,29 @@
             assert(*i == 10+n);
         assert(n == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {10, 11, 12, 13};
+        C c(std::begin(t1), std::end(t1));
+        c = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        int n = 0;
+        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, ++n)
+            assert(*i == n);
+        assert(n == 10);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t1), std::end(t1));
+        c = {10, 11, 12, 13};
+        int n = 0;
+        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, ++n)
+            assert(*i == 10+n);
+        assert(n == 4);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
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 38fef42..ccbd7ce 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/assign_range.pass.cpp
@@ -17,6 +17,7 @@
 #include <iterator>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,32 @@
             assert(*i == 10+n);
         assert(n == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        const T t1[] = {10, 11, 12, 13};
+        C c(std::begin(t1), std::end(t1));
+        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)
+            assert(*i == n);
+        assert(n == 10);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t0[] = {10, 11, 12, 13};
+        const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t1), std::end(t1));
+        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)
+            assert(*i == 10+n);
+        assert(n == 4);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp
index 53add15..7e7dbb6 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/assign_size_value.pass.cpp
@@ -15,6 +15,8 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -39,4 +41,28 @@
             assert(*i == 10);
         assert(n == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {10, 11, 12, 13};
+        C c(std::begin(t1), std::end(t1));
+        c.assign(10, 1);
+        int n = 0;
+        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, ++n)
+            assert(*i == 1);
+        assert(n == 10);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t1), std::end(t1));
+        c.assign(4, 10);
+        int n = 0;
+        for (C::const_iterator i = c.cbegin(); i != c.cend(); ++i, ++n)
+            assert(*i == 10);
+        assert(n == 4);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp
index 7bd2668..0c3f162 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/copy.pass.cpp
@@ -16,6 +16,7 @@
 #include <iterator>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -49,4 +50,20 @@
         assert(c.get_allocator() == A(-2));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef min_allocator<int> A;
+        typedef std::forward_list<T, A> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c0(std::begin(t), std::end(t), A());
+        C c = c0;
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == std::end(t) - std::begin(t));
+        assert(c == c0);
+        assert(c.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp
index e085f65..7649679 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/copy_alloc.pass.cpp
@@ -16,6 +16,7 @@
 #include <iterator>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -47,4 +48,20 @@
         assert(c == c0);
         assert(c.get_allocator() == A(9));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef min_allocator<int> A;
+        typedef std::forward_list<T, A> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c0(std::begin(t), std::end(t), A());
+        C c(c0, A());
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == std::end(t) - std::begin(t));
+        assert(c == c0);
+        assert(c.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp
index 7c6c357..aa00236 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/default.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -22,4 +24,12 @@
         C c;
         assert(c.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        assert(c.empty());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp
index 503e97b..987185d 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/init.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -26,5 +28,16 @@
             assert(*i == n);
         assert(n == 10);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == 10);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp
index cd36b44..4b62a42 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/init_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -30,5 +31,18 @@
         assert(n == 10);
         assert(c.get_allocator() == A(14));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        C c({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, A());
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == 10);
+        assert(c.get_allocator() == A());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp
index a5b4725..01b1259 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/move.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "../../../test_allocator.h"
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -51,5 +52,22 @@
         assert(c0.empty());
         assert(c.get_allocator() == A(10));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef MoveOnly T;
+        typedef min_allocator<int> A;
+        typedef std::forward_list<T, A> C;
+        T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        typedef std::move_iterator<T*> I;
+        C c0(I(std::begin(t)), I(std::end(t)), A());
+        C c = std::move(c0);
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == std::end(t) - std::begin(t));
+        assert(c0.empty());
+        assert(c.get_allocator() == A());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp
index 47f9592..b659e88 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/move_alloc.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "../../../test_allocator.h"
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -51,5 +52,22 @@
         assert(!c0.empty());
         assert(c.get_allocator() == A(9));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef MoveOnly T;
+        typedef min_allocator<int> A;
+        typedef std::forward_list<T, A> C;
+        T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        typedef std::move_iterator<T*> I;
+        C c0(I(std::begin(t)), I(std::end(t)), A());
+        C c(std::move(c0), A());
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == std::end(t) - std::begin(t));
+        assert(c0.empty());
+        assert(c.get_allocator() == A());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp
index e9c8aba..57d3450 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/range.pass.cpp
@@ -17,6 +17,7 @@
 #include <iterator>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -31,4 +32,17 @@
             assert(*i == n);
         assert(n == std::end(t) - std::begin(t));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef input_iterator<const T*> I;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(I(std::begin(t)), I(std::end(t)));
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == std::end(t) - std::begin(t));
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp
index 0eec764..8f3b39a 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/range_alloc.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "../../../test_allocator.h"
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -35,4 +36,19 @@
         assert(n == std::end(t) - std::begin(t));
         assert(c.get_allocator() == A(13));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        typedef input_iterator<const T*> I;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(I(std::begin(t)), I(std::end(t)), A());
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == n);
+        assert(n == std::end(t) - std::begin(t));
+        assert(c.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp
index eeffb70..fb71b31 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp
@@ -10,11 +10,24 @@
 // <forward_list>
 
 // explicit forward_list(size_type n);
+// explicit forward_list(size_type n, const Alloc& a);
 
 #include <forward_list>
 #include <cassert>
 
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
+
+template <class T, class Allocator>
+void check_allocator(unsigned n, Allocator const &alloc = Allocator())
+{
+#if _LIBCPP_STD_VER > 11
+    typedef std::forward_list<T, Allocator> C;
+    C d(n, alloc);
+    assert(d.get_allocator() == alloc);
+    assert(std::distance(d.begin(), d.end()) == n);
+#endif
+}
 
 int main()
 {
@@ -32,4 +45,22 @@
 #endif
         assert(n == N);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef DefaultOnly T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        unsigned N = 10;
+        C c(N);
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+            assert(*i == T());
+#else
+            ;
+#endif
+        assert(n == N);
+        check_allocator<T, min_allocator<T>> ( 0 );
+        check_allocator<T, min_allocator<T>> ( 3 );
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp
index f95e783..4981d7e 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/size_value.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -27,4 +29,17 @@
             assert(*i == v);
         assert(n == N);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        T v(6);
+        unsigned N = 10;
+        C c(N, v);
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == v);
+        assert(n == N);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp
index 34835d6..da4e80d 100644
--- a/test/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.cons/size_value_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -31,4 +32,19 @@
         assert(n == N);
         assert(c.get_allocator() == A(12));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<int> A;
+        typedef A::value_type T;
+        typedef std::forward_list<T, A> C;
+        T v(6);
+        unsigned N = 10;
+        C c(N, v, A());
+        unsigned n = 0;
+        for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n)
+            assert(*i == v);
+        assert(n == N);
+        assert(c.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp
index 947d0dc..1b89177 100644
--- a/test/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.iter/before_begin.pass.cpp
@@ -17,6 +17,8 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -58,4 +60,45 @@
         C::const_iterator i = c.before_begin();
         assert(std::distance(i, c.end()) == 11);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        C::iterator i = c.before_begin();
+        assert(std::distance(i, c.end()) == 1);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const C c;
+        C::const_iterator i = c.before_begin();
+        assert(std::distance(i, c.end()) == 1);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const C c;
+        C::const_iterator i = c.cbefore_begin();
+        assert(std::distance(i, c.end()) == 1);
+        assert(c.cbefore_begin() == c.before_begin());
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        C::iterator i = c.before_begin();
+        assert(std::distance(i, c.end()) == 11);
+        assert(std::next(c.before_begin()) == c.begin());
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        const C c(std::begin(t), std::end(t));
+        C::const_iterator i = c.before_begin();
+        assert(std::distance(i, c.end()) == 11);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp
index e27e34b..2e99514 100644
--- a/test/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.iter/iterators.pass.cpp
@@ -20,6 +20,8 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -69,4 +71,72 @@
         C::iterator i;
         C::const_iterator j;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        C::iterator i = c.begin();
+        C::iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const C c;
+        C::const_iterator i = c.begin();
+        C::const_iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        C::const_iterator i = c.cbegin();
+        C::const_iterator j = c.cend();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+        assert(i == c.end());
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        C::iterator i = c.begin();
+        assert(*i == 0);
+        ++i;
+        assert(*i == 1);
+        *i = 10;
+        assert(*i == 10);
+        assert(std::distance(c.begin(), c.end()) == 10);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C::iterator i;
+        C::const_iterator j;
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        std::forward_list<int>::iterator ii1{}, ii2{};
+        std::forward_list<int>::iterator ii4 = ii1;
+        std::forward_list<int>::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+
+//         std::forward_list<int> c;
+//         assert ( ii1 != c.cbegin());
+//         assert ( cii != c.begin());
+//         assert ( cii != c.cend());
+//         assert ( ii1 != c.end());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp
index 5c9c7bb..33db9e9 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/clear.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../NotConstructible.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -37,4 +38,25 @@
         c.clear();
         assert(distance(c.begin(), c.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef NotConstructible T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        c.clear();
+        assert(distance(c.begin(), c.end()) == 0);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4};
+        C c(std::begin(t), std::end(t));
+
+        c.clear();
+        assert(distance(c.begin(), c.end()) == 0);
+
+        c.clear();
+        assert(distance(c.begin(), c.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp
index db18c91..680b5b8 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_after.pass.cpp
@@ -16,6 +16,7 @@
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -51,5 +52,38 @@
         assert(*next(c.begin(), 3) == Emplaceable(2, 3.5));
         assert(distance(c.begin(), c.end()) == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef Emplaceable T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef C::iterator I;
+        C c;
+        I i = c.emplace_after(c.cbefore_begin());
+        assert(i == c.begin());
+        assert(c.front() == Emplaceable());
+        assert(distance(c.begin(), c.end()) == 1);
+
+        i = c.emplace_after(c.cbegin(), 1, 2.5);
+        assert(i == next(c.begin()));
+        assert(c.front() == Emplaceable());
+        assert(*next(c.begin()) == Emplaceable(1, 2.5));
+        assert(distance(c.begin(), c.end()) == 2);
+
+        i = c.emplace_after(next(c.cbegin()), 2, 3.5);
+        assert(i == next(c.begin(), 2));
+        assert(c.front() == Emplaceable());
+        assert(*next(c.begin()) == Emplaceable(1, 2.5));
+        assert(*next(c.begin(), 2) == Emplaceable(2, 3.5));
+        assert(distance(c.begin(), c.end()) == 3);
+
+        i = c.emplace_after(c.cbegin(), 3, 4.5);
+        assert(i == next(c.begin()));
+        assert(c.front() == Emplaceable());
+        assert(*next(c.begin(), 1) == Emplaceable(3, 4.5));
+        assert(*next(c.begin(), 2) == Emplaceable(1, 2.5));
+        assert(*next(c.begin(), 3) == Emplaceable(2, 3.5));
+        assert(distance(c.begin(), c.end()) == 4);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp
index 27b67e5..f3c7f4a 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/emplace_front.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -31,5 +32,19 @@
         assert(*next(c.begin()) == Emplaceable());
         assert(distance(c.begin(), c.end()) == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef Emplaceable T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        c.emplace_front();
+        assert(c.front() == Emplaceable());
+        assert(distance(c.begin(), c.end()) == 1);
+        c.emplace_front(1, 2.5);
+        assert(c.front() == Emplaceable(1, 2.5));
+        assert(*next(c.begin()) == Emplaceable());
+        assert(distance(c.begin(), c.end()) == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp
index 2e5f68f..f326593 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_many.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -82,4 +84,72 @@
         assert(i == c.end());
         assert(distance(c.begin(), c.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+
+        C::iterator i = c.erase_after(next(c.cbefore_begin(), 4), next(c.cbefore_begin(), 4));
+        assert(i == next(c.cbefore_begin(), 4));
+        assert(distance(c.begin(), c.end()) == 10);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(*next(c.begin(), 3) == 3);
+        assert(*next(c.begin(), 4) == 4);
+        assert(*next(c.begin(), 5) == 5);
+        assert(*next(c.begin(), 6) == 6);
+        assert(*next(c.begin(), 7) == 7);
+        assert(*next(c.begin(), 8) == 8);
+        assert(*next(c.begin(), 9) == 9);
+
+        i = c.erase_after(next(c.cbefore_begin(), 2), next(c.cbefore_begin(), 5));
+        assert(i == next(c.begin(), 2));
+        assert(distance(c.begin(), c.end()) == 8);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 4);
+        assert(*next(c.begin(), 3) == 5);
+        assert(*next(c.begin(), 4) == 6);
+        assert(*next(c.begin(), 5) == 7);
+        assert(*next(c.begin(), 6) == 8);
+        assert(*next(c.begin(), 7) == 9);
+
+        i = c.erase_after(next(c.cbefore_begin(), 2), next(c.cbefore_begin(), 3));
+        assert(i == next(c.begin(), 2));
+        assert(distance(c.begin(), c.end()) == 8);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 4);
+        assert(*next(c.begin(), 3) == 5);
+        assert(*next(c.begin(), 4) == 6);
+        assert(*next(c.begin(), 5) == 7);
+        assert(*next(c.begin(), 6) == 8);
+        assert(*next(c.begin(), 7) == 9);
+
+        i = c.erase_after(next(c.cbefore_begin(), 5), next(c.cbefore_begin(), 9));
+        assert(i == c.end());
+        assert(distance(c.begin(), c.end()) == 5);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 4);
+        assert(*next(c.begin(), 3) == 5);
+        assert(*next(c.begin(), 4) == 6);
+
+        i = c.erase_after(next(c.cbefore_begin(), 0), next(c.cbefore_begin(), 2));
+        assert(i == c.begin());
+        assert(distance(c.begin(), c.end()) == 4);
+        assert(*next(c.begin(), 0) == 1);
+        assert(*next(c.begin(), 1) == 4);
+        assert(*next(c.begin(), 2) == 5);
+        assert(*next(c.begin(), 3) == 6);
+
+        i = c.erase_after(next(c.cbefore_begin(), 0), next(c.cbefore_begin(), 5));
+        assert(i == c.begin());
+        assert(i == c.end());
+        assert(distance(c.begin(), c.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp
index 6b706de..e36089e 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/erase_after_one.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -53,4 +55,43 @@
         assert(i == c.end());
         assert(distance(c.begin(), c.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4};
+        C c(std::begin(t), std::end(t));
+
+        C::iterator i = c.erase_after(next(c.cbefore_begin(), 4));
+        assert(i == c.end());
+        assert(distance(c.begin(), c.end()) == 4);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(*next(c.begin(), 3) == 3);
+
+        i = c.erase_after(next(c.cbefore_begin(), 0));
+        assert(i == c.begin());
+        assert(distance(c.begin(), c.end()) == 3);
+        assert(*next(c.begin(), 0) == 1);
+        assert(*next(c.begin(), 1) == 2);
+        assert(*next(c.begin(), 2) == 3);
+
+        i = c.erase_after(next(c.cbefore_begin(), 1));
+        assert(i == next(c.begin()));
+        assert(distance(c.begin(), c.end()) == 2);
+        assert(*next(c.begin(), 0) == 1);
+        assert(*next(c.begin(), 1) == 3);
+
+        i = c.erase_after(next(c.cbefore_begin(), 1));
+        assert(i == c.end());
+        assert(distance(c.begin(), c.end()) == 1);
+        assert(*next(c.begin(), 0) == 1);
+
+        i = c.erase_after(next(c.cbefore_begin(), 0));
+        assert(i == c.begin());
+        assert(i == c.end());
+        assert(distance(c.begin(), c.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp
index 5cfb8ad..b6785e7 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_const.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -48,4 +50,38 @@
         assert(*next(c.begin(), 3) == 2);
         assert(distance(c.begin(), c.end()) == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef C::iterator I;
+        C c;
+        I i = c.insert_after(c.cbefore_begin(), 0);
+        assert(i == c.begin());
+        assert(c.front() == 0);
+        assert(c.front() == 0);
+        assert(distance(c.begin(), c.end()) == 1);
+
+        i = c.insert_after(c.cbegin(), 1);
+        assert(i == next(c.begin()));
+        assert(c.front() == 0);
+        assert(*next(c.begin()) == 1);
+        assert(distance(c.begin(), c.end()) == 2);
+
+        i = c.insert_after(next(c.cbegin()), 2);
+        assert(i == next(c.begin(), 2));
+        assert(c.front() == 0);
+        assert(*next(c.begin()) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(distance(c.begin(), c.end()) == 3);
+
+        i = c.insert_after(c.cbegin(), 3);
+        assert(i == next(c.begin()));
+        assert(c.front() == 0);
+        assert(*next(c.begin(), 1) == 3);
+        assert(*next(c.begin(), 2) == 1);
+        assert(*next(c.begin(), 3) == 2);
+        assert(distance(c.begin(), c.end()) == 4);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp
index eb8b8e1..7afaacd 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_init.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -42,5 +44,32 @@
         assert(*next(c.begin(), 3) == 1);
         assert(*next(c.begin(), 4) == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef C::iterator I;
+        C c;
+        I i = c.insert_after(c.cbefore_begin(), {});
+        assert(i == c.before_begin());
+        assert(distance(c.begin(), c.end()) == 0);
+
+        i = c.insert_after(c.cbefore_begin(), {0, 1, 2});
+        assert(i == next(c.before_begin(), 3));
+        assert(distance(c.begin(), c.end()) == 3);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+
+        i = c.insert_after(c.begin(), {3, 4});
+        assert(i == next(c.begin(), 2));
+        assert(distance(c.begin(), c.end()) == 5);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 3);
+        assert(*next(c.begin(), 2) == 4);
+        assert(*next(c.begin(), 3) == 1);
+        assert(*next(c.begin(), 4) == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp
index 4d8ccc2..dde6a13 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_range.pass.cpp
@@ -17,6 +17,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -47,4 +48,33 @@
         assert(*next(c.begin(), 3) == 1);
         assert(*next(c.begin(), 4) == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef C::iterator I;
+        typedef input_iterator<const T*> J;
+        C c;
+        const T t[] = {0, 1, 2, 3, 4};
+        I i = c.insert_after(c.cbefore_begin(), J(t), J(t));
+        assert(i == c.before_begin());
+        assert(distance(c.begin(), c.end()) == 0);
+
+        i = c.insert_after(c.cbefore_begin(), J(t), J(t+3));
+        assert(i == next(c.before_begin(), 3));
+        assert(distance(c.begin(), c.end()) == 3);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+
+        i = c.insert_after(c.begin(), J(t+3), J(t+5));
+        assert(i == next(c.begin(), 2));
+        assert(distance(c.begin(), c.end()) == 5);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 3);
+        assert(*next(c.begin(), 2) == 4);
+        assert(*next(c.begin(), 3) == 1);
+        assert(*next(c.begin(), 4) == 2);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp
index 44dbe7c..59f6770 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_rv.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -51,5 +52,39 @@
         assert(*next(c.begin(), 3) == 2);
         assert(distance(c.begin(), c.end()) == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef MoveOnly T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef C::iterator I;
+        C c;
+        I i = c.insert_after(c.cbefore_begin(), 0);
+        assert(i == c.begin());
+        assert(c.front() == 0);
+        assert(c.front() == 0);
+        assert(distance(c.begin(), c.end()) == 1);
+
+        i = c.insert_after(c.cbegin(), 1);
+        assert(i == next(c.begin()));
+        assert(c.front() == 0);
+        assert(*next(c.begin()) == 1);
+        assert(distance(c.begin(), c.end()) == 2);
+
+        i = c.insert_after(next(c.cbegin()), 2);
+        assert(i == next(c.begin(), 2));
+        assert(c.front() == 0);
+        assert(*next(c.begin()) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(distance(c.begin(), c.end()) == 3);
+
+        i = c.insert_after(c.cbegin(), 3);
+        assert(i == next(c.begin()));
+        assert(c.front() == 0);
+        assert(*next(c.begin(), 1) == 3);
+        assert(*next(c.begin(), 2) == 1);
+        assert(*next(c.begin(), 3) == 2);
+        assert(distance(c.begin(), c.end()) == 4);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp
index 2bf8b12..4297753 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/insert_after_size_value.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -41,4 +43,31 @@
         assert(*next(c.begin(), 3) == 3);
         assert(*next(c.begin(), 4) == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef C::iterator I;
+        C c;
+        I i = c.insert_after(c.cbefore_begin(), 0, 0);
+        assert(i == c.before_begin());
+        assert(distance(c.begin(), c.end()) == 0);
+
+        i = c.insert_after(c.cbefore_begin(), 3, 3);
+        assert(i == next(c.before_begin(), 3));
+        assert(distance(c.begin(), c.end()) == 3);
+        assert(*next(c.begin(), 0) == 3);
+        assert(*next(c.begin(), 1) == 3);
+        assert(*next(c.begin(), 2) == 3);
+
+        i = c.insert_after(c.begin(), 2, 2);
+        assert(i == next(c.begin(), 2));
+        assert(distance(c.begin(), c.end()) == 5);
+        assert(*next(c.begin(), 0) == 3);
+        assert(*next(c.begin(), 1) == 2);
+        assert(*next(c.begin(), 2) == 2);
+        assert(*next(c.begin(), 3) == 3);
+        assert(*next(c.begin(), 4) == 3);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp
index c73f6a5..0b73c7a 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/pop_front.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -45,4 +46,33 @@
         assert(distance(c.begin(), c.end()) == 0);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        c.push_front(1);
+        c.push_front(3);
+        c.pop_front();
+        assert(distance(c.begin(), c.end()) == 1);
+        assert(c.front() == 1);
+        c.pop_front();
+        assert(distance(c.begin(), c.end()) == 0);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef MoveOnly T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        c.push_front(1);
+        c.push_front(3);
+        c.pop_front();
+        assert(distance(c.begin(), c.end()) == 1);
+        assert(c.front() == 1);
+        c.pop_front();
+        assert(distance(c.begin(), c.end()) == 0);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp
index dd12833..bcf2865 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_const.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -28,4 +30,18 @@
         assert(*next(c.begin()) == 1);
         assert(distance(c.begin(), c.end()) == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        c.push_front(1);
+        assert(c.front() == 1);
+        assert(distance(c.begin(), c.end()) == 1);
+        c.push_front(3);
+        assert(c.front() == 3);
+        assert(*next(c.begin()) == 1);
+        assert(distance(c.begin(), c.end()) == 2);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp
index 1624ed6..43c62eb 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_exception_safety.pass.cpp
@@ -19,14 +19,14 @@
 
 
 class CMyClass {
-	public: CMyClass();
-	public: CMyClass(const CMyClass& iOther);
-	public: ~CMyClass();
+    public: CMyClass();
+    public: CMyClass(const CMyClass& iOther);
+    public: ~CMyClass();
 
-	private: int fMagicValue;
+    private: int fMagicValue;
 
-	private: static int kStartedConstructionMagicValue;
-	private: static int kFinishedConstructionMagicValue;
+    private: static int kStartedConstructionMagicValue;
+    private: static int kFinishedConstructionMagicValue;
 };
 
 // Value for fMagicValue when the constructor has started running, but not yet finished
@@ -35,39 +35,39 @@
 int CMyClass::kFinishedConstructionMagicValue = 12345;
 
 CMyClass::CMyClass() :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::CMyClass(const CMyClass& /*iOther*/) :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
-	if (gCopyConstructorShouldThow) {
-		throw std::exception();
-	}
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
+    if (gCopyConstructorShouldThow) {
+        throw std::exception();
+    }
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::~CMyClass() {
-	// Only instances for which the constructor has finished running should be destructed
-	assert(fMagicValue == kFinishedConstructionMagicValue);
+    // Only instances for which the constructor has finished running should be destructed
+    assert(fMagicValue == kFinishedConstructionMagicValue);
 }
 
 int main()
 {
-	CMyClass instance;
-	std::forward_list<CMyClass> vec;
+    CMyClass instance;
+    std::forward_list<CMyClass> vec;
 
-	vec.push_front(instance);
+    vec.push_front(instance);
 
-	gCopyConstructorShouldThow = true;
-	try {
-		vec.push_front(instance);
-	}
-	catch (...) {
-	}
+    gCopyConstructorShouldThow = true;
+    try {
+        vec.push_front(instance);
+    }
+    catch (...) {
+    }
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp
index ff68826..f2e99e1 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/push_front_rv.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -31,5 +32,19 @@
         assert(*next(c.begin()) == 1);
         assert(distance(c.begin(), c.end()) == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef MoveOnly T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        c.push_front(1);
+        assert(c.front() == 1);
+        assert(distance(c.begin(), c.end()) == 1);
+        c.push_front(3);
+        assert(c.front() == 3);
+        assert(*next(c.begin()) == 1);
+        assert(distance(c.begin(), c.end()) == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp
index b283b86..e937280 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -63,4 +64,51 @@
         assert(*next(c.begin(), 4) == 0);
         assert(*next(c.begin(), 5) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef DefaultOnly T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        c.resize(0);
+        assert(distance(c.begin(), c.end()) == 0);
+        c.resize(10);
+        assert(distance(c.begin(), c.end()) == 10);
+        c.resize(20);
+        assert(distance(c.begin(), c.end()) == 20);
+        c.resize(5);
+        assert(distance(c.begin(), c.end()) == 5);
+        c.resize(0);
+        assert(distance(c.begin(), c.end()) == 0);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4};
+        C c(std::begin(t), std::end(t));
+
+        c.resize(3);
+        assert(distance(c.begin(), c.end()) == 3);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+
+        c.resize(6);
+        assert(distance(c.begin(), c.end()) == 6);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(*next(c.begin(), 3) == 0);
+        assert(*next(c.begin(), 4) == 0);
+        assert(*next(c.begin(), 5) == 0);
+
+        c.resize(6);
+        assert(distance(c.begin(), c.end()) == 6);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(*next(c.begin(), 3) == 0);
+        assert(*next(c.begin(), 4) == 0);
+        assert(*next(c.begin(), 5) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp
index 14873ae..89775d1 100644
--- a/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.modifiers/resize_size_value.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -48,4 +49,36 @@
         assert(*next(c.begin(), 4) == 10);
         assert(*next(c.begin(), 5) == 10);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4};
+        C c(std::begin(t), std::end(t));
+
+        c.resize(3, 10);
+        assert(distance(c.begin(), c.end()) == 3);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+
+        c.resize(6, 10);
+        assert(distance(c.begin(), c.end()) == 6);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(*next(c.begin(), 3) == 10);
+        assert(*next(c.begin(), 4) == 10);
+        assert(*next(c.begin(), 5) == 10);
+
+        c.resize(6, 12);
+        assert(distance(c.begin(), c.end()) == 6);
+        assert(*next(c.begin(), 0) == 0);
+        assert(*next(c.begin(), 1) == 1);
+        assert(*next(c.begin(), 2) == 2);
+        assert(*next(c.begin(), 3) == 10);
+        assert(*next(c.begin(), 4) == 10);
+        assert(*next(c.begin(), 5) == 10);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp
index 3e74d80..280d92c 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/merge.pass.cpp
@@ -15,6 +15,8 @@
 #include <iterator>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -29,4 +31,18 @@
         C c3(std::begin(t3), std::end(t3));
         assert(c1 == c3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {3, 5, 6, 7, 12, 13};
+        const T t2[] = {0, 1, 2, 4, 8, 9, 10, 11, 14, 15};
+        const T t3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.merge(c2);
+        C c3(std::begin(t3), std::end(t3));
+        assert(c1 == c3);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp
index fe0a470..6d6c40e 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/merge_pred.pass.cpp
@@ -16,6 +16,8 @@
 #include <functional>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -30,4 +32,18 @@
         C c3(std::begin(t3), std::end(t3));
         assert(c1 == c3);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {13, 12, 7, 6, 5, 3};
+        const T t2[] = {15, 14, 11, 10, 9, 8, 4, 2, 1, 0};
+        const T t3[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.merge(c2, std::greater<T>());
+        C c3(std::begin(t3), std::end(t3));
+        assert(c1 == c3);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp
index 806b609..9874803 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/remove.pass.cpp
@@ -15,6 +15,8 @@
 #include <iterator>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -64,4 +66,53 @@
         c1.remove(0);
         assert(c1 == c2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 5, 5, 0, 0, 0, 5};
+        const T t2[] = {5, 5, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.remove(0);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 0, 0, 0};
+        C c1(std::begin(t1), std::end(t1));
+        C c2;
+        c1.remove(0);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5};
+        const T t2[] = {5, 5, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.remove(0);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c1;
+        C c2;
+        c1.remove(0);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5, 0};
+        const T t2[] = {5, 5, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.remove(0);
+        assert(c1 == c2);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp
index a8d3b15..93b8ad8 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp
@@ -15,6 +15,8 @@
 #include <iterator>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 bool g(int i)
 {
     return i < 3;
@@ -69,4 +71,53 @@
         c1.remove_if(g);
         assert(c1 == c2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 5, 5, 0, 0, 0, 5};
+        const T t2[] = {5, 5, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.remove_if(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 0, 0, 0};
+        C c1(std::begin(t1), std::end(t1));
+        C c2;
+        c1.remove_if(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5};
+        const T t2[] = {5, 5, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.remove_if(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c1;
+        C c2;
+        c1.remove_if(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5, 0};
+        const T t2[] = {5, 5, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.remove_if(g);
+        assert(c1 == c2);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp
index 1a1e444..b707c19 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/reverse.pass.cpp
@@ -16,16 +16,17 @@
 #include <algorithm>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
+template <class C>
 void test(int N)
 {
-    typedef int T;
-    typedef std::forward_list<T> C;
     C c;
     for (int i = 0; i < N; ++i)
         c.push_front(i);
     c.reverse();
     assert(distance(c.begin(), c.end()) == N);
-    C::const_iterator j = c.begin();
+    typename C::const_iterator j = c.begin();
     for (int i = 0; i < N; ++i, ++j)
         assert(*j == i);
 }
@@ -33,5 +34,9 @@
 int main()
 {
     for (int i = 0; i < 10; ++i)
-        test(i);
+        test<std::forward_list<int> >(i);
+#if __cplusplus >= 201103L
+    for (int i = 0; i < 10; ++i)
+        test<std::forward_list<int, min_allocator<int>> >(i);
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp
index 6badaf7..9a8bd17 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/sort.pass.cpp
@@ -17,10 +17,12 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
+template <class C>
 void test(int N)
 {
-    typedef int T;
-    typedef std::forward_list<T> C;
+    typedef typename C::value_type T;
     typedef std::vector<T> V;
     V v;
     for (int i = 0; i < N; ++i)
@@ -29,7 +31,7 @@
     C c(v.begin(), v.end());
     c.sort();
     assert(distance(c.begin(), c.end()) == N);
-    C::const_iterator j = c.begin();
+    typename C::const_iterator j = c.begin();
     for (int i = 0; i < N; ++i, ++j)
         assert(*j == i);
 }
@@ -37,5 +39,9 @@
 int main()
 {
     for (int i = 0; i < 40; ++i)
-        test(i);
+        test<std::forward_list<int> >(i);
+#if __cplusplus >= 201103L
+    for (int i = 0; i < 40; ++i)
+        test<std::forward_list<int, min_allocator<int>> >(i);
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp
index dbc58f3..8524439 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/sort_pred.pass.cpp
@@ -18,10 +18,12 @@
 #include <functional>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
+template <class C>
 void test(int N)
 {
-    typedef int T;
-    typedef std::forward_list<T> C;
+    typedef typename C::value_type T;
     typedef std::vector<T> V;
     V v;
     for (int i = 0; i < N; ++i)
@@ -30,7 +32,7 @@
     C c(v.begin(), v.end());
     c.sort(std::greater<T>());
     assert(distance(c.begin(), c.end()) == N);
-    C::const_iterator j = c.begin();
+    typename C::const_iterator j = c.begin();
     for (int i = 0; i < N; ++i, ++j)
         assert(*j == N-1-i);
 }
@@ -38,5 +40,9 @@
 int main()
 {
     for (int i = 0; i < 40; ++i)
-        test(i);
+        test<std::forward_list<int> >(i);
+#if __cplusplus >= 201103L
+    for (int i = 0; i < 40; ++i)
+        test<std::forward_list<int, min_allocator<int>> >(i);
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp
index 794180b..0fee4a4 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_flist.pass.cpp
@@ -15,17 +15,19 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 typedef int T;
-typedef std::forward_list<T> C;
 const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7};
 const T t2[] = {10, 11, 12, 13, 14, 15};
 const int size_t1 = std::end(t1) - std::begin(t1);
 const int size_t2 = std::end(t2) - std::begin(t2);
 
+template <class C>
 void
 testd(const C& c, int p, int l)
 {
-    C::const_iterator i = c.begin();
+    typename C::const_iterator i = c.begin();
     int n1 = 0;
     for (; n1 < p; ++n1, ++i)
         assert(*i == t1[n1]);
@@ -38,7 +40,9 @@
 
 int main()
 {
+    {
     // splicing different containers
+    typedef std::forward_list<T> C;
     for (int l = 0; l <= size_t2; ++l)
     {
         for (int p = 0; p <= size_t1; ++p)
@@ -50,4 +54,22 @@
             testd(c1, p, l);
         }
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    // splicing different containers
+    typedef std::forward_list<T, min_allocator<T>> C;
+    for (int l = 0; l <= size_t2; ++l)
+    {
+        for (int p = 0; p <= size_t1; ++p)
+        {
+            C c1(std::begin(t1), std::end(t1));
+            C c2(t2, t2+l);
+
+            c1.splice_after(next(c1.cbefore_begin(), p), std::move(c2));
+            testd(c1, p, l);
+        }
+    }
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp
index cebb71b..6e75d49 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp
@@ -15,17 +15,19 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 typedef int T;
-typedef std::forward_list<T> C;
 const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7};
 const T t2[] = {10, 11, 12};
 const int size_t1 = std::end(t1) - std::begin(t1);
 const int size_t2 = std::end(t2) - std::begin(t2);
 
+template <class C>
 void
 testd(const C& c, int p, int f)
 {
-    C::const_iterator i = c.begin();
+    typename C::const_iterator i = c.begin();
     int n1 = 0;
     for (; n1 < p; ++n1, ++i)
         assert(*i == t1[n1]);
@@ -36,10 +38,11 @@
     assert(distance(c.begin(), c.end()) == size_t1 + 1);
 }
 
+template <class C>
 void
 tests(const C& c, int p, int f)
 {
-    C::const_iterator i = c.begin();
+    typename C::const_iterator i = c.begin();
     int n = 0;
     int d = 1;
     if (p == f || p == f+1)
@@ -74,7 +77,9 @@
 
 int main()
 {
+    {
     // splicing different containers
+    typedef std::forward_list<T> C;
     for (int f = 0; f <= size_t2-1; ++f)
     {
         for (int p = 0; p <= size_t1; ++p)
@@ -100,4 +105,36 @@
             tests(c1, p, f);
         }
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    // splicing different containers
+    typedef std::forward_list<T, min_allocator<T>> C;
+    for (int f = 0; f <= size_t2-1; ++f)
+    {
+        for (int p = 0; p <= size_t1; ++p)
+        {
+            C c1(std::begin(t1), std::end(t1));
+            C c2(std::begin(t2), std::end(t2));
+
+            c1.splice_after(next(c1.cbefore_begin(), p), std::move(c2),
+                  next(c2.cbefore_begin(), f));
+            testd(c1, p, f);
+        }
+    }
+
+    // splicing within same container
+    for (int f = 0; f <= size_t1-1; ++f)
+    {
+        for (int p = 0; p <= size_t1; ++p)
+        {
+            C c1(std::begin(t1), std::end(t1));
+
+            c1.splice_after(next(c1.cbefore_begin(), p), std::move(c1),
+                  next(c1.cbefore_begin(), f));
+            tests(c1, p, f);
+        }
+    }
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp
index 0851ee1..0c61280 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/splice_after_range.pass.cpp
@@ -16,17 +16,19 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../../min_allocator.h"
+
 typedef int T;
-typedef std::forward_list<T> C;
 const T t1[] = {0, 1, 2, 3, 4, 5, 6, 7};
 const T t2[] = {10, 11, 12, 13, 14, 15};
 const int size_t1 = std::end(t1) - std::begin(t1);
 const int size_t2 = std::end(t2) - std::begin(t2);
 
+template <class C>
 void
 testd(const C& c, int p, int f, int l)
 {
-    C::const_iterator i = c.begin();
+    typename C::const_iterator i = c.begin();
     int n1 = 0;
     for (; n1 < p; ++n1, ++i)
         assert(*i == t1[n1]);
@@ -37,10 +39,11 @@
     assert(distance(c.begin(), c.end()) == size_t1 + (l > f+1 ? l-1-f : 0));
 }
 
+template <class C>
 void
 tests(const C& c, int p, int f, int l)
 {
-    C::const_iterator i = c.begin();
+    typename C::const_iterator i = c.begin();
     int n = 0;
     int d = l > f+1 ? l-1-f : 0;
     if (d == 0 || p == f)
@@ -75,7 +78,9 @@
 
 int main()
 {
+    {
     // splicing different containers
+    typedef std::forward_list<T> C;
     for (int f = 0; f <= size_t2+1; ++f)
     {
         for (int l = f; l <= size_t2+1; ++l)
@@ -115,4 +120,50 @@
             }
         }
     }
+    }
+#if __cplusplus >= 201103L
+    {
+    // splicing different containers
+    typedef std::forward_list<T, min_allocator<T>> C;
+    for (int f = 0; f <= size_t2+1; ++f)
+    {
+        for (int l = f; l <= size_t2+1; ++l)
+        {
+            for (int p = 0; p <= size_t1; ++p)
+            {
+                C c1(std::begin(t1), std::end(t1));
+                C c2(std::begin(t2), std::end(t2));
+
+                c1.splice_after(next(c1.cbefore_begin(), p), std::move(c2),
+                      next(c2.cbefore_begin(), f), next(c2.cbefore_begin(), l));
+                testd(c1, p, f, l);
+            }
+        }
+    }
+
+    // splicing within same container
+    for (int f = 0; f <= size_t1+1; ++f)
+    {
+        for (int l = f; l <= size_t1; ++l)
+        {
+            for (int p = 0; p <= f; ++p)
+            {
+                C c1(std::begin(t1), std::end(t1));
+
+                c1.splice_after(next(c1.cbefore_begin(), p), std::move(c1),
+                      next(c1.cbefore_begin(), f), next(c1.cbefore_begin(), l));
+                tests(c1, p, f, l);
+            }
+            for (int p = l; p <= size_t1; ++p)
+            {
+                C c1(std::begin(t1), std::end(t1));
+
+                c1.splice_after(next(c1.cbefore_begin(), p), std::move(c1),
+                      next(c1.cbefore_begin(), f), next(c1.cbefore_begin(), l));
+                tests(c1, p, f, l);
+            }
+        }
+    }
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/unique.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/unique.pass.cpp
index 023fe92..9c95dc9 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/unique.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/unique.pass.cpp
@@ -15,6 +15,8 @@
 #include <iterator>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -65,4 +67,54 @@
         c1.unique();
         assert(c1 == c2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 5, 5, 0, 0, 0, 5};
+        const T t2[] = {0, 5, 0, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique();
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 0, 0, 0};
+        const T t2[] = {0};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique();
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5};
+        const T t2[] = {5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique();
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c1;
+        C c2;
+        c1.unique();
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5, 0};
+        const T t2[] = {5, 0};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique();
+        assert(c1 == c2);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp
index 3ac98e7..f956f27 100644
--- a/test/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.ops/unique_pred.pass.cpp
@@ -15,6 +15,8 @@
 #include <iterator>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 bool g(int x, int y)
 {
     return x == y;
@@ -70,4 +72,54 @@
         c1.unique(g);
         assert(c1 == c2);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 5, 5, 0, 0, 0, 5};
+        const T t2[] = {0, 5, 0, 5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {0, 0, 0, 0};
+        const T t2[] = {0};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5};
+        const T t2[] = {5};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c1;
+        C c2;
+        c1.unique(g);
+        assert(c1 == c2);
+    }
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        const T t1[] = {5, 5, 5, 0};
+        const T t2[] = {5, 0};
+        C c1(std::begin(t1), std::end(t1));
+        C c2(std::begin(t2), std::end(t2));
+        c1.unique(g);
+        assert(c1 == c2);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp
index 244ed34..485d89e 100644
--- a/test/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp
@@ -22,10 +22,12 @@
 #include <algorithm>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
+template <class C>
 void test(int N, int M)
 {
-    typedef int T;
-    typedef std::forward_list<T> C;
+    typedef typename C::value_type T;
     C c1;
     for (int i = 0; i < N; ++i)
         c1.push_front(i);
@@ -49,5 +51,10 @@
 {
     for (int i = 0; i < 10; ++i)
         for (int j = 0; j < 10; ++j)
-            test(i, j);
+            test<std::forward_list<int> >(i, j);
+#if __cplusplus >= 201103L
+    for (int i = 0; i < 10; ++i)
+        for (int j = 0; j < 10; ++j)
+            test<std::forward_list<int, min_allocator<int>> >(i, j);
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp
index 5327263..da27cc9 100644
--- a/test/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.spec/member_swap.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -175,4 +176,84 @@
         assert(distance(c2.begin(), c2.end()) == 0);
         assert(c2.get_allocator() == A(1));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        const T t1[] = {0, 1, 2, 3, 4, 5};
+        C c1(std::begin(t1), std::end(t1), A());
+        const T t2[] = {10, 11, 12};
+        C c2(std::begin(t2), std::end(t2), A());
+        c1.swap(c2);
+
+        assert(distance(c1.begin(), c1.end()) == 3);
+        assert(*next(c1.begin(), 0) == 10);
+        assert(*next(c1.begin(), 1) == 11);
+        assert(*next(c1.begin(), 2) == 12);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 6);
+        assert(*next(c2.begin(), 0) == 0);
+        assert(*next(c2.begin(), 1) == 1);
+        assert(*next(c2.begin(), 2) == 2);
+        assert(*next(c2.begin(), 3) == 3);
+        assert(*next(c2.begin(), 4) == 4);
+        assert(*next(c2.begin(), 5) == 5);
+        assert(c2.get_allocator() == A());
+    }
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        const T t1[] = {0, 1, 2, 3, 4, 5};
+        C c1(std::begin(t1), std::end(t1), A());
+        C c2(A{});
+        c1.swap(c2);
+
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 6);
+        assert(*next(c2.begin(), 0) == 0);
+        assert(*next(c2.begin(), 1) == 1);
+        assert(*next(c2.begin(), 2) == 2);
+        assert(*next(c2.begin(), 3) == 3);
+        assert(*next(c2.begin(), 4) == 4);
+        assert(*next(c2.begin(), 5) == 5);
+        assert(c2.get_allocator() == A());
+    }
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        C c1(A{});
+        const T t2[] = {10, 11, 12};
+        C c2(std::begin(t2), std::end(t2), A());
+        c1.swap(c2);
+
+        assert(distance(c1.begin(), c1.end()) == 3);
+        assert(*next(c1.begin(), 0) == 10);
+        assert(*next(c1.begin(), 1) == 11);
+        assert(*next(c1.begin(), 2) == 12);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 0);
+        assert(c2.get_allocator() == A());
+    }
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        C c1(A{});
+        C c2(A{});
+        c1.swap(c2);
+
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 0);
+        assert(c2.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp
index 9963cf8..115a369 100644
--- a/test/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.spec/non_member_swap.pass.cpp
@@ -16,6 +16,7 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -176,4 +177,84 @@
         assert(distance(c2.begin(), c2.end()) == 0);
         assert(c2.get_allocator() == A(1));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        const T t1[] = {0, 1, 2, 3, 4, 5};
+        C c1(std::begin(t1), std::end(t1), A());
+        const T t2[] = {10, 11, 12};
+        C c2(std::begin(t2), std::end(t2), A());
+        swap(c1, c2);
+
+        assert(distance(c1.begin(), c1.end()) == 3);
+        assert(*next(c1.begin(), 0) == 10);
+        assert(*next(c1.begin(), 1) == 11);
+        assert(*next(c1.begin(), 2) == 12);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 6);
+        assert(*next(c2.begin(), 0) == 0);
+        assert(*next(c2.begin(), 1) == 1);
+        assert(*next(c2.begin(), 2) == 2);
+        assert(*next(c2.begin(), 3) == 3);
+        assert(*next(c2.begin(), 4) == 4);
+        assert(*next(c2.begin(), 5) == 5);
+        assert(c2.get_allocator() == A());
+    }
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        const T t1[] = {0, 1, 2, 3, 4, 5};
+        C c1(std::begin(t1), std::end(t1), A());
+        C c2(A{});
+        swap(c1, c2);
+
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 6);
+        assert(*next(c2.begin(), 0) == 0);
+        assert(*next(c2.begin(), 1) == 1);
+        assert(*next(c2.begin(), 2) == 2);
+        assert(*next(c2.begin(), 3) == 3);
+        assert(*next(c2.begin(), 4) == 4);
+        assert(*next(c2.begin(), 5) == 5);
+        assert(c2.get_allocator() == A());
+    }
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        C c1(A{});
+        const T t2[] = {10, 11, 12};
+        C c2(std::begin(t2), std::end(t2), A());
+        swap(c1, c2);
+
+        assert(distance(c1.begin(), c1.end()) == 3);
+        assert(*next(c1.begin(), 0) == 10);
+        assert(*next(c1.begin(), 1) == 11);
+        assert(*next(c1.begin(), 2) == 12);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 0);
+        assert(c2.get_allocator() == A());
+    }
+    {
+        typedef int T;
+        typedef min_allocator<T> A;
+        typedef std::forward_list<T, A> C;
+        C c1(A{});
+        C c2(A{});
+        swap(c1, c2);
+
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert(c1.get_allocator() == A());
+
+        assert(distance(c2.begin(), c2.end()) == 0);
+        assert(c2.get_allocator() == A());
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp b/test/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp
index 717ea5a..7823693 100644
--- a/test/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp
+++ b/test/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp
@@ -30,10 +30,12 @@
 #include <algorithm>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
+template <class C>
 void test(int N, int M)
 {
-    typedef int T;
-    typedef std::forward_list<T> C;
+    typedef typename C::value_type T;
     C c1;
     for (int i = 0; i < N; ++i)
         c1.push_front(i);
@@ -54,5 +56,10 @@
 {
     for (int i = 0; i < 10; ++i)
         for (int j = 0; j < 10; ++j)
-            test(i, j);
+            test<std::forward_list<int> >(i, j);
+#if __cplusplus >= 201103L
+    for (int i = 0; i < 10; ++i)
+        for (int j = 0; j < 10; ++j)
+            test<std::forward_list<int, min_allocator<int>> >(i, j);
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/max_size.pass.cpp b/test/containers/sequences/forwardlist/max_size.pass.cpp
index d942b96..96883b5 100644
--- a/test/containers/sequences/forwardlist/max_size.pass.cpp
+++ b/test/containers/sequences/forwardlist/max_size.pass.cpp
@@ -14,6 +14,8 @@
 #include <forward_list>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -22,4 +24,12 @@
         C c;
         assert(c.max_size() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::forward_list<T, min_allocator<T>> C;
+        C c;
+        assert(c.max_size() > 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/forwardlist/types.pass.cpp b/test/containers/sequences/forwardlist/types.pass.cpp
index d91dc69..d812f8a 100644
--- a/test/containers/sequences/forwardlist/types.pass.cpp
+++ b/test/containers/sequences/forwardlist/types.pass.cpp
@@ -28,6 +28,8 @@
 #include <forward_list>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     static_assert((std::is_same<std::forward_list<char>::value_type, char>::value), "");
@@ -38,4 +40,14 @@
     static_assert((std::is_same<std::forward_list<char>::const_pointer, const char*>::value), "");
     static_assert((std::is_same<std::forward_list<char>::size_type, std::size_t>::value), "");
     static_assert((std::is_same<std::forward_list<char>::difference_type, std::ptrdiff_t>::value), "");
+#if __cplusplus >= 201103L
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::value_type, char>::value), "");
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::allocator_type, min_allocator<char> >::value), "");
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::reference, char&>::value), "");
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::const_reference, const char&>::value), "");
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::pointer, min_pointer<char>>::value), "");
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::const_pointer, min_pointer<const char>>::value), "");
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::size_type, std::size_t>::value), "");
+    static_assert((std::is_same<std::forward_list<char, min_allocator<char>>::difference_type, std::ptrdiff_t>::value), "");
+#endif
 }
diff --git a/test/containers/sequences/list/db_back.pass.cpp b/test/containers/sequences/list/db_back.pass.cpp
index ef8e692..22a7eac 100644
--- a/test/containers/sequences/list/db_back.pass.cpp
+++ b/test/containers/sequences/list/db_back.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call back() on empty container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::list<T> C;
     C c(1);
@@ -30,6 +33,18 @@
     c.clear();
     assert(c.back() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::list<T, min_allocator<T>> C;
+    C c(1);
+    assert(c.back() == 0);
+    c.clear();
+    assert(c.back() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/db_cback.pass.cpp b/test/containers/sequences/list/db_cback.pass.cpp
index dc40b47..613b4f1 100644
--- a/test/containers/sequences/list/db_cback.pass.cpp
+++ b/test/containers/sequences/list/db_cback.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call back() on empty const container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,13 +21,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::list<T> C;
     const C c;
     assert(c.back() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::list<T, min_allocator<T>> C;
+    const C c;
+    assert(c.back() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/db_cfront.pass.cpp b/test/containers/sequences/list/db_cfront.pass.cpp
index aa5ab98..2646fe1 100644
--- a/test/containers/sequences/list/db_cfront.pass.cpp
+++ b/test/containers/sequences/list/db_cfront.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call front() on empty const container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,13 +21,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::list<T> C;
     const C c;
     assert(c.front() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::list<T, min_allocator<T>> C;
+    const C c;
+    assert(c.front() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/db_front.pass.cpp b/test/containers/sequences/list/db_front.pass.cpp
index fc37c5a..f7c3dfc 100644
--- a/test/containers/sequences/list/db_front.pass.cpp
+++ b/test/containers/sequences/list/db_front.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call front() on empty container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::list<T> C;
     C c(1);
@@ -30,6 +33,18 @@
     c.clear();
     assert(c.front() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::list<T, min_allocator<T>> C;
+    C c(1);
+    assert(c.front() == 0);
+    c.clear();
+    assert(c.front() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/db_iterators_6.pass.cpp b/test/containers/sequences/list/db_iterators_6.pass.cpp
index c64b438..9528d75 100644
--- a/test/containers/sequences/list/db_iterators_6.pass.cpp
+++ b/test/containers/sequences/list/db_iterators_6.pass.cpp
@@ -11,7 +11,7 @@
 
 // Decrement iterator prior to begin.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::list<T> C;
     C c(1);
@@ -31,6 +34,19 @@
     assert(i == c.begin());
     --i;
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::list<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.end();
+    --i;
+    assert(i == c.begin());
+    --i;
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/db_iterators_7.pass.cpp b/test/containers/sequences/list/db_iterators_7.pass.cpp
index 0d61b23..795ffa7 100644
--- a/test/containers/sequences/list/db_iterators_7.pass.cpp
+++ b/test/containers/sequences/list/db_iterators_7.pass.cpp
@@ -11,7 +11,7 @@
 
 // Increment iterator past end.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::list<T> C;
     C c(1);
@@ -31,6 +34,19 @@
     assert(i == c.end());
     ++i;
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::list<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/db_iterators_8.pass.cpp b/test/containers/sequences/list/db_iterators_8.pass.cpp
index b05c3ab..2c34723 100644
--- a/test/containers/sequences/list/db_iterators_8.pass.cpp
+++ b/test/containers/sequences/list/db_iterators_8.pass.cpp
@@ -11,7 +11,7 @@
 
 // Dereference non-dereferenceable iterator.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,14 +21,28 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::list<T> C;
     C c(1);
     C::iterator i = c.end();
     T j = *i;
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::list<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/db_iterators_9.pass.cpp b/test/containers/sequences/list/db_iterators_9.pass.cpp
new file mode 100644
index 0000000..d02fcd6
--- /dev/null
+++ b/test/containers/sequences/list/db_iterators_9.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <list>
+
+// Operations on "NULL" iterators
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) do { if (!x) throw 1; } while(0)
+
+#include <list>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+struct S { int val; };
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+    {
+    unsigned lib_asserts;
+
+    typedef S T;
+    typedef std::list<T> C;
+    C::iterator i{};
+    C::const_iterator ci{};
+    
+    lib_asserts = 0;
+    try { ++i; }  catch (int) { ++lib_asserts; }
+    try { i++; }  catch (int) { ++lib_asserts; }
+    try { ++ci; } catch (int) { ++lib_asserts; }
+    try { ci++; } catch (int) { ++lib_asserts; }
+    assert(lib_asserts == 4);
+
+    lib_asserts = 0;
+    try { --i; }  catch (int) { ++lib_asserts; }
+    try { i--; }  catch (int) { ++lib_asserts; }
+    try { --ci; } catch (int) { ++lib_asserts; }
+    try { ci--; } catch (int) { ++lib_asserts; }
+    assert(lib_asserts == 4);
+
+    lib_asserts = 0;
+    try { *i; }             catch (int) { ++lib_asserts; }
+    try { *ci; }            catch (int) { ++lib_asserts; }
+    try { (void)  i->val; } catch (int) { ++lib_asserts; }
+    try { (void) ci->val; } catch (int) { ++lib_asserts; }
+    assert(lib_asserts == 4);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/sequences/list/iterators.pass.cpp b/test/containers/sequences/list/iterators.pass.cpp
index a53e977..9f6a51b 100644
--- a/test/containers/sequences/list/iterators.pass.cpp
+++ b/test/containers/sequences/list/iterators.pass.cpp
@@ -20,6 +20,14 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../min_allocator.h"
+
+struct A
+{
+    int first;
+    int second;
+};
+
 int main()
 {
     {
@@ -69,4 +77,80 @@
         C::iterator i;
         C::const_iterator j;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::list<T, min_allocator<T>> C;
+        C c;
+        C::iterator i = c.begin();
+        C::iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef int T;
+        typedef std::list<T, min_allocator<T>> C;
+        const C c;
+        C::const_iterator i = c.begin();
+        C::const_iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef int T;
+        typedef std::list<T, min_allocator<T>> C;
+        C c;
+        C::const_iterator i = c.cbegin();
+        C::const_iterator j = c.cend();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+        assert(i == c.end());
+    }
+    {
+        typedef int T;
+        typedef std::list<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        C::iterator i = c.begin();
+        assert(*i == 0);
+        ++i;
+        assert(*i == 1);
+        *i = 10;
+        assert(*i == 10);
+        assert(std::distance(c.begin(), c.end()) == 10);
+    }
+    {
+        typedef int T;
+        typedef std::list<T, min_allocator<T>> C;
+        C::iterator i;
+        C::const_iterator j;
+    }
+    {
+        typedef A T;
+        typedef std::list<T, min_allocator<T>> C;
+        C c = {A{1, 2}};
+        C::iterator i = c.begin();
+        i->first = 3;
+        C::const_iterator j = i;
+        assert(j->first == 3);
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    {
+        std::list<int> c;
+        std::list<int>::iterator ii1{}, ii2{};
+        std::list<int>::iterator ii4 = ii1;
+        std::list<int>::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+
+        assert ( ii1 != c.cbegin());
+        assert ( cii != c.begin());
+    }
+#endif
+
 }
diff --git a/test/containers/sequences/list/list.capacity/resize_size.pass.cpp b/test/containers/sequences/list/list.capacity/resize_size.pass.cpp
index 93fc26c..d5135ee 100644
--- a/test/containers/sequences/list/list.capacity/resize_size.pass.cpp
+++ b/test/containers/sequences/list/list.capacity/resize_size.pass.cpp
@@ -14,6 +14,7 @@
 #include <list>
 #include <cassert>
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,35 @@
         assert(std::distance(l.begin(), l.end()) == 20);
     }
 #endif  // __LIBCPP_MOVE
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l(5, 2);
+        l.resize(2);
+        assert(l.size() == 2);
+        assert(std::distance(l.begin(), l.end()) == 2);
+        assert((l == std::list<int, min_allocator<int>>(2, 2)));
+    }
+    {
+        std::list<int, min_allocator<int>> l(5, 2);
+        l.resize(10);
+        assert(l.size() == 10);
+        assert(std::distance(l.begin(), l.end()) == 10);
+        assert(l.front() == 2);
+        assert(l.back() == 0);
+    }
+#ifdef __LIBCPP_MOVE
+    {
+        std::list<DefaultOnly, min_allocator<DefaultOnly>> l(10);
+        l.resize(5);
+        assert(l.size() == 5);
+        assert(std::distance(l.begin(), l.end()) == 5);
+    }
+    {
+        std::list<DefaultOnly, min_allocator<DefaultOnly>> l(10);
+        l.resize(20);
+        assert(l.size() == 20);
+        assert(std::distance(l.begin(), l.end()) == 20);
+    }
+#endif  // __LIBCPP_MOVE
+#endif
 }
diff --git a/test/containers/sequences/list/list.capacity/resize_size_value.pass.cpp b/test/containers/sequences/list/list.capacity/resize_size_value.pass.cpp
index 1779d46..dbe2c3f 100644
--- a/test/containers/sequences/list/list.capacity/resize_size_value.pass.cpp
+++ b/test/containers/sequences/list/list.capacity/resize_size_value.pass.cpp
@@ -14,6 +14,7 @@
 #include <list>
 #include <cassert>
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -32,4 +33,21 @@
         assert(l.front() == 2);
         assert(l.back() == 3.5);
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<double, min_allocator<double>> l(5, 2);
+        l.resize(2, 3.5);
+        assert(l.size() == 2);
+        assert(std::distance(l.begin(), l.end()) == 2);
+        assert((l == std::list<double, min_allocator<double>>(2, 2)));
+    }
+    {
+        std::list<double, min_allocator<double>> l(5, 2);
+        l.resize(10, 3.5);
+        assert(l.size() == 10);
+        assert(std::distance(l.begin(), l.end()) == 10);
+        assert(l.front() == 2);
+        assert(l.back() == 3.5);
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/assign_copy.pass.cpp b/test/containers/sequences/list/list.cons/assign_copy.pass.cpp
index 3233e3e..422436a 100644
--- a/test/containers/sequences/list/list.cons/assign_copy.pass.cpp
+++ b/test/containers/sequences/list/list.cons/assign_copy.pass.cpp
@@ -14,6 +14,7 @@
 #include <list>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -31,4 +32,13 @@
         assert(l2 == l);
         assert(l2.get_allocator() == other_allocator<int>(5));
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int> > l(3, 2, min_allocator<int>());
+        std::list<int, min_allocator<int> > l2(l, min_allocator<int>());
+        l2 = l;
+        assert(l2 == l);
+        assert(l2.get_allocator() == min_allocator<int>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp b/test/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp
index 9721ad2..e438f40 100644
--- a/test/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::list<int> d;
     d.assign({3, 4, 5, 6});
     assert(d.size() == 4);
@@ -25,5 +28,18 @@
     assert(*i++ == 4);
     assert(*i++ == 5);
     assert(*i++ == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<int, min_allocator<int>> d;
+    d.assign({3, 4, 5, 6});
+    assert(d.size() == 4);
+    std::list<int, min_allocator<int>>::iterator i = d.begin();
+    assert(*i++ == 3);
+    assert(*i++ == 4);
+    assert(*i++ == 5);
+    assert(*i++ == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/list/list.cons/assign_move.pass.cpp b/test/containers/sequences/list/list.cons/assign_move.pass.cpp
index beeacb5..da788dd 100644
--- a/test/containers/sequences/list/list.cons/assign_move.pass.cpp
+++ b/test/containers/sequences/list/list.cons/assign_move.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -61,5 +62,21 @@
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
+        std::list<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::list<MoveOnly, min_allocator<MoveOnly> > l2(min_allocator<MoveOnly>{});
+        l2 = std::move(l);
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == lo.get_allocator());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/list/list.cons/copy.pass.cpp b/test/containers/sequences/list/list.cons/copy.pass.cpp
index 5fea3f5..b490eba 100644
--- a/test/containers/sequences/list/list.cons/copy.pass.cpp
+++ b/test/containers/sequences/list/list.cons/copy.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../DefaultOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -37,4 +38,17 @@
         assert(l2.get_allocator() == other_allocator<int>(-2));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l(3, 2);
+        std::list<int, min_allocator<int>> l2 = l;
+        assert(l2 == l);
+    }
+    {
+        std::list<int, min_allocator<int> > l(3, 2, min_allocator<int>());
+        std::list<int, min_allocator<int> > l2 = l;
+        assert(l2 == l);
+        assert(l2.get_allocator() == l.get_allocator());
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/copy_alloc.pass.cpp b/test/containers/sequences/list/list.cons/copy_alloc.pass.cpp
index 453c4b5..30eb9ff 100644
--- a/test/containers/sequences/list/list.cons/copy_alloc.pass.cpp
+++ b/test/containers/sequences/list/list.cons/copy_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../DefaultOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -30,4 +31,12 @@
         assert(l2 == l);
         assert(l2.get_allocator() == other_allocator<int>(3));
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int> > l(3, 2, min_allocator<int>());
+        std::list<int, min_allocator<int> > l2(l, min_allocator<int>());
+        assert(l2 == l);
+        assert(l2.get_allocator() == min_allocator<int>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/default.pass.cpp b/test/containers/sequences/list/list.cons/default.pass.cpp
index 97eedf4..a6e193c 100644
--- a/test/containers/sequences/list/list.cons/default.pass.cpp
+++ b/test/containers/sequences/list/list.cons/default.pass.cpp
@@ -14,6 +14,7 @@
 #include <list>
 #include <cassert>
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -32,4 +33,21 @@
         assert(l.size() == 0);
         assert(std::distance(l.begin(), l.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l;
+        assert(l.size() == 0);
+        assert(std::distance(l.begin(), l.end()) == 0);
+    }
+    {
+        std::list<DefaultOnly, min_allocator<DefaultOnly>> l;
+        assert(l.size() == 0);
+        assert(std::distance(l.begin(), l.end()) == 0);
+    }
+    {
+        std::list<int, min_allocator<int>> l((min_allocator<int>()));
+        assert(l.size() == 0);
+        assert(std::distance(l.begin(), l.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp b/test/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp
index 29b8936..ef42e52 100644
--- a/test/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp
+++ b/test/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp
@@ -14,8 +14,7 @@
 #include <list>
 #include <cassert>
 #include "../../../stack_allocator.h"
-
-#include <iostream>
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -34,4 +33,16 @@
         assert(l.size() == 0);
         assert(std::distance(l.begin(), l.end()) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l;
+        assert(l.size() == 0);
+        assert(std::distance(l.begin(), l.end()) == 0);
+    }
+    {
+        std::list<int, min_allocator<int>> l((min_allocator<int>()));
+        assert(l.size() == 0);
+        assert(std::distance(l.begin(), l.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/initializer_list.pass.cpp b/test/containers/sequences/list/list.cons/initializer_list.pass.cpp
index d111a25..f862eed 100644
--- a/test/containers/sequences/list/list.cons/initializer_list.pass.cpp
+++ b/test/containers/sequences/list/list.cons/initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::list<int> d = {3, 4, 5, 6};
     assert(d.size() == 4);
     std::list<int>::iterator i = d.begin();
@@ -24,5 +27,17 @@
     assert(*i++ == 4);
     assert(*i++ == 5);
     assert(*i++ == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<int, min_allocator<int>> d = {3, 4, 5, 6};
+    assert(d.size() == 4);
+    std::list<int, min_allocator<int>>::iterator i = d.begin();
+    assert(*i++ == 3);
+    assert(*i++ == 4);
+    assert(*i++ == 5);
+    assert(*i++ == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp b/test/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp
index 7f302ed..649610a 100644
--- a/test/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp
+++ b/test/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::list<int, test_allocator<int>> d({3, 4, 5, 6}, test_allocator<int>(3));
     assert(d.get_allocator() == test_allocator<int>(3));
     assert(d.size() == 4);
@@ -27,5 +29,18 @@
     assert(*i++ == 4);
     assert(*i++ == 5);
     assert(*i++ == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<int, min_allocator<int>> d({3, 4, 5, 6}, min_allocator<int>());
+    assert(d.get_allocator() == min_allocator<int>());
+    assert(d.size() == 4);
+    std::list<int, min_allocator<int>>::iterator i = d.begin();
+    assert(*i++ == 3);
+    assert(*i++ == 4);
+    assert(*i++ == 5);
+    assert(*i++ == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/list/list.cons/input_iterator.pass.cpp b/test/containers/sequences/list/list.cons/input_iterator.pass.cpp
index 859f6bc..b5d8dcb 100644
--- a/test/containers/sequences/list/list.cons/input_iterator.pass.cpp
+++ b/test/containers/sequences/list/list.cons/input_iterator.pass.cpp
@@ -16,6 +16,7 @@
 #include <cassert>
 #include "test_iterators.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -50,4 +51,27 @@
         for (std::list<int>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j)
             assert(*i == j);
     }
+#if __cplusplus >= 201103L
+    {
+        int a[] = {0, 1, 2, 3};
+        std::list<int, min_allocator<int>> l(input_iterator<const int*>(a),
+                         input_iterator<const int*>(a + sizeof(a)/sizeof(a[0])));
+        assert(l.size() == sizeof(a)/sizeof(a[0]));
+        assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0]));
+        int j = 0;
+        for (std::list<int, min_allocator<int>>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j)
+            assert(*i == j);
+    }
+    {
+        int a[] = {0, 1, 2, 3};
+        std::list<int, min_allocator<int>> l(input_iterator<const int*>(a),
+                         input_iterator<const int*>(a + sizeof(a)/sizeof(a[0])),
+                         min_allocator<int>());
+        assert(l.size() == sizeof(a)/sizeof(a[0]));
+        assert(std::distance(l.begin(), l.end()) == sizeof(a)/sizeof(a[0]));
+        int j = 0;
+        for (std::list<int, min_allocator<int>>::const_iterator i = l.begin(), e = l.end(); i != e; ++i, ++j)
+            assert(*i == j);
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/move.pass.cpp b/test/containers/sequences/list/list.cons/move.pass.cpp
index 5e76caf..f1c5a98 100644
--- a/test/containers/sequences/list/list.cons/move.pass.cpp
+++ b/test/containers/sequences/list/list.cons/move.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -45,5 +46,29 @@
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
+        std::list<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::list<MoveOnly, min_allocator<MoveOnly> > l2 = std::move(l);
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == lo.get_allocator());
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<int> l1 = {1, 2, 3};
+        std::list<int>::iterator i = l1.begin();
+        std::list<int> l2 = std::move(l1);
+        assert(*l2.erase(i) == 2);
+        assert(l2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/list/list.cons/move_alloc.pass.cpp b/test/containers/sequences/list/list.cons/move_alloc.pass.cpp
index 3206ea5..94711d4 100644
--- a/test/containers/sequences/list/list.cons/move_alloc.pass.cpp
+++ b/test/containers/sequences/list/list.cons/move_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -58,5 +59,20 @@
         assert(!l.empty());
         assert(l2.get_allocator() == other_allocator<MoveOnly>(4));
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
+        std::list<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::list<MoveOnly, min_allocator<MoveOnly> > l2(std::move(l), min_allocator<MoveOnly>());
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == min_allocator<MoveOnly>());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp b/test/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp
index a744f0f..f090043 100644
--- a/test/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp
+++ b/test/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp
@@ -13,10 +13,12 @@
 
 #include <list>
 #include <cassert>
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::list<int> d;
     d = {3, 4, 5, 6};
     assert(d.size() == 4);
@@ -25,5 +27,18 @@
     assert(*i++ == 4);
     assert(*i++ == 5);
     assert(*i++ == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<int, min_allocator<int>> d;
+    d = {3, 4, 5, 6};
+    assert(d.size() == 4);
+    std::list<int, min_allocator<int>>::iterator i = d.begin();
+    assert(*i++ == 3);
+    assert(*i++ == 4);
+    assert(*i++ == 5);
+    assert(*i++ == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/list/list.cons/size_type.pass.cpp b/test/containers/sequences/list/list.cons/size_type.pass.cpp
index f636a43..864b5ad 100644
--- a/test/containers/sequences/list/list.cons/size_type.pass.cpp
+++ b/test/containers/sequences/list/list.cons/size_type.pass.cpp
@@ -15,6 +15,24 @@
 #include <cassert>
 #include "../../../DefaultOnly.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
+
+template <class T, class Allocator>
+void
+test3(unsigned n, Allocator const &alloc = Allocator())
+{
+#if _LIBCPP_STD_VER > 11
+    typedef std::list<T, Allocator> C;
+    typedef typename C::const_iterator const_iterator;
+    {
+    C d(n, alloc);
+    assert(d.size() == n);
+    assert(std::distance(d.begin(), d.end()) == n);
+    assert(d.get_allocator() == alloc);
+    }
+#endif
+}
+
 
 int main()
 {
@@ -40,6 +58,21 @@
         ++i;
         assert(*i == 0);
     }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef std::list<int, min_allocator<int> > C;
+        C l(3, min_allocator<int> ());
+        assert(l.size() == 3);
+        assert(std::distance(l.begin(), l.end()) == 3);
+        C::const_iterator i = l.begin();
+        assert(*i == 0);
+        ++i;
+        assert(*i == 0);
+        ++i;
+        assert(*i == 0);
+        test3<int, min_allocator<int>> (3);
+    }
+#endif
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     {
         std::list<DefaultOnly> l(3);
@@ -47,4 +80,24 @@
         assert(std::distance(l.begin(), l.end()) == 3);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l(3);
+        assert(l.size() == 3);
+        assert(std::distance(l.begin(), l.end()) == 3);
+        std::list<int, min_allocator<int>>::const_iterator i = l.begin();
+        assert(*i == 0);
+        ++i;
+        assert(*i == 0);
+        ++i;
+        assert(*i == 0);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        std::list<DefaultOnly, min_allocator<DefaultOnly>> l(3);
+        assert(l.size() == 3);
+        assert(std::distance(l.begin(), l.end()) == 3);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/sequences/list/list.cons/size_value_alloc.pass.cpp b/test/containers/sequences/list/list.cons/size_value_alloc.pass.cpp
index 212777c..89cdf0e 100644
--- a/test/containers/sequences/list/list.cons/size_value_alloc.pass.cpp
+++ b/test/containers/sequences/list/list.cons/size_value_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../DefaultOnly.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -51,4 +52,28 @@
         ++i;
         assert(*i == 2);
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l(3, 2);
+        assert(l.size() == 3);
+        assert(std::distance(l.begin(), l.end()) == 3);
+        std::list<int, min_allocator<int>>::const_iterator i = l.begin();
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l(3, 2, min_allocator<int>());
+        assert(l.size() == 3);
+        assert(std::distance(l.begin(), l.end()) == 3);
+        std::list<int, min_allocator<int>>::const_iterator i = l.begin();
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/clear.pass.cpp b/test/containers/sequences/list/list.modifiers/clear.pass.cpp
index e3b63a2..5bfab6f 100644
--- a/test/containers/sequences/list/list.modifiers/clear.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/clear.pass.cpp
@@ -14,10 +14,22 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a[] = {1, 2, 3};
     std::list<int> c(a, a+3);
     c.clear();
     assert(c.empty());
+    }
+#if __cplusplus >= 201103L
+    {
+    int a[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> c(a, a+3);
+    c.clear();
+    assert(c.empty());
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/emplace.pass.cpp b/test/containers/sequences/list/list.modifiers/emplace.pass.cpp
index 218c42b..9f5edf5 100644
--- a/test/containers/sequences/list/list.modifiers/emplace.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/emplace.pass.cpp
@@ -11,13 +11,15 @@
 
 // template <class... Args> void emplace(const_iterator p, Args&&... args);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 class A
 {
     int i_;
@@ -36,6 +38,7 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     std::list<A> c;
     c.emplace(c.cbegin(), 2, 3.5);
     assert(c.size() == 1);
@@ -47,8 +50,8 @@
     assert(c.front().getd() == 3.5);
     assert(c.back().geti() == 3);
     assert(c.back().getd() == 4.5);
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#if _LIBCPP_DEBUG2 >= 1
+    }
+#if _LIBCPP_DEBUG >= 1
     {
         std::list<A> c1;
         std::list<A> c2;
@@ -56,4 +59,30 @@
         assert(false);
     }
 #endif
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+    std::list<A, min_allocator<A>> c;
+    c.emplace(c.cbegin(), 2, 3.5);
+    assert(c.size() == 1);
+    assert(c.front().geti() == 2);
+    assert(c.front().getd() == 3.5);
+    c.emplace(c.cend(), 3, 4.5);
+    assert(c.size() == 2);
+    assert(c.front().geti() == 2);
+    assert(c.front().getd() == 3.5);
+    assert(c.back().geti() == 3);
+    assert(c.back().getd() == 4.5);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<A, min_allocator<A>> c1;
+        std::list<A, min_allocator<A>> c2;
+        std::list<A, min_allocator<A>>::iterator i = c1.emplace(c2.cbegin(), 2, 3.5);
+        assert(false);
+    }
+#endif
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/emplace_back.pass.cpp b/test/containers/sequences/list/list.modifiers/emplace_back.pass.cpp
index 2802fe5..71bc671 100644
--- a/test/containers/sequences/list/list.modifiers/emplace_back.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/emplace_back.pass.cpp
@@ -14,6 +14,8 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 class A
 {
     int i_;
@@ -32,6 +34,7 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     std::list<A> c;
     c.emplace_back(2, 3.5);
     assert(c.size() == 1);
@@ -43,5 +46,21 @@
     assert(c.front().getd() == 3.5);
     assert(c.back().geti() == 3);
     assert(c.back().getd() == 4.5);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<A, min_allocator<A>> c;
+    c.emplace_back(2, 3.5);
+    assert(c.size() == 1);
+    assert(c.front().geti() == 2);
+    assert(c.front().getd() == 3.5);
+    c.emplace_back(3, 4.5);
+    assert(c.size() == 2);
+    assert(c.front().geti() == 2);
+    assert(c.front().getd() == 3.5);
+    assert(c.back().geti() == 3);
+    assert(c.back().getd() == 4.5);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/list/list.modifiers/emplace_front.pass.cpp b/test/containers/sequences/list/list.modifiers/emplace_front.pass.cpp
index 09fe68c..2eee9da 100644
--- a/test/containers/sequences/list/list.modifiers/emplace_front.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/emplace_front.pass.cpp
@@ -14,6 +14,8 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 class A
 {
     int i_;
@@ -32,6 +34,7 @@
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     std::list<A> c;
     c.emplace_front(2, 3.5);
     assert(c.size() == 1);
@@ -43,5 +46,21 @@
     assert(c.front().getd() == 4.5);
     assert(c.back().geti() == 2);
     assert(c.back().getd() == 3.5);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<A, min_allocator<A>> c;
+    c.emplace_front(2, 3.5);
+    assert(c.size() == 1);
+    assert(c.front().geti() == 2);
+    assert(c.front().getd() == 3.5);
+    c.emplace_front(3, 4.5);
+    assert(c.size() == 2);
+    assert(c.front().geti() == 3);
+    assert(c.front().getd() == 4.5);
+    assert(c.back().geti() == 2);
+    assert(c.back().getd() == 3.5);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter.pass.cpp
index deac04b..0c2e5a1 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter.pass.cpp
@@ -14,8 +14,11 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::list<int> l1(a1, a1+3);
     std::list<int>::const_iterator i = l1.begin();
@@ -35,4 +38,28 @@
     assert(j == l1.end());
     assert(l1.size() == 0);
     assert(distance(l1.begin(), l1.end()) == 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+    ++i;
+    std::list<int, min_allocator<int>>::iterator j = l1.erase(i);
+    assert(l1.size() == 2);
+    assert(distance(l1.begin(), l1.end()) == 2);
+    assert(*j == 3);
+    assert(*l1.begin() == 1);
+    assert(*next(l1.begin()) == 3);
+    j = l1.erase(j);
+    assert(j == l1.end());
+    assert(l1.size() == 1);
+    assert(distance(l1.begin(), l1.end()) == 1);
+    assert(*l1.begin() == 1);
+    j = l1.erase(l1.begin());
+    assert(j == l1.end());
+    assert(l1.size() == 0);
+    assert(distance(l1.begin(), l1.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp
index 68ba20d..d5fd044 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter_db1.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator position) with end()
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <cstdlib>
 #include <exception>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::list<int> l1(a1, a1+3);
     std::list<int>::const_iterator i = l1.end();
     l1.erase(i);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>>::const_iterator i = l1.end();
+    l1.erase(i);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp
index 8026878..df567aa 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter_db2.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator position) with iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,14 +20,28 @@
 #include <cstdlib>
 #include <exception>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::list<int> l1(a1, a1+3);
     std::list<int> l2(a1, a1+3);
     std::list<int>::const_iterator i = l2.begin();
     l1.erase(i);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>> l2(a1, a1+3);
+    std::list<int, min_allocator<int>>::const_iterator i = l2.begin();
+    l1.erase(i);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp
index a7c9a0d..e1a6e5a 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp
@@ -14,6 +14,8 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     int a1[] = {1, 2, 3};
@@ -47,4 +49,36 @@
         assert(distance(l1.cbegin(), l1.cend()) == 0);
         assert(i == l1.begin());
     }
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), l1.cbegin());
+        assert(l1.size() == 3);
+        assert(distance(l1.cbegin(), l1.cend()) == 3);
+        assert(i == l1.begin());
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin()));
+        assert(l1.size() == 2);
+        assert(distance(l1.cbegin(), l1.cend()) == 2);
+        assert(i == l1.begin());
+        assert((l1 == std::list<int, min_allocator<int>>(a1+1, a1+3)));
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2));
+        assert(l1.size() == 1);
+        assert(distance(l1.cbegin(), l1.cend()) == 1);
+        assert(i == l1.begin());
+        assert((l1 == std::list<int, min_allocator<int>>(a1+2, a1+3)));
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3));
+        assert(l1.size() == 0);
+        assert(distance(l1.cbegin(), l1.cend()) == 0);
+        assert(i == l1.begin());
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp
index d9d901d..18b825b 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db1.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with first iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::list<int> l1(a1, a1+3);
     std::list<int> l2(a1, a1+3);
     std::list<int>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin()));
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>> l2(a1, a1+3);
+    std::list<int, min_allocator<int>>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin()));
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp
index dc9a0fe..84fbf37 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db2.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with second iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::list<int> l1(a1, a1+3);
     std::list<int> l2(a1, a1+3);
     std::list<int>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin()));
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>> l2(a1, a1+3);
+    std::list<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp
index acfc90e..4bdee44 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db3.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with both iterators from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::list<int> l1(a1, a1+3);
     std::list<int> l2(a1, a1+3);
     std::list<int>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin()));
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>> l2(a1, a1+3);
+    std::list<int, min_allocator<int>>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp
index bf69657..5b1d3e1 100644
--- a/test/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/erase_iter_iter_db4.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with a bad range
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,12 +20,24 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::list<int> l1(a1, a1+3);
     std::list<int>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin());
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin());
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp b/test/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp
index d82dbcc..9afb506 100644
--- a/test/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::list<int> d(10, 1);
     std::list<int>::iterator i = d.insert(next(d.cbegin(), 2), {3, 4, 5, 6});
     assert(d.size() == 14);
@@ -36,5 +39,29 @@
     assert(*i++ == 1);
     assert(*i++ == 1);
     assert(*i++ == 1);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<int, min_allocator<int>> d(10, 1);
+    std::list<int, min_allocator<int>>::iterator i = d.insert(next(d.cbegin(), 2), {3, 4, 5, 6});
+    assert(d.size() == 14);
+    assert(i == next(d.begin(), 2));
+    i = d.begin();
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    assert(*i++ == 3);
+    assert(*i++ == 4);
+    assert(*i++ == 5);
+    assert(*i++ == 6);
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    assert(*i++ == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
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 e8ea2a8..9e23df3 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,7 +12,7 @@
 // template <InputIterator Iter>
 //   iterator insert(const_iterator position, Iter first, Iter last);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
@@ -20,6 +20,7 @@
 #include <cstdlib>
 #include <cassert>
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int throw_next = 0xFFFF;
 int count = 0;
@@ -97,9 +98,9 @@
     ++i;
     assert(*i == 3);
     }
-#if _LIBCPP_DEBUG2 >= 1
+    throw_next = 0xFFFF;
+#if _LIBCPP_DEBUG >= 1
     {
-        throw_next = 0xFFFF;
         std::list<int> v(100);
         std::list<int> v2(100);
         int a[] = {1, 2, 3, 4, 5};
@@ -109,4 +110,74 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> l1;
+    std::list<int, min_allocator<int>>::iterator i = l1.insert(l1.begin(), a1, a1+3);
+    assert(i == l1.begin());
+    assert(l1.size() == 3);
+    assert(distance(l1.begin(), l1.end()) == 3);
+    i = l1.begin();
+    assert(*i == 1);
+    ++i;
+    assert(*i == 2);
+    ++i;
+    assert(*i == 3);
+    int a2[] = {4, 5, 6};
+    i = l1.insert(i, a2, a2+3);
+    assert(*i == 4);
+    assert(l1.size() == 6);
+    assert(distance(l1.begin(), l1.end()) == 6);
+    i = l1.begin();
+    assert(*i == 1);
+    ++i;
+    assert(*i == 2);
+    ++i;
+    assert(*i == 4);
+    ++i;
+    assert(*i == 5);
+    ++i;
+    assert(*i == 6);
+    ++i;
+    assert(*i == 3);
+    throw_next = 2;
+    int save_count = count;
+    try
+    {
+        i = l1.insert(i, a2, a2+3);
+        assert(false);
+    }
+    catch (...)
+    {
+    }
+    assert(save_count == count);
+    assert(l1.size() == 6);
+    assert(distance(l1.begin(), l1.end()) == 6);
+    i = l1.begin();
+    assert(*i == 1);
+    ++i;
+    assert(*i == 2);
+    ++i;
+    assert(*i == 4);
+    ++i;
+    assert(*i == 5);
+    ++i;
+    assert(*i == 6);
+    ++i;
+    assert(*i == 3);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        throw_next = 0xFFFF;
+        std::list<int, min_allocator<int>> v(100);
+        std::list<int, min_allocator<int>> v2(100);
+        int a[] = {1, 2, 3, 4, 5};
+        const int N = sizeof(a)/sizeof(a[0]);
+        std::list<int, min_allocator<int>>::iterator i = v.insert(next(v2.cbegin(), 10), input_iterator<const int*>(a),
+                                       input_iterator<const int*>(a+N));
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp b/test/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp
index 3c35224..e575753 100644
--- a/test/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp
@@ -11,7 +11,7 @@
 
 // iterator insert(const_iterator position, value_type&& x);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
@@ -19,10 +19,12 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     std::list<MoveOnly> l1;
     l1.insert(l1.cend(), MoveOnly(1));
     assert(l1.size() == 1);
@@ -31,8 +33,9 @@
     assert(l1.size() == 2);
     assert(l1.front() == MoveOnly(2));
     assert(l1.back() == MoveOnly(1));
+    }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::list<int> v1(3);
         std::list<int> v2(3);
@@ -40,4 +43,26 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+    std::list<MoveOnly, min_allocator<MoveOnly>> l1;
+    l1.insert(l1.cend(), MoveOnly(1));
+    assert(l1.size() == 1);
+    assert(l1.front() == MoveOnly(1));
+    l1.insert(l1.cbegin(), MoveOnly(2));
+    assert(l1.size() == 2);
+    assert(l1.front() == MoveOnly(2));
+    assert(l1.back() == MoveOnly(1));
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<int, min_allocator<int>> v1(3);
+        std::list<int, min_allocator<int>> v2(3);
+        v1.insert(v2.begin(), 4);
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/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 9221a7f..0de5a9f 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,7 +11,7 @@
 
 // iterator insert(const_iterator position, size_type n, const value_type& x);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
@@ -19,6 +19,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int throw_next = 0xFFFF;
 int count = 0;
 
@@ -39,6 +41,7 @@
 
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     int a2[] = {1, 4, 4, 4, 4, 4, 2, 3};
     std::list<int> l1(a1, a1+3);
@@ -58,7 +61,8 @@
     throw_next = 0xFFFF;
     assert(save_count == count);
     assert(l1 == std::list<int>(a2, a2+8));
-#if _LIBCPP_DEBUG2 >= 1
+    }
+#if _LIBCPP_DEBUG >= 1
     {
         std::list<int> c1(100);
         std::list<int> c2;
@@ -66,4 +70,35 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    int a2[] = {1, 4, 4, 4, 4, 4, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>>::iterator i = l1.insert(next(l1.cbegin()), 5, 4);
+    assert(i == next(l1.begin()));
+    assert((l1 == std::list<int, min_allocator<int>>(a2, a2+8)));
+    throw_next = 4;
+    int save_count = count;
+    try
+    {
+        i = l1.insert(i, 5, 5);
+        assert(false);
+    }
+    catch (...)
+    {
+    }
+    throw_next = 0xFFFF;
+    assert(save_count == count);
+    assert((l1 == std::list<int, min_allocator<int>>(a2, a2+8)));
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<int, min_allocator<int>> c1(100);
+        std::list<int, min_allocator<int>> c2;
+        std::list<int, min_allocator<int>>::iterator i = c1.insert(next(c2.cbegin(), 10), 5, 1);
+        assert(false);
+    }
+#endif
+#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 6ea2a17..bf9ed8b 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,7 +11,7 @@
 
 // iterator insert(const_iterator position, const value_type& x);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
@@ -19,6 +19,8 @@
 #include <cstdlib>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int throw_next = 0xFFFF;
 int count = 0;
 
@@ -39,6 +41,7 @@
 
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     int a2[] = {1, 4, 2, 3};
     std::list<int> l1(a1, a1+3);
@@ -60,7 +63,8 @@
     throw_next = 0xFFFF;
     assert(save_count == count);
     assert(l1 == std::list<int>(a2, a2+4));
-#if _LIBCPP_DEBUG2 >= 1
+    }
+#if _LIBCPP_DEBUG >= 1
     {
         std::list<int> v1(3);
         std::list<int> v2(3);
@@ -69,4 +73,38 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    int a2[] = {1, 4, 2, 3};
+    std::list<int, min_allocator<int>> l1(a1, a1+3);
+    std::list<int, min_allocator<int>>::iterator i = l1.insert(next(l1.cbegin()), 4);
+    assert(i == next(l1.begin()));
+    assert(l1.size() == 4);
+    assert(distance(l1.begin(), l1.end()) == 4);
+    assert((l1 == std::list<int, min_allocator<int>>(a2, a2+4)));
+    throw_next = 0;
+    int save_count = count;
+    try
+    {
+        i = l1.insert(i, 5);
+        assert(false);
+    }
+    catch (...)
+    {
+    }
+    throw_next = 0xFFFF;
+    assert(save_count == count);
+    assert((l1 == std::list<int, min_allocator<int>>(a2, a2+4)));
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<int, min_allocator<int>> v1(3);
+        std::list<int, min_allocator<int>> v2(3);
+        int i = 4;
+        v1.insert(v2.begin(), i);
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/pop_back.pass.cpp b/test/containers/sequences/list/list.modifiers/pop_back.pass.cpp
index 97105fd..a687b1b 100644
--- a/test/containers/sequences/list/list.modifiers/pop_back.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/pop_back.pass.cpp
@@ -11,15 +11,18 @@
 
 // void pop_back();
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a[] = {1, 2, 3};
     std::list<int> c(a, a+3);
     c.pop_back();
@@ -28,8 +31,25 @@
     assert(c == std::list<int>(a, a+1));
     c.pop_back();
     assert(c.empty());
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
         c.pop_back();
         assert(false);
 #endif        
+    }
+#if __cplusplus >= 201103L
+    {
+    int a[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> c(a, a+3);
+    c.pop_back();
+    assert((c == std::list<int, min_allocator<int>>(a, a+2)));
+    c.pop_back();
+    assert((c == std::list<int, min_allocator<int>>(a, a+1)));
+    c.pop_back();
+    assert(c.empty());
+#if _LIBCPP_DEBUG >= 1
+        c.pop_back();
+        assert(false);
+#endif        
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/pop_front.pass.cpp b/test/containers/sequences/list/list.modifiers/pop_front.pass.cpp
index 77cb145..cc1462c 100644
--- a/test/containers/sequences/list/list.modifiers/pop_front.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/pop_front.pass.cpp
@@ -14,8 +14,11 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a[] = {1, 2, 3};
     std::list<int> c(a, a+3);
     c.pop_front();
@@ -24,4 +27,17 @@
     assert(c == std::list<int>(a+2, a+3));
     c.pop_front();
     assert(c.empty());
+    }
+#if __cplusplus >= 201103L
+    {
+    int a[] = {1, 2, 3};
+    std::list<int, min_allocator<int>> c(a, a+3);
+    c.pop_front();
+    assert((c == std::list<int, min_allocator<int>>(a+1, a+3)));
+    c.pop_front();
+    assert((c == std::list<int, min_allocator<int>>(a+2, a+3)));
+    c.pop_front();
+    assert(c.empty());
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/push_back.pass.cpp b/test/containers/sequences/list/list.modifiers/push_back.pass.cpp
index 6e5f1af..2022bb0 100644
--- a/test/containers/sequences/list/list.modifiers/push_back.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/push_back.pass.cpp
@@ -14,11 +14,24 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     std::list<int> c;
     for (int i = 0; i < 5; ++i)
         c.push_back(i);
     int a[] = {0, 1, 2, 3, 4};
     assert(c == std::list<int>(a, a+5));
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<int, min_allocator<int>> c;
+    for (int i = 0; i < 5; ++i)
+        c.push_back(i);
+    int a[] = {0, 1, 2, 3, 4};
+    assert((c == std::list<int, min_allocator<int>>(a, a+5)));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp b/test/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp
index bdb6af3..9d3c05e 100644
--- a/test/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/push_back_exception_safety.pass.cpp
@@ -19,14 +19,14 @@
 
 
 class CMyClass {
-	public: CMyClass();
-	public: CMyClass(const CMyClass& iOther);
-	public: ~CMyClass();
+    public: CMyClass();
+    public: CMyClass(const CMyClass& iOther);
+    public: ~CMyClass();
 
-	private: int fMagicValue;
+    private: int fMagicValue;
 
-	private: static int kStartedConstructionMagicValue;
-	private: static int kFinishedConstructionMagicValue;
+    private: static int kStartedConstructionMagicValue;
+    private: static int kFinishedConstructionMagicValue;
 };
 
 // Value for fMagicValue when the constructor has started running, but not yet finished
@@ -35,39 +35,39 @@
 int CMyClass::kFinishedConstructionMagicValue = 12345;
 
 CMyClass::CMyClass() :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::CMyClass(const CMyClass& /*iOther*/) :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
-	if (gCopyConstructorShouldThow) {
-		throw std::exception();
-	}
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
+    if (gCopyConstructorShouldThow) {
+        throw std::exception();
+    }
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::~CMyClass() {
-	// Only instances for which the constructor has finished running should be destructed
-	assert(fMagicValue == kFinishedConstructionMagicValue);
+    // Only instances for which the constructor has finished running should be destructed
+    assert(fMagicValue == kFinishedConstructionMagicValue);
 }
 
 int main()
 {
-	CMyClass instance;
-	std::list<CMyClass> vec;
+    CMyClass instance;
+    std::list<CMyClass> vec;
 
-	vec.push_back(instance);
+    vec.push_back(instance);
 
-	gCopyConstructorShouldThow = true;
-	try {
-		vec.push_back(instance);
-	}
-	catch (...) {
-	}
+    gCopyConstructorShouldThow = true;
+    try {
+        vec.push_back(instance);
+    }
+    catch (...) {
+    }
 }
diff --git a/test/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp b/test/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp
index 846b56d..3f0dddd 100644
--- a/test/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     std::list<MoveOnly> l1;
     l1.push_back(MoveOnly(1));
     assert(l1.size() == 1);
@@ -27,5 +29,18 @@
     assert(l1.size() == 2);
     assert(l1.front() == MoveOnly(1));
     assert(l1.back() == MoveOnly(2));
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<MoveOnly, min_allocator<MoveOnly>> l1;
+    l1.push_back(MoveOnly(1));
+    assert(l1.size() == 1);
+    assert(l1.front() == MoveOnly(1));
+    l1.push_back(MoveOnly(2));
+    assert(l1.size() == 2);
+    assert(l1.front() == MoveOnly(1));
+    assert(l1.back() == MoveOnly(2));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/list/list.modifiers/push_front.pass.cpp b/test/containers/sequences/list/list.modifiers/push_front.pass.cpp
index 7061cb8..7042829 100644
--- a/test/containers/sequences/list/list.modifiers/push_front.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/push_front.pass.cpp
@@ -14,11 +14,24 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     std::list<int> c;
     for (int i = 0; i < 5; ++i)
         c.push_front(i);
     int a[] = {4, 3, 2, 1, 0};
     assert(c == std::list<int>(a, a+5));
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<int, min_allocator<int>> c;
+    for (int i = 0; i < 5; ++i)
+        c.push_front(i);
+    int a[] = {4, 3, 2, 1, 0};
+    assert((c == std::list<int, min_allocator<int>>(a, a+5)));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp b/test/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp
index 03f8af2..6609005 100644
--- a/test/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/push_front_exception_safety.pass.cpp
@@ -19,14 +19,14 @@
 
 
 class CMyClass {
-	public: CMyClass();
-	public: CMyClass(const CMyClass& iOther);
-	public: ~CMyClass();
+    public: CMyClass();
+    public: CMyClass(const CMyClass& iOther);
+    public: ~CMyClass();
 
-	private: int fMagicValue;
+    private: int fMagicValue;
 
-	private: static int kStartedConstructionMagicValue;
-	private: static int kFinishedConstructionMagicValue;
+    private: static int kStartedConstructionMagicValue;
+    private: static int kFinishedConstructionMagicValue;
 };
 
 // Value for fMagicValue when the constructor has started running, but not yet finished
@@ -35,39 +35,39 @@
 int CMyClass::kFinishedConstructionMagicValue = 12345;
 
 CMyClass::CMyClass() :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::CMyClass(const CMyClass& /*iOther*/) :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
-	if (gCopyConstructorShouldThow) {
-		throw std::exception();
-	}
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
+    if (gCopyConstructorShouldThow) {
+        throw std::exception();
+    }
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::~CMyClass() {
-	// Only instances for which the constructor has finished running should be destructed
-	assert(fMagicValue == kFinishedConstructionMagicValue);
+    // Only instances for which the constructor has finished running should be destructed
+    assert(fMagicValue == kFinishedConstructionMagicValue);
 }
 
 int main()
 {
-	CMyClass instance;
-	std::list<CMyClass> vec;
+    CMyClass instance;
+    std::list<CMyClass> vec;
 
-	vec.push_front(instance);
+    vec.push_front(instance);
 
-	gCopyConstructorShouldThow = true;
-	try {
-		vec.push_front(instance);
-	}
-	catch (...) {
-	}
+    gCopyConstructorShouldThow = true;
+    try {
+        vec.push_front(instance);
+    }
+    catch (...) {
+    }
 }
diff --git a/test/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp b/test/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp
index 931501e..e7976fa 100644
--- a/test/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp
+++ b/test/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
     std::list<MoveOnly> l1;
     l1.push_front(MoveOnly(1));
     assert(l1.size() == 1);
@@ -27,5 +29,18 @@
     assert(l1.size() == 2);
     assert(l1.front() == MoveOnly(2));
     assert(l1.back() == MoveOnly(1));
+    }
+#if __cplusplus >= 201103L
+    {
+    std::list<MoveOnly, min_allocator<MoveOnly>> l1;
+    l1.push_front(MoveOnly(1));
+    assert(l1.size() == 1);
+    assert(l1.front() == MoveOnly(1));
+    l1.push_front(MoveOnly(2));
+    assert(l1.size() == 2);
+    assert(l1.front() == MoveOnly(2));
+    assert(l1.back() == MoveOnly(1));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/list/list.ops/merge.pass.cpp b/test/containers/sequences/list/list.ops/merge.pass.cpp
index a20e1b5..9b8d2ad 100644
--- a/test/containers/sequences/list/list.ops/merge.pass.cpp
+++ b/test/containers/sequences/list/list.ops/merge.pass.cpp
@@ -14,8 +14,11 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 3, 7, 9, 10};
     int a2[] = {0, 2, 4, 5, 6, 8, 11};
     int a3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
@@ -23,4 +26,16 @@
     std::list<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
     c1.merge(c2);
     assert(c1 == std::list<int>(a3, a3+sizeof(a3)/sizeof(a3[0])));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 3, 7, 9, 10};
+    int a2[] = {0, 2, 4, 5, 6, 8, 11};
+    int a3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+    std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+    c1.merge(c2);
+    assert((c1 == std::list<int, min_allocator<int>>(a3, a3+sizeof(a3)/sizeof(a3[0]))));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/merge_comp.pass.cpp b/test/containers/sequences/list/list.ops/merge_comp.pass.cpp
index 141988b..b09e2dc 100644
--- a/test/containers/sequences/list/list.ops/merge_comp.pass.cpp
+++ b/test/containers/sequences/list/list.ops/merge_comp.pass.cpp
@@ -15,8 +15,11 @@
 #include <functional>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {10, 9, 7, 3, 1};
     int a2[] = {11, 8, 6, 5, 4, 2, 0};
     int a3[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
@@ -24,4 +27,16 @@
     std::list<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
     c1.merge(c2, std::greater<int>());
     assert(c1 == std::list<int>(a3, a3+sizeof(a3)/sizeof(a3[0])));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {10, 9, 7, 3, 1};
+    int a2[] = {11, 8, 6, 5, 4, 2, 0};
+    int a3[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+    std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+    std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+    c1.merge(c2, std::greater<int>());
+    assert((c1 == std::list<int, min_allocator<int>>(a3, a3+sizeof(a3)/sizeof(a3[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 0af405c..f17dfc8 100644
--- a/test/containers/sequences/list/list.ops/remove.pass.cpp
+++ b/test/containers/sequences/list/list.ops/remove.pass.cpp
@@ -14,11 +14,24 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3, 4};
     int a2[] = {1, 2, 4};
     std::list<int> c(a1, a1+4);
     c.remove(3);
     assert(c == std::list<int>(a2, a2+3));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3, 4};
+    int a2[] = {1, 2, 4};
+    std::list<int, min_allocator<int>> c(a1, a1+4);
+    c.remove(3);
+    assert((c == std::list<int, min_allocator<int>>(a2, a2+3)));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/remove_if.pass.cpp b/test/containers/sequences/list/list.ops/remove_if.pass.cpp
index 1b56ea7..e636607 100644
--- a/test/containers/sequences/list/list.ops/remove_if.pass.cpp
+++ b/test/containers/sequences/list/list.ops/remove_if.pass.cpp
@@ -15,6 +15,8 @@
 #include <cassert>
 #include <functional>
 
+#include "../../../min_allocator.h"
+
 bool g(int i)
 {
     return i < 3;
@@ -22,9 +24,20 @@
 
 int main()
 {
+    {
     int a1[] = {1, 2, 3, 4};
     int a2[] = {3, 4};
     std::list<int> c(a1, a1+4);
     c.remove_if(g);
     assert(c == std::list<int>(a2, a2+2));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3, 4};
+    int a2[] = {3, 4};
+    std::list<int, min_allocator<int>> c(a1, a1+4);
+    c.remove_if(g);
+    assert((c == std::list<int, min_allocator<int>>(a2, a2+2)));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/reverse.pass.cpp b/test/containers/sequences/list/list.ops/reverse.pass.cpp
index b8d1684..3eafeee 100644
--- a/test/containers/sequences/list/list.ops/reverse.pass.cpp
+++ b/test/containers/sequences/list/list.ops/reverse.pass.cpp
@@ -14,11 +14,24 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
     int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
     std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
     c1.reverse();
     assert(c1 == std::list<int>(a2, a2+sizeof(a2)/sizeof(a2[0])));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+    int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+    c1.reverse();
+    assert((c1 == std::list<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/sort.pass.cpp b/test/containers/sequences/list/list.ops/sort.pass.cpp
index 887cb54..a79f0a6 100644
--- a/test/containers/sequences/list/list.ops/sort.pass.cpp
+++ b/test/containers/sequences/list/list.ops/sort.pass.cpp
@@ -14,11 +14,24 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9};
     int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
     std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
     c1.sort();
     assert(c1 == std::list<int>(a2, a2+sizeof(a2)/sizeof(a2[0])));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9};
+    int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+    c1.sort();
+    assert((c1 == std::list<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/sort_comp.pass.cpp b/test/containers/sequences/list/list.ops/sort_comp.pass.cpp
index d080522..c107e1f 100644
--- a/test/containers/sequences/list/list.ops/sort_comp.pass.cpp
+++ b/test/containers/sequences/list/list.ops/sort_comp.pass.cpp
@@ -15,11 +15,24 @@
 #include <functional>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9};
     int a2[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
     std::list<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
     c1.sort(std::greater<int>());
     assert(c1 == std::list<int>(a2, a2+sizeof(a2)/sizeof(a2[0])));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9};
+    int a2[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+    std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+    c1.sort(std::greater<int>());
+    assert((c1 == std::list<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/splice_pos_list.pass.cpp b/test/containers/sequences/list/list.ops/splice_pos_list.pass.cpp
index 26d1912..81916e0 100644
--- a/test/containers/sequences/list/list.ops/splice_pos_list.pass.cpp
+++ b/test/containers/sequences/list/list.ops/splice_pos_list.pass.cpp
@@ -11,13 +11,15 @@
 
 // void splice(const_iterator position, list& x);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     int a1[] = {1, 2, 3};
@@ -401,7 +403,7 @@
         ++i;
         assert(*i == 6);
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::list<int> v1(3);
         std::list<int> v2(3);
@@ -409,4 +411,393 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2;
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 0);
+        assert(distance(l1.begin(), l1.end()) == 0);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2;
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2;
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 4);
+        assert(distance(l1.begin(), l1.end()) == 4);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+        ++i;
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.end(), l2);
+        assert(l1.size() == 4);
+        assert(distance(l1.begin(), l1.end()) == 4);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2;
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2;
+        l1.splice(next(l1.begin()), l2);
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2;
+        l1.splice(next(l1.begin(), 2), l2);
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(next(l1.begin()), l2);
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(next(l1.begin(), 2), l2);
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 4);
+        assert(distance(l1.begin(), l1.end()) == 4);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(next(l1.begin()), l2);
+        assert(l1.size() == 4);
+        assert(distance(l1.begin(), l1.end()) == 4);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(next(l1.begin(), 2), l2);
+        assert(l1.size() == 4);
+        assert(distance(l1.begin(), l1.end()) == 4);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.begin(), l2);
+        assert(l1.size() == 6);
+        assert(distance(l1.begin(), l1.end()) == 6);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(next(l1.begin()), l2);
+        assert(l1.size() == 6);
+        assert(distance(l1.begin(), l1.end()) == 6);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(next(l1.begin(), 2), l2);
+        assert(l1.size() == 6);
+        assert(distance(l1.begin(), l1.end()) == 6);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+        ++i;
+        assert(*i == 3);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(next(l1.begin(), 3), l2);
+        assert(l1.size() == 6);
+        assert(distance(l1.begin(), l1.end()) == 6);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<int, min_allocator<int>> v1(3);
+        std::list<int, min_allocator<int>> v2(3);
+        v1.splice(v2.begin(), v2);
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp b/test/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp
index 64402ce..f4c0489 100644
--- a/test/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp
+++ b/test/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp
@@ -11,13 +11,15 @@
 
 // void splice(const_iterator position, list<T,Allocator>& x, iterator i);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     int a1[] = {1, 2, 3};
@@ -178,7 +180,7 @@
         ++i;
         assert(*i == 2);
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::list<int> v1(3);
         std::list<int> v2(3);
@@ -186,4 +188,170 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(l1.end(), l2, l2.begin());
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(l1.end(), l2, l2.begin());
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 1);
+        assert(distance(l2.begin(), l2.end()) == 1);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        i = l2.begin();
+        assert(*i == 5);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+2);
+        l1.splice(l1.end(), l2, next(l2.begin()));
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 1);
+        assert(distance(l2.begin(), l2.end()) == 1);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 5);
+        i = l2.begin();
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.end(), l2, l2.begin());
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 2);
+        assert(distance(l2.begin(), l2.end()) == 2);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        i = l2.begin();
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.end(), l2, next(l2.begin()));
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 2);
+        assert(distance(l2.begin(), l2.end()) == 2);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 5);
+        i = l2.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 6);
+    }
+    {
+        std::list<int, min_allocator<int>> l1;
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.end(), l2, next(l2.begin(), 2));
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        assert(l2.size() == 2);
+        assert(distance(l2.begin(), l2.end()) == 2);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 6);
+        i = l2.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 5);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        l1.splice(l1.begin(), l1, l1.begin());
+        assert(l1.size() == 1);
+        assert(distance(l1.begin(), l1.end()) == 1);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(l1.begin(), l2, l2.begin());
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+1);
+        std::list<int, min_allocator<int>> l2(a2, a2+1);
+        l1.splice(next(l1.begin()), l2, l2.begin());
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        assert(l2.size() == 0);
+        assert(distance(l2.begin(), l2.end()) == 0);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        l1.splice(l1.begin(), l1, l1.begin());
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        l1.splice(l1.begin(), l1, next(l1.begin()));
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 2);
+        ++i;
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        l1.splice(next(l1.begin()), l1, l1.begin());
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+2);
+        l1.splice(next(l1.begin()), l1, next(l1.begin()));
+        assert(l1.size() == 2);
+        assert(distance(l1.begin(), l1.end()) == 2);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<int, min_allocator<int>> v1(3);
+        std::list<int, min_allocator<int>> v2(3);
+        v1.splice(v1.begin(), v2, v1.begin());
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp b/test/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp
index 2dabf83..5745af5 100644
--- a/test/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp
+++ b/test/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp
@@ -11,13 +11,15 @@
 
 // void splice(const_iterator position, list& x, iterator first, iterator last);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     int a1[] = {1, 2, 3};
@@ -118,7 +120,7 @@
         i = l2.begin();
         assert(*i == 4);
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::list<int> v1(3);
         std::list<int> v2(3);
@@ -126,4 +128,110 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        l1.splice(l1.begin(), l1, next(l1.begin()), next(l1.begin()));
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        l1.splice(l1.begin(), l1, next(l1.begin()), next(l1.begin(), 2));
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 2);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 3);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        l1.splice(l1.begin(), l1, next(l1.begin()), next(l1.begin(), 3));
+        assert(l1.size() == 3);
+        assert(distance(l1.begin(), l1.end()) == 3);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 1);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.begin(), l2, next(l2.begin()), l2.end());
+        assert(l1.size() == 5);
+        assert(distance(l1.begin(), l1.end()) == 5);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        assert(l2.size() == 1);
+        i = l2.begin();
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(next(l1.begin()), l2, next(l2.begin()), l2.end());
+        assert(l1.size() == 5);
+        assert(distance(l1.begin(), l1.end()) == 5);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        assert(l2.size() == 1);
+        i = l2.begin();
+        assert(*i == 4);
+    }
+    {
+        std::list<int, min_allocator<int>> l1(a1, a1+3);
+        std::list<int, min_allocator<int>> l2(a2, a2+3);
+        l1.splice(l1.end(), l2, next(l2.begin()), l2.end());
+        assert(l1.size() == 5);
+        assert(distance(l1.begin(), l1.end()) == 5);
+        std::list<int, min_allocator<int>>::const_iterator i = l1.begin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 5);
+        ++i;
+        assert(*i == 6);
+        assert(l2.size() == 1);
+        i = l2.begin();
+        assert(*i == 4);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::list<int, min_allocator<int>> v1(3);
+        std::list<int, min_allocator<int>> v2(3);
+        v1.splice(v1.begin(), v2, v2.begin(), v1.end());
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/unique.pass.cpp b/test/containers/sequences/list/list.ops/unique.pass.cpp
index 17f79dc..cfd9d03 100644
--- a/test/containers/sequences/list/list.ops/unique.pass.cpp
+++ b/test/containers/sequences/list/list.ops/unique.pass.cpp
@@ -14,11 +14,24 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
     int a2[] = {2, 1, 4, 3};
     std::list<int> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
     c.unique();
     assert(c == std::list<int>(a2, a2+4));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
+    int a2[] = {2, 1, 4, 3};
+    std::list<int, min_allocator<int>> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
+    c.unique();
+    assert((c == std::list<int, min_allocator<int>>(a2, a2+4)));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.ops/unique_pred.pass.cpp b/test/containers/sequences/list/list.ops/unique_pred.pass.cpp
index 08aede6..a9687a9 100644
--- a/test/containers/sequences/list/list.ops/unique_pred.pass.cpp
+++ b/test/containers/sequences/list/list.ops/unique_pred.pass.cpp
@@ -14,6 +14,8 @@
 #include <list>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 bool g(int x, int y)
 {
     return x == y;
@@ -21,9 +23,20 @@
 
 int main()
 {
+    {
     int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
     int a2[] = {2, 1, 4, 3};
     std::list<int> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
     c.unique(g);
     assert(c == std::list<int>(a2, a2+4));
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3};
+    int a2[] = {2, 1, 4, 3};
+    std::list<int, min_allocator<int>> c(a1, a1+sizeof(a1)/sizeof(a1[0]));
+    c.unique(g);
+    assert((c == std::list<int, min_allocator<int>>(a2, a2+4)));
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/list.special/db_swap_1.pass.cpp b/test/containers/sequences/list/list.special/db_swap_1.pass.cpp
index 12730c2..e440f69 100644
--- a/test/containers/sequences/list/list.special/db_swap_1.pass.cpp
+++ b/test/containers/sequences/list/list.special/db_swap_1.pass.cpp
@@ -12,7 +12,7 @@
 // template <class T, class Alloc>
 //   void swap(list<T,Alloc>& x, list<T,Alloc>& y);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
@@ -20,10 +20,11 @@
 #include <cassert>
 
 #include <__debug>
+#include "../../../min_allocator.h"
 
 int main()
 {
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
@@ -38,5 +39,21 @@
         c1.erase(i1);
         assert(false);
     }
+#if __cplusplus >= 201103L
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        std::list<int, min_allocator<int>>::iterator i1 = c1.begin();
+        std::list<int, min_allocator<int>>::iterator i2 = c2.begin();
+        swap(c1, c2);
+        c1.erase(i2);
+        c2.erase(i1);
+        std::list<int, min_allocator<int>>::iterator j = i1;
+        c1.erase(i1);
+        assert(false);
+    }
+#endif
 #endif
 }
diff --git a/test/containers/sequences/list/list.special/swap.pass.cpp b/test/containers/sequences/list/list.special/swap.pass.cpp
index f6f25ba..a8283fd 100644
--- a/test/containers/sequences/list/list.special/swap.pass.cpp
+++ b/test/containers/sequences/list/list.special/swap.pass.cpp
@@ -15,6 +15,7 @@
 #include <list>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -85,4 +86,61 @@
         assert((c2 == std::list<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
         assert(c2.get_allocator() == A(1));
     }
+#if __cplusplus >= 201103L
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        swap(c1, c2);
+        assert((c1 == std::list<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+        assert((c2 == std::list<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::list<int, min_allocator<int>> c1(a1, a1);
+        std::list<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        swap(c1, c2);
+        assert((c1 == std::list<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+        assert(c2.empty());
+        assert(distance(c2.begin(), c2.end()) == 0);
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::list<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::list<int, min_allocator<int>> c2(a2, a2);
+        swap(c1, c2);
+        assert(c1.empty());
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert((c2 == std::list<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::list<int, min_allocator<int>> c1(a1, a1);
+        std::list<int, min_allocator<int>> c2(a2, a2);
+        swap(c1, c2);
+        assert(c1.empty());
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert(c2.empty());
+        assert(distance(c2.begin(), c2.end()) == 0);
+    }
+#ifndef _LIBCPP_DEBUG_LEVEL
+// This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        typedef min_allocator<int> A;
+        std::list<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A());
+        std::list<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A());
+        swap(c1, c2);
+        assert((c1 == std::list<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+        assert(c1.get_allocator() == A());
+        assert((c2 == std::list<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+        assert(c2.get_allocator() == A());
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/list/types.pass.cpp b/test/containers/sequences/list/types.pass.cpp
index e8de457..9fa3a05 100644
--- a/test/containers/sequences/list/types.pass.cpp
+++ b/test/containers/sequences/list/types.pass.cpp
@@ -25,6 +25,8 @@
 #include <list>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     static_assert((std::is_same<std::list<int>::value_type, int>::value), "");
@@ -33,4 +35,12 @@
     static_assert((std::is_same<std::list<int>::const_reference, std::allocator<int>::const_reference>::value), "");
     static_assert((std::is_same<std::list<int>::pointer, std::allocator<int>::pointer>::value), "");
     static_assert((std::is_same<std::list<int>::const_pointer, std::allocator<int>::const_pointer>::value), "");
+#if __cplusplus >= 201103L
+    static_assert((std::is_same<std::list<int, min_allocator<int>>::value_type, int>::value), "");
+    static_assert((std::is_same<std::list<int, min_allocator<int>>::allocator_type, min_allocator<int> >::value), "");
+    static_assert((std::is_same<std::list<int, min_allocator<int>>::reference, int&>::value), "");
+    static_assert((std::is_same<std::list<int, min_allocator<int>>::const_reference, const int&>::value), "");
+    static_assert((std::is_same<std::list<int, min_allocator<int>>::pointer, min_pointer<int>>::value), "");
+    static_assert((std::is_same<std::list<int, min_allocator<int>>::const_pointer, min_pointer<const int>>::value), "");
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/assign_copy.pass.cpp b/test/containers/sequences/vector.bool/assign_copy.pass.cpp
index d7db57d..7cf927b 100644
--- a/test/containers/sequences/vector.bool/assign_copy.pass.cpp
+++ b/test/containers/sequences/vector.bool/assign_copy.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -31,4 +32,13 @@
         assert(l2 == l);
         assert(l2.get_allocator() == other_allocator<bool>(5));
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool> > l(3, 2, min_allocator<bool>());
+        std::vector<bool, min_allocator<bool> > l2(l, min_allocator<bool>());
+        l2 = l;
+        assert(l2 == l);
+        assert(l2.get_allocator() == min_allocator<bool>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/assign_initializer_list.pass.cpp b/test/containers/sequences/vector.bool/assign_initializer_list.pass.cpp
index 14da561..2cf9297 100644
--- a/test/containers/sequences/vector.bool/assign_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector.bool/assign_initializer_list.pass.cpp
@@ -14,15 +14,30 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<int> d;
+    {
+    std::vector<bool> d;
     d.assign({true, false, false, true});
     assert(d.size() == 4);
     assert(d[0] == true);
     assert(d[1] == false);
     assert(d[2] == false);
     assert(d[3] == true);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<bool, min_allocator<bool>> d;
+    d.assign({true, false, false, true});
+    assert(d.size() == 4);
+    assert(d[0] == true);
+    assert(d[1] == false);
+    assert(d[2] == false);
+    assert(d[3] == true);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector.bool/assign_move.pass.cpp b/test/containers/sequences/vector.bool/assign_move.pass.cpp
index ca4f1d8..5edd313 100644
--- a/test/containers/sequences/vector.bool/assign_move.pass.cpp
+++ b/test/containers/sequences/vector.bool/assign_move.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -60,5 +61,21 @@
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool> > l(min_allocator<bool>{});
+        std::vector<bool, min_allocator<bool> > lo(min_allocator<bool>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::vector<bool, min_allocator<bool> > l2(min_allocator<bool>{});
+        l2 = std::move(l);
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == lo.get_allocator());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector.bool/capacity.pass.cpp b/test/containers/sequences/vector.bool/capacity.pass.cpp
index 4feb3d9..87c9898 100644
--- a/test/containers/sequences/vector.bool/capacity.pass.cpp
+++ b/test/containers/sequences/vector.bool/capacity.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -27,4 +29,16 @@
         v.push_back(0);
         assert(v.capacity() >= 101);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v;
+        assert(v.capacity() == 0);
+    }
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        assert(v.capacity() >= 100);
+        v.push_back(0);
+        assert(v.capacity() >= 101);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/construct_default.pass.cpp b/test/containers/sequences/vector.bool/construct_default.pass.cpp
index 4a8785a..fa396ab 100644
--- a/test/containers/sequences/vector.bool/construct_default.pass.cpp
+++ b/test/containers/sequences/vector.bool/construct_default.pass.cpp
@@ -16,6 +16,7 @@
 #include <cassert>
 
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 template <class C>
 void
@@ -43,4 +44,10 @@
     test0<std::vector<bool> >();
     test1<std::vector<bool, test_allocator<bool> > >(test_allocator<bool>(3));
     }
+#if __cplusplus >= 201103L
+    {
+    test0<std::vector<bool, min_allocator<bool>> >();
+    test1<std::vector<bool, min_allocator<bool> > >(min_allocator<bool>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/construct_iter_iter.pass.cpp b/test/containers/sequences/vector.bool/construct_iter_iter.pass.cpp
index e2c01ee..3225d87 100644
--- a/test/containers/sequences/vector.bool/construct_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector.bool/construct_iter_iter.pass.cpp
@@ -16,6 +16,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 template <class C, class Iterator>
 void
@@ -37,4 +38,11 @@
     test<std::vector<bool> >(bidirectional_iterator<const bool*>(a), bidirectional_iterator<const bool*>(an));
     test<std::vector<bool> >(random_access_iterator<const bool*>(a), random_access_iterator<const bool*>(an));
     test<std::vector<bool> >(a, an);
+#if __cplusplus >= 201103L
+    test<std::vector<bool, min_allocator<bool>> >(input_iterator<const bool*>(a), input_iterator<const bool*>(an));
+    test<std::vector<bool, min_allocator<bool>> >(forward_iterator<const bool*>(a), forward_iterator<const bool*>(an));
+    test<std::vector<bool, min_allocator<bool>> >(bidirectional_iterator<const bool*>(a), bidirectional_iterator<const bool*>(an));
+    test<std::vector<bool, min_allocator<bool>> >(random_access_iterator<const bool*>(a), random_access_iterator<const bool*>(an));
+    test<std::vector<bool, min_allocator<bool>> >(a, an);
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp b/test/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp
index 70932b1..12f1cae 100644
--- a/test/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp
+++ b/test/containers/sequences/vector.bool/construct_iter_iter_alloc.pass.cpp
@@ -17,6 +17,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 template <class C, class Iterator>
 void
@@ -33,10 +34,22 @@
 {
     bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
     bool* an = a + sizeof(a)/sizeof(a[0]);
+    {
     std::allocator<bool> alloc;
     test<std::vector<bool> >(input_iterator<const bool*>(a), input_iterator<const bool*>(an), alloc);
     test<std::vector<bool> >(forward_iterator<const bool*>(a), forward_iterator<const bool*>(an), alloc);
     test<std::vector<bool> >(bidirectional_iterator<const bool*>(a), bidirectional_iterator<const bool*>(an), alloc);
     test<std::vector<bool> >(random_access_iterator<const bool*>(a), random_access_iterator<const bool*>(an), alloc);
     test<std::vector<bool> >(a, an, alloc);
+    }
+#if __cplusplus >= 201103L
+    {
+    min_allocator<bool> alloc;
+    test<std::vector<bool, min_allocator<bool>> >(input_iterator<const bool*>(a), input_iterator<const bool*>(an), alloc);
+    test<std::vector<bool, min_allocator<bool>> >(forward_iterator<const bool*>(a), forward_iterator<const bool*>(an), alloc);
+    test<std::vector<bool, min_allocator<bool>> >(bidirectional_iterator<const bool*>(a), bidirectional_iterator<const bool*>(an), alloc);
+    test<std::vector<bool, min_allocator<bool>> >(random_access_iterator<const bool*>(a), random_access_iterator<const bool*>(an), alloc);
+    test<std::vector<bool, min_allocator<bool>> >(a, an, alloc);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/construct_size.pass.cpp b/test/containers/sequences/vector.bool/construct_size.pass.cpp
index a1e9527..aa4ca0e 100644
--- a/test/containers/sequences/vector.bool/construct_size.pass.cpp
+++ b/test/containers/sequences/vector.bool/construct_size.pass.cpp
@@ -15,9 +15,28 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+#include "../../test_allocator.h"
+
 template <class C>
 void
-test(typename C::size_type n)
+test2(typename C::size_type n, typename C::allocator_type const& a = typename C::allocator_type ())
+{
+#if _LIBCPP_STD_VER > 11
+    C c(n, a);
+    assert(c.__invariants());
+    assert(c.size() == n);
+    assert(c.get_allocator() == a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i)
+        assert(*i == typename C::value_type());
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
+}
+
+template <class C>
+void
+test1(typename C::size_type n)
 {
     C c(n);
     assert(c.__invariants());
@@ -27,7 +46,19 @@
         assert(*i == typename C::value_type());
 }
 
+template <class C>
+void
+test(typename C::size_type n)
+{
+    test1<C> ( n );
+    test2<C> ( n );
+}
+
 int main()
 {
     test<std::vector<bool> >(50);
+#if __cplusplus >= 201103L
+    test<std::vector<bool, min_allocator<bool>> >(50);
+    test2<std::vector<bool, test_allocator<bool>> >( 100, test_allocator<bool>(23));
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/construct_size_value.pass.cpp b/test/containers/sequences/vector.bool/construct_size_value.pass.cpp
index f84678a..dc950a2 100644
--- a/test/containers/sequences/vector.bool/construct_size_value.pass.cpp
+++ b/test/containers/sequences/vector.bool/construct_size_value.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 template <class C>
 void
 test(typename C::size_type n, const typename C::value_type& x)
@@ -29,4 +31,7 @@
 int main()
 {
     test<std::vector<bool> >(50, 3);
+#if __cplusplus >= 201103L
+    test<std::vector<bool, min_allocator<bool>> >(50, 3);
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp b/test/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp
index 0add99b..5e0b22a 100644
--- a/test/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp
+++ b/test/containers/sequences/vector.bool/construct_size_value_alloc.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 template <class C>
 void
 test(typename C::size_type n, const typename C::value_type& x,
@@ -31,4 +33,7 @@
 int main()
 {
     test<std::vector<bool> >(50, 3, std::allocator<bool>());
+#if __cplusplus >= 201103L
+    test<std::vector<bool, min_allocator<bool>> >(50, 3, min_allocator<bool>());
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/copy.pass.cpp b/test/containers/sequences/vector.bool/copy.pass.cpp
index 82e9fe1..f0e2c79 100644
--- a/test/containers/sequences/vector.bool/copy.pass.cpp
+++ b/test/containers/sequences/vector.bool/copy.pass.cpp
@@ -15,6 +15,7 @@
 #include <vector>
 #include <cassert>
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 template <class C>
 void
@@ -48,4 +49,17 @@
         assert(v2.get_allocator() == other_allocator<bool>(-2));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
+        bool* an = a + sizeof(a)/sizeof(a[0]);
+        test(std::vector<bool, min_allocator<bool>>(a, an));
+    }
+    {
+        std::vector<bool, min_allocator<bool> > v(3, 2, min_allocator<bool>());
+        std::vector<bool, min_allocator<bool> > v2 = v;
+        assert(v2 == v);
+        assert(v2.get_allocator() == v.get_allocator());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/copy_alloc.pass.cpp b/test/containers/sequences/vector.bool/copy_alloc.pass.cpp
index fc3edcb..58e71dd 100644
--- a/test/containers/sequences/vector.bool/copy_alloc.pass.cpp
+++ b/test/containers/sequences/vector.bool/copy_alloc.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 template <class C>
 void
@@ -45,4 +46,17 @@
         assert(l2 == l);
         assert(l2.get_allocator() == other_allocator<bool>(3));
     }
+#if __cplusplus >= 201103L
+    {
+        int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
+        int* an = a + sizeof(a)/sizeof(a[0]);
+        test(std::vector<bool, min_allocator<bool>>(a, an), min_allocator<bool>());
+    }
+    {
+        std::vector<bool, min_allocator<bool> > l(3, 2, min_allocator<bool>());
+        std::vector<bool, min_allocator<bool> > l2(l, min_allocator<bool>());
+        assert(l2 == l);
+        assert(l2.get_allocator() == min_allocator<bool>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/emplace.pass.cpp b/test/containers/sequences/vector.bool/emplace.pass.cpp
new file mode 100644
index 0000000..c575440
--- /dev/null
+++ b/test/containers/sequences/vector.bool/emplace.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+//  vector<bool>
+
+// template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
+
+#include <vector>
+#include <cassert>
+#include "../../min_allocator.h"
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef std::vector<bool> C;
+        C c;
+        
+        C::iterator i = c.emplace(c.cbegin());
+        assert(i == c.begin());
+        assert(c.size() == 1);
+        assert(c.front() == false);
+
+        i = c.emplace(c.cend(), true);
+        assert(i == c.end()-1);
+        assert(c.size() == 2);
+        assert(c.front() == false);
+        assert(c.back() == true);
+
+        i = c.emplace(c.cbegin()+1, 1 == 1);
+        assert(i == c.begin()+1);
+        assert(c.size() == 3);
+        assert(c.front() == false);
+        assert(c[1] == true);
+        assert(c.back() == true);
+    }
+    {
+        typedef std::vector<bool, min_allocator<bool>> C;
+        C c;
+
+        C::iterator i = c.emplace(c.cbegin());
+        assert(i == c.begin());
+        assert(c.size() == 1);
+        assert(c.front() == false);
+
+        i = c.emplace(c.cend(), true);
+        assert(i == c.end()-1);
+        assert(c.size() == 2);
+        assert(c.front() == false);
+        assert(c.back() == true);
+
+        i = c.emplace(c.cbegin()+1, 1 == 1);
+        assert(i == c.begin()+1);
+        assert(c.size() == 3);
+        assert(c.size() == 3);
+        assert(c.front() == false);
+        assert(c[1] == true);
+        assert(c.back() == true);
+    }
+#endif
+}
diff --git a/test/containers/sequences/vector.bool/emplace_back.pass.cpp b/test/containers/sequences/vector.bool/emplace_back.pass.cpp
new file mode 100644
index 0000000..86e0d7a
--- /dev/null
+++ b/test/containers/sequences/vector.bool/emplace_back.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+//  vector.bool
+
+// template <class... Args> void emplace_back(Args&&... args);
+
+#include <vector>
+#include <cassert>
+#include "../../min_allocator.h"
+
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef std::vector<bool> C;
+        C c;
+        c.emplace_back();
+        assert(c.size() == 1);
+        assert(c.front() == false);
+        c.emplace_back(true);
+        assert(c.size() == 2);
+        assert(c.front() == false);
+        assert(c.back() == true);
+        c.emplace_back(1 == 1);
+        assert(c.size() == 3);
+        assert(c.front() == false);
+        assert(c[1] == true);
+        assert(c.back() == true);
+    }
+    {
+        typedef std::vector<bool, min_allocator<bool>> C;
+        C c;
+        
+        c.emplace_back();
+        assert(c.size() == 1);
+        assert(c.front() == false);
+        c.emplace_back(true);
+        assert(c.size() == 2);
+        assert(c.front() == false);
+        assert(c.back() == true);
+        c.emplace_back(1 == 1);
+        assert(c.size() == 3);
+        assert(c.front() == false);
+        assert(c[1] == true);
+        assert(c.back() == true);
+    }
+#endif
+}
diff --git a/test/containers/sequences/vector.bool/erase_iter.pass.cpp b/test/containers/sequences/vector.bool/erase_iter.pass.cpp
index 29aaceb..776b43e 100644
--- a/test/containers/sequences/vector.bool/erase_iter.pass.cpp
+++ b/test/containers/sequences/vector.bool/erase_iter.pass.cpp
@@ -15,9 +15,12 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     bool a1[] = {1, 0, 1};
+    {
     std::vector<bool> l1(a1, a1+3);
     std::vector<bool>::const_iterator i = l1.begin();
     ++i;
@@ -36,4 +39,27 @@
     assert(j == l1.end());
     assert(l1.size() == 0);
     assert(distance(l1.begin(), l1.end()) == 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<bool, min_allocator<bool>> l1(a1, a1+3);
+    std::vector<bool, min_allocator<bool>>::const_iterator i = l1.begin();
+    ++i;
+    std::vector<bool, min_allocator<bool>>::iterator j = l1.erase(i);
+    assert(l1.size() == 2);
+    assert(distance(l1.begin(), l1.end()) == 2);
+    assert(*j == true);
+    assert(*l1.begin() == 1);
+    assert(*next(l1.begin()) == true);
+    j = l1.erase(j);
+    assert(j == l1.end());
+    assert(l1.size() == 1);
+    assert(distance(l1.begin(), l1.end()) == 1);
+    assert(*l1.begin() == true);
+    j = l1.erase(l1.begin());
+    assert(j == l1.end());
+    assert(l1.size() == 0);
+    assert(distance(l1.begin(), l1.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/erase_iter_iter.pass.cpp b/test/containers/sequences/vector.bool/erase_iter_iter.pass.cpp
index d35603b..8778c32 100644
--- a/test/containers/sequences/vector.bool/erase_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector.bool/erase_iter_iter.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     bool a1[] = {1, 0, 1};
@@ -48,4 +50,36 @@
         assert(distance(l1.cbegin(), l1.cend()) == 0);
         assert(i == l1.begin());
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> l1(a1, a1+3);
+        std::vector<bool, min_allocator<bool>>::iterator i = l1.erase(l1.cbegin(), l1.cbegin());
+        assert(l1.size() == 3);
+        assert(distance(l1.cbegin(), l1.cend()) == 3);
+        assert(i == l1.begin());
+    }
+    {
+        std::vector<bool, min_allocator<bool>> l1(a1, a1+3);
+        std::vector<bool, min_allocator<bool>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin()));
+        assert(l1.size() == 2);
+        assert(distance(l1.cbegin(), l1.cend()) == 2);
+        assert(i == l1.begin());
+        assert((l1 == std::vector<bool, min_allocator<bool>>(a1+1, a1+3)));
+    }
+    {
+        std::vector<bool, min_allocator<bool>> l1(a1, a1+3);
+        std::vector<bool, min_allocator<bool>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2));
+        assert(l1.size() == 1);
+        assert(distance(l1.cbegin(), l1.cend()) == 1);
+        assert(i == l1.begin());
+        assert((l1 == std::vector<bool, min_allocator<bool>>(a1+2, a1+3)));
+    }
+    {
+        std::vector<bool, min_allocator<bool>> l1(a1, a1+3);
+        std::vector<bool, min_allocator<bool>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3));
+        assert(l1.size() == 0);
+        assert(distance(l1.cbegin(), l1.cend()) == 0);
+        assert(i == l1.begin());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/find.pass.cpp b/test/containers/sequences/vector.bool/find.pass.cpp
new file mode 100644
index 0000000..8bad87e
--- /dev/null
+++ b/test/containers/sequences/vector.bool/find.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+// vector<bool>
+
+// std::find with vector<bool>::iterator
+
+// http://llvm.org/bugs/show_bug.cgi?id=16816
+
+#include <vector>
+#include <cassert>
+
+int main()
+{
+    {
+        for (unsigned i = 1; i < 256; ++i)
+        {
+            std::vector<bool> b(i,true);
+            std::vector<bool>::iterator j = std::find(b.begin()+1, b.end(), false);
+            assert(j-b.begin() == i);
+        }
+    }
+    {
+        for (unsigned i = 1; i < 256; ++i)
+        {
+            std::vector<bool> b(i,false);
+            std::vector<bool>::iterator j = std::find(b.begin()+1, b.end(), true);
+            assert(j-b.begin() == i);
+        }
+    }
+}
diff --git a/test/containers/sequences/vector.bool/initializer_list.pass.cpp b/test/containers/sequences/vector.bool/initializer_list.pass.cpp
index 04d94e0..7c1a5de 100644
--- a/test/containers/sequences/vector.bool/initializer_list.pass.cpp
+++ b/test/containers/sequences/vector.bool/initializer_list.pass.cpp
@@ -14,14 +14,28 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<int> d = {true, false, false, true};
+    {
+    std::vector<bool> d = {true, false, false, true};
     assert(d.size() == 4);
     assert(d[0] == true);
     assert(d[1] == false);
     assert(d[2] == false);
     assert(d[3] == true);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<bool, min_allocator<bool>> d = {true, false, false, true};
+    assert(d.size() == 4);
+    assert(d[0] == true);
+    assert(d[1] == false);
+    assert(d[2] == false);
+    assert(d[3] == true);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp b/test/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp
index f8b2ee6..19b5b57 100644
--- a/test/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp
+++ b/test/containers/sequences/vector.bool/initializer_list_alloc.pass.cpp
@@ -15,16 +15,30 @@
 #include <cassert>
 
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-    std::vector<int, test_allocator<int>> d({true, false, false, true}, test_allocator<int>(3));
-    assert(d.get_allocator() == test_allocator<int>(3));
+    {
+    std::vector<bool, test_allocator<bool>> d({true, false, false, true}, test_allocator<bool>(3));
+    assert(d.get_allocator() == test_allocator<bool>(3));
     assert(d.size() == 4);
     assert(d[0] == true);
     assert(d[1] == false);
     assert(d[2] == false);
     assert(d[3] == true);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<bool, min_allocator<bool>> d({true, false, false, true}, min_allocator<bool>());
+    assert(d.get_allocator() == min_allocator<bool>());
+    assert(d.size() == 4);
+    assert(d[0] == true);
+    assert(d[1] == false);
+    assert(d[2] == false);
+    assert(d[3] == true);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp b/test/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp
index c0b4334..4865b28 100644
--- a/test/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector.bool/insert_iter_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::vector<bool> d(10, true);
     std::vector<bool>::iterator i = d.insert(d.cbegin() + 2, {false, true, true, false});
     assert(d.size() == 14);
@@ -35,5 +38,28 @@
     assert(d[11] == true);
     assert(d[12] == true);
     assert(d[13] == true);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<bool, min_allocator<bool>> d(10, true);
+    std::vector<bool, min_allocator<bool>>::iterator i = d.insert(d.cbegin() + 2, {false, true, true, false});
+    assert(d.size() == 14);
+    assert(i == d.begin() + 2);
+    assert(d[0] == true);
+    assert(d[1] == true);
+    assert(d[2] == false);
+    assert(d[3] == true);
+    assert(d[4] == true);
+    assert(d[5] == false);
+    assert(d[6] == true);
+    assert(d[7] == true);
+    assert(d[8] == true);
+    assert(d[9] == true);
+    assert(d[10] == true);
+    assert(d[11] == true);
+    assert(d[12] == true);
+    assert(d[13] == true);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
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 6d150cd..5099ebc 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
@@ -16,6 +16,7 @@
 #include <vector>
 #include <cassert>
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -51,4 +52,38 @@
         for (; j < 105; ++j)
             assert(v[j] == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        bool a[] = {1, 0, 0, 1, 1};
+        const unsigned N = sizeof(a)/sizeof(a[0]);
+        std::vector<bool, min_allocator<bool>>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const bool*>(a),
+                                        input_iterator<const bool*>(a+N));
+        assert(v.size() == 100 + 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 < 105; ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        bool a[] = {1, 0, 0, 1, 1};
+        const unsigned N = sizeof(a)/sizeof(a[0]);
+        std::vector<bool, min_allocator<bool>>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const bool*>(a),
+                                        forward_iterator<const bool*>(a+N));
+        assert(v.size() == 100 + 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 < 105; ++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 09817c2..9d49816 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
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -30,4 +32,19 @@
         for (++j; j < 105; ++j)
             assert(v[j] == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        std::vector<bool, min_allocator<bool>>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
+        assert(v.size() == 105);
+        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 < 105; ++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 203a4bd..37bdebc 100644
--- a/test/containers/sequences/vector.bool/insert_iter_value.pass.cpp
+++ b/test/containers/sequences/vector.bool/insert_iter_value.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -29,4 +31,18 @@
         for (++j; j < 101; ++j)
             assert(v[j] == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        std::vector<bool, min_allocator<bool>>::iterator i = v.insert(v.cbegin() + 10, 1);
+        assert(v.size() == 101);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        assert(v[j] == 1);
+        for (++j; j < 101; ++j)
+            assert(v[j] == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/iterators.pass.cpp b/test/containers/sequences/vector.bool/iterators.pass.cpp
index 45b524c..98f725e 100644
--- a/test/containers/sequences/vector.bool/iterators.pass.cpp
+++ b/test/containers/sequences/vector.bool/iterators.pass.cpp
@@ -20,6 +20,8 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -56,4 +58,52 @@
         C::iterator i;
         C::const_iterator j;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef bool T;
+        typedef std::vector<T, min_allocator<T>> C;
+        C c;
+        C::iterator i = c.begin();
+        C::iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef bool T;
+        typedef std::vector<T, min_allocator<T>> C;
+        const C c;
+        C::const_iterator i = c.begin();
+        C::const_iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef bool T;
+        typedef std::vector<T, min_allocator<T>> C;
+        C c;
+        C::const_iterator i = c.cbegin();
+        C::const_iterator j = c.cend();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+        assert(i == c.end());
+    }
+    {
+        typedef bool T;
+        typedef std::vector<T, min_allocator<T>> C;
+        C::iterator i;
+        C::const_iterator j;
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        std::vector<bool>::iterator ii1{}, ii2{};
+        std::vector<bool>::iterator ii4 = ii1;
+        std::vector<bool>::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/move.pass.cpp b/test/containers/sequences/vector.bool/move.pass.cpp
index b99048e..49d8e23 100644
--- a/test/containers/sequences/vector.bool/move.pass.cpp
+++ b/test/containers/sequences/vector.bool/move.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -44,5 +45,20 @@
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool> > l(min_allocator<bool>{});
+        std::vector<bool, min_allocator<bool> > lo(min_allocator<bool>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::vector<bool, min_allocator<bool> > l2 = std::move(l);
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == lo.get_allocator());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector.bool/move_alloc.pass.cpp b/test/containers/sequences/vector.bool/move_alloc.pass.cpp
index f51f454..2b890d7 100644
--- a/test/containers/sequences/vector.bool/move_alloc.pass.cpp
+++ b/test/containers/sequences/vector.bool/move_alloc.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -57,5 +58,20 @@
         assert(!l.empty());
         assert(l2.get_allocator() == other_allocator<bool>(4));
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool> > l(min_allocator<bool>{});
+        std::vector<bool, min_allocator<bool> > lo(min_allocator<bool>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::vector<bool, min_allocator<bool> > l2(std::move(l), min_allocator<bool>());
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == min_allocator<bool>());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp b/test/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp
index ca786a6..6f20177 100644
--- a/test/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector.bool/op_equal_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::vector<bool> d;
     d = {true, false, false, true};
     assert(d.size() == 4);
@@ -24,5 +27,17 @@
     assert(d[1] == false);
     assert(d[2] == false);
     assert(d[3] == true);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<bool, min_allocator<bool>> d;
+    d = {true, false, false, true};
+    assert(d.size() == 4);
+    assert(d[0] == true);
+    assert(d[1] == false);
+    assert(d[2] == false);
+    assert(d[3] == true);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector.bool/push_back.pass.cpp b/test/containers/sequences/vector.bool/push_back.pass.cpp
index dd38045..21b3907 100644
--- a/test/containers/sequences/vector.bool/push_back.pass.cpp
+++ b/test/containers/sequences/vector.bool/push_back.pass.cpp
@@ -15,12 +15,14 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
         bool a[] = {0, 1, 1, 0, 1, 0, 0};
         const unsigned N = sizeof(a)/sizeof(a[0]);
-        std::vector<int> c;
+        std::vector<bool> c;
         for (unsigned i = 0; i < N; ++i)
         {
             c.push_back(a[i]);
@@ -29,4 +31,18 @@
                 assert(c[j] == a[j]);
         }
     }
+#if __cplusplus >= 201103L
+    {
+        bool a[] = {0, 1, 1, 0, 1, 0, 0};
+        const unsigned N = sizeof(a)/sizeof(a[0]);
+        std::vector<bool, min_allocator<bool>> c;
+        for (unsigned i = 0; i < N; ++i)
+        {
+            c.push_back(a[i]);
+            assert(c.size() == i+1);
+            for (int j = 0; j < c.size(); ++j)
+                assert(c[j] == a[j]);
+        }
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/reserve.pass.cpp b/test/containers/sequences/vector.bool/reserve.pass.cpp
index 21867b3..4e7fbef 100644
--- a/test/containers/sequences/vector.bool/reserve.pass.cpp
+++ b/test/containers/sequences/vector.bool/reserve.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -32,4 +34,21 @@
         assert(v.size() == 100);
         assert(v.capacity() >= 150);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v;
+        v.reserve(10);
+        assert(v.capacity() >= 10);
+    }
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        assert(v.capacity() >= 100);
+        v.reserve(50);
+        assert(v.size() == 100);
+        assert(v.capacity() >= 100);
+        v.reserve(150);
+        assert(v.size() == 100);
+        assert(v.capacity() >= 150);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/resize_size.pass.cpp b/test/containers/sequences/vector.bool/resize_size.pass.cpp
index 44a8345..1703245 100644
--- a/test/containers/sequences/vector.bool/resize_size.pass.cpp
+++ b/test/containers/sequences/vector.bool/resize_size.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -26,4 +28,15 @@
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        v.resize(50);
+        assert(v.size() == 50);
+        assert(v.capacity() >= 100);
+        v.resize(200);
+        assert(v.size() == 200);
+        assert(v.capacity() >= 200);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/resize_size_value.pass.cpp b/test/containers/sequences/vector.bool/resize_size_value.pass.cpp
index 1e283f5..1413f5c 100644
--- a/test/containers/sequences/vector.bool/resize_size_value.pass.cpp
+++ b/test/containers/sequences/vector.bool/resize_size_value.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -31,4 +33,20 @@
         for (unsigned i = 50; i < 200; ++i)
             assert(v[i] == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        v.resize(50, 1);
+        assert(v.size() == 50);
+        assert(v.capacity() >= 100);
+        assert((v == std::vector<bool, min_allocator<bool>>(50)));
+        v.resize(200, 1);
+        assert(v.size() == 200);
+        assert(v.capacity() >= 200);
+        for (unsigned i = 0; i < 50; ++i)
+            assert(v[i] == 0);
+        for (unsigned i = 50; i < 200; ++i)
+            assert(v[i] == 1);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/shrink_to_fit.pass.cpp b/test/containers/sequences/vector.bool/shrink_to_fit.pass.cpp
index 6966272..0b4cf49 100644
--- a/test/containers/sequences/vector.bool/shrink_to_fit.pass.cpp
+++ b/test/containers/sequences/vector.bool/shrink_to_fit.pass.cpp
@@ -15,6 +15,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -24,4 +26,13 @@
         assert(v.capacity() >= 101);
         assert(v.size() >= 101);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v(100);
+        v.push_back(1);
+        v.shrink_to_fit();
+        assert(v.capacity() >= 101);
+        assert(v.size() >= 101);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/swap.pass.cpp b/test/containers/sequences/vector.bool/swap.pass.cpp
index 5d0f0af..ce5a10e 100644
--- a/test/containers/sequences/vector.bool/swap.pass.cpp
+++ b/test/containers/sequences/vector.bool/swap.pass.cpp
@@ -15,6 +15,7 @@
 #include <vector>
 #include <cassert>
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -61,4 +62,37 @@
         assert(v[0] == false);
         assert(v[1] == true);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<bool, min_allocator<bool>> v1(100);
+        std::vector<bool, min_allocator<bool>> v2(200);
+        v1.swap(v2);
+        assert(v1.size() == 200);
+        assert(v1.capacity() >= 200);
+        assert(v2.size() == 100);
+        assert(v2.capacity() >= 100);
+    }
+    {
+        typedef min_allocator<bool> A;
+        std::vector<bool, A> v1(100, true, A());
+        std::vector<bool, A> v2(200, false, A());
+        swap(v1, v2);
+        assert(v1.size() == 200);
+        assert(v1.capacity() >= 200);
+        assert(v2.size() == 100);
+        assert(v2.capacity() >= 100);
+        assert(v1.get_allocator() == A());
+        assert(v2.get_allocator() == A());
+    }
+    {
+        std::vector<bool, min_allocator<bool>> v(2);
+        std::vector<bool, min_allocator<bool>>::reference r1 = v[0];
+        std::vector<bool, min_allocator<bool>>::reference r2 = v[1];
+        r1 = true;
+        using std::swap;
+        swap(r1, r2);
+        assert(v[0] == false);
+        assert(v[1] == true);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/types.pass.cpp b/test/containers/sequences/vector.bool/types.pass.cpp
index 9055a20..ef33d04 100644
--- a/test/containers/sequences/vector.bool/types.pass.cpp
+++ b/test/containers/sequences/vector.bool/types.pass.cpp
@@ -33,6 +33,7 @@
 
 #include "../../test_allocator.h"
 #include "../../Copyable.h"
+#include "../../min_allocator.h"
 
 template <class Allocator>
 void
@@ -43,8 +44,8 @@
     static_assert((std::is_same<typename C::value_type, bool>::value), "");
     static_assert((std::is_same<typename C::value_type, typename Allocator::value_type>::value), "");
     static_assert((std::is_same<typename C::allocator_type, Allocator>::value), "");
-    static_assert((std::is_same<typename C::size_type, typename Allocator::size_type>::value), "");
-    static_assert((std::is_same<typename C::difference_type, typename Allocator::difference_type>::value), "");
+    static_assert((std::is_same<typename C::size_type, typename std::allocator_traits<Allocator>::size_type>::value), "");
+    static_assert((std::is_same<typename C::difference_type, typename std::allocator_traits<Allocator>::difference_type>::value), "");
     static_assert((std::is_same<
         typename std::iterator_traits<typename C::iterator>::iterator_category,
         std::random_access_iterator_tag>::value), "");
@@ -65,4 +66,7 @@
     test<std::allocator<bool> >();
     static_assert((std::is_same<std::vector<bool>::allocator_type,
                                 std::allocator<bool> >::value), "");
+#if __cplusplus >= 201103L
+    test<min_allocator<bool> >();
+#endif
 }
diff --git a/test/containers/sequences/vector.bool/vector_bool.pass.cpp b/test/containers/sequences/vector.bool/vector_bool.pass.cpp
index 0835250..e2bc48a 100644
--- a/test/containers/sequences/vector.bool/vector_bool.pass.cpp
+++ b/test/containers/sequences/vector.bool/vector_bool.pass.cpp
@@ -22,8 +22,11 @@
 #include <cassert>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef std::vector<bool> T;
     typedef std::hash<T> H;
     static_assert((std::is_base_of<std::unary_function<T, std::size_t>,
@@ -32,4 +35,17 @@
     T vb(std::begin(ba), std::end(ba));
     H h;
     assert(h(vb) != 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::vector<bool, min_allocator<bool>> T;
+    typedef std::hash<T> H;
+    static_assert((std::is_base_of<std::unary_function<T, std::size_t>,
+                                   H>::value), "");
+    bool ba[] = {true, false, true, true, false};
+    T vb(std::begin(ba), std::end(ba));
+    H h;
+    assert(h(vb) != 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/const_value_type.pass.cpp b/test/containers/sequences/vector/const_value_type.pass.cpp
new file mode 100644
index 0000000..e16e439
--- /dev/null
+++ b/test/containers/sequences/vector/const_value_type.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// vector<const int> v;  // an extension
+
+#include <vector>
+#include <type_traits>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    std::vector<const int> v = {1, 2, 3};
+#endif
+}
diff --git a/test/containers/sequences/vector/db_back.pass.cpp b/test/containers/sequences/vector/db_back.pass.cpp
index b28af8b..0544452 100644
--- a/test/containers/sequences/vector/db_back.pass.cpp
+++ b/test/containers/sequences/vector/db_back.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call back() on empty container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
@@ -30,6 +33,18 @@
     c.clear();
     assert(c.back() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    assert(c.back() == 0);
+    c.clear();
+    assert(c.back() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_cback.pass.cpp b/test/containers/sequences/vector/db_cback.pass.cpp
index 18f0630..b8fd032 100644
--- a/test/containers/sequences/vector/db_cback.pass.cpp
+++ b/test/containers/sequences/vector/db_cback.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call back() on empty const container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,13 +21,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     const C c;
     assert(c.back() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    const C c;
+    assert(c.back() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_cfront.pass.cpp b/test/containers/sequences/vector/db_cfront.pass.cpp
index 9712a39..36ba0dd 100644
--- a/test/containers/sequences/vector/db_cfront.pass.cpp
+++ b/test/containers/sequences/vector/db_cfront.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call front() on empty const container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,13 +21,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     const C c;
     assert(c.front() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    const C c;
+    assert(c.front() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_cindex.pass.cpp b/test/containers/sequences/vector/db_cindex.pass.cpp
index ad33043..18ef2cf 100644
--- a/test/containers/sequences/vector/db_cindex.pass.cpp
+++ b/test/containers/sequences/vector/db_cindex.pass.cpp
@@ -11,7 +11,7 @@
 
 // Index const vector out of bounds.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,14 +21,28 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     const C c(1);
     assert(c[0] == 0);
     assert(c[1] == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    const C c(1);
+    assert(c[0] == 0);
+    assert(c[1] == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_front.pass.cpp b/test/containers/sequences/vector/db_front.pass.cpp
index 4892e28..97cdb24 100644
--- a/test/containers/sequences/vector/db_front.pass.cpp
+++ b/test/containers/sequences/vector/db_front.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call front() on empty container.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
@@ -30,6 +33,18 @@
     c.clear();
     assert(c.front() == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    assert(c.front() == 0);
+    c.clear();
+    assert(c.front() == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_index.pass.cpp b/test/containers/sequences/vector/db_index.pass.cpp
index 05b0bc4..785263b 100644
--- a/test/containers/sequences/vector/db_index.pass.cpp
+++ b/test/containers/sequences/vector/db_index.pass.cpp
@@ -11,7 +11,7 @@
 
 // Index vector out of bounds.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
@@ -30,6 +33,18 @@
     c.clear();
     assert(c[0] == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    assert(c[0] == 0);
+    c.clear();
+    assert(c[0] == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_2.pass.cpp b/test/containers/sequences/vector/db_iterators_2.pass.cpp
index 616ee5b..2670002 100644
--- a/test/containers/sequences/vector/db_iterators_2.pass.cpp
+++ b/test/containers/sequences/vector/db_iterators_2.pass.cpp
@@ -11,7 +11,7 @@
 
 // Compare iterators from different containers with <.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,14 +21,28 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c1;
     C c2;
     bool b = c1.begin() < c2.begin();
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c1;
+    C c2;
+    bool b = c1.begin() < c2.begin();
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_3.pass.cpp b/test/containers/sequences/vector/db_iterators_3.pass.cpp
index 1ef27cf..d47e3d4 100644
--- a/test/containers/sequences/vector/db_iterators_3.pass.cpp
+++ b/test/containers/sequences/vector/db_iterators_3.pass.cpp
@@ -11,7 +11,7 @@
 
 // Subtract iterators from different containers.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,14 +21,28 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c1;
     C c2;
     int i = c1.begin() - c2.begin();
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c1;
+    C c2;
+    int i = c1.begin() - c2.begin();
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_4.pass.cpp b/test/containers/sequences/vector/db_iterators_4.pass.cpp
index 4d60bd9..bba222e 100644
--- a/test/containers/sequences/vector/db_iterators_4.pass.cpp
+++ b/test/containers/sequences/vector/db_iterators_4.pass.cpp
@@ -11,7 +11,7 @@
 
 // Index iterator out of bounds.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
@@ -30,6 +33,18 @@
     assert(i[0] == 0);
     assert(i[1] == 0);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.begin();
+    assert(i[0] == 0);
+    assert(i[1] == 0);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_5.pass.cpp b/test/containers/sequences/vector/db_iterators_5.pass.cpp
index bb3bf05..c5d96c5 100644
--- a/test/containers/sequences/vector/db_iterators_5.pass.cpp
+++ b/test/containers/sequences/vector/db_iterators_5.pass.cpp
@@ -11,7 +11,7 @@
 
 // Add to iterator out of bounds.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
@@ -32,6 +35,20 @@
     i = c.begin();
     i += 2;
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.begin();
+    i += 1;
+    assert(i == c.end());
+    i = c.begin();
+    i += 2;
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_6.pass.cpp b/test/containers/sequences/vector/db_iterators_6.pass.cpp
index 24db88d..d33f29d 100644
--- a/test/containers/sequences/vector/db_iterators_6.pass.cpp
+++ b/test/containers/sequences/vector/db_iterators_6.pass.cpp
@@ -11,7 +11,7 @@
 
 // Decrement iterator prior to begin.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
@@ -31,6 +34,19 @@
     assert(i == c.begin());
     --i;
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.end();
+    --i;
+    assert(i == c.begin());
+    --i;
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_7.pass.cpp b/test/containers/sequences/vector/db_iterators_7.pass.cpp
index 709af3a..25555b4 100644
--- a/test/containers/sequences/vector/db_iterators_7.pass.cpp
+++ b/test/containers/sequences/vector/db_iterators_7.pass.cpp
@@ -11,7 +11,7 @@
 
 // Increment iterator past end.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,8 +21,11 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
@@ -31,6 +34,19 @@
     assert(i == c.end());
     ++i;
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_8.pass.cpp b/test/containers/sequences/vector/db_iterators_8.pass.cpp
index 178240a..d891630 100644
--- a/test/containers/sequences/vector/db_iterators_8.pass.cpp
+++ b/test/containers/sequences/vector/db_iterators_8.pass.cpp
@@ -11,7 +11,7 @@
 
 // Dereference non-dereferenceable iterator.
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -21,14 +21,28 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../min_allocator.h"
+
 int main()
 {
+    {
     typedef int T;
     typedef std::vector<T> C;
     C c(1);
     C::iterator i = c.end();
     T j = *i;
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::vector<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/iterators.pass.cpp b/test/containers/sequences/vector/iterators.pass.cpp
index 9ebd20b..4ee16e9 100644
--- a/test/containers/sequences/vector/iterators.pass.cpp
+++ b/test/containers/sequences/vector/iterators.pass.cpp
@@ -20,6 +20,14 @@
 #include <cassert>
 #include <iterator>
 
+#include "../../min_allocator.h"
+
+struct A
+{
+    int first;
+    int second;
+};
+
 int main()
 {
     {
@@ -69,4 +77,75 @@
         C::iterator i;
         C::const_iterator j;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::vector<T, min_allocator<T>> C;
+        C c;
+        C::iterator i = c.begin();
+        C::iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef int T;
+        typedef std::vector<T, min_allocator<T>> C;
+        const C c;
+        C::const_iterator i = c.begin();
+        C::const_iterator j = c.end();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+    }
+    {
+        typedef int T;
+        typedef std::vector<T, min_allocator<T>> C;
+        C c;
+        C::const_iterator i = c.cbegin();
+        C::const_iterator j = c.cend();
+        assert(std::distance(i, j) == 0);
+        assert(i == j);
+        assert(i == c.end());
+    }
+    {
+        typedef int T;
+        typedef std::vector<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        C::iterator i = c.begin();
+        assert(*i == 0);
+        ++i;
+        assert(*i == 1);
+        *i = 10;
+        assert(*i == 10);
+        assert(std::distance(c.begin(), c.end()) == 10);
+    }
+    {
+        typedef int T;
+        typedef std::vector<T, min_allocator<T>> C;
+        C::iterator i;
+        C::const_iterator j;
+    }
+    {
+        typedef A T;
+        typedef std::vector<T, min_allocator<T>> C;
+        C c = {A{1, 2}};
+        C::iterator i = c.begin();
+        i->first = 3;
+        C::const_iterator j = i;
+        assert(j->first == 3);
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::vector<int> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/types.pass.cpp b/test/containers/sequences/vector/types.pass.cpp
index 12c5350..5e1dc9b 100644
--- a/test/containers/sequences/vector/types.pass.cpp
+++ b/test/containers/sequences/vector/types.pass.cpp
@@ -35,6 +35,7 @@
 
 #include "../../test_allocator.h"
 #include "../../Copyable.h"
+#include "../../min_allocator.h"
 
 template <class T, class Allocator>
 void
@@ -72,4 +73,12 @@
     test<Copyable, test_allocator<Copyable> >();
     static_assert((std::is_same<std::vector<char>::allocator_type,
                                 std::allocator<char> >::value), "");
+#if __cplusplus >= 201103L
+    static_assert((std::is_same<std::vector<int, min_allocator<int>>::value_type, int>::value), "");
+    static_assert((std::is_same<std::vector<int, min_allocator<int>>::allocator_type, min_allocator<int> >::value), "");
+    static_assert((std::is_same<std::vector<int, min_allocator<int>>::reference, int&>::value), "");
+    static_assert((std::is_same<std::vector<int, min_allocator<int>>::const_reference, const int&>::value), "");
+    static_assert((std::is_same<std::vector<int, min_allocator<int>>::pointer, min_pointer<int>>::value), "");
+    static_assert((std::is_same<std::vector<int, min_allocator<int>>::const_pointer, min_pointer<const int>>::value), "");
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp b/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp
index da4c1ca..861ec9a 100644
--- a/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp
@@ -14,6 +14,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -26,4 +28,16 @@
         v.push_back(0);
         assert(v.capacity() > 101);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v;
+        assert(v.capacity() == 0);
+    }
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        assert(v.capacity() == 100);
+        v.push_back(0);
+        assert(v.capacity() > 101);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp b/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp
index 450fc90..4b91711 100644
--- a/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -42,4 +43,21 @@
         assert(v.size() == 100);
         assert(v.capacity() == 150);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v;
+        v.reserve(10);
+        assert(v.capacity() >= 10);
+    }
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        assert(v.capacity() == 100);
+        v.reserve(50);
+        assert(v.size() == 100);
+        assert(v.capacity() == 100);
+        v.reserve(150);
+        assert(v.size() == 100);
+        assert(v.capacity() == 150);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp b/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp
index f373026..7a3389f 100644
--- a/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -57,4 +58,15 @@
         assert(v.capacity() >= 200);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        std::vector<MoveOnly, min_allocator<MoveOnly>> v(100);
+        v.resize(50);
+        assert(v.size() == 50);
+        assert(v.capacity() == 100);
+        v.resize(200);
+        assert(v.size() == 200);
+        assert(v.capacity() >= 200);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp b/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp
index 41042ba..fb26761 100644
--- a/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -40,4 +41,29 @@
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        v.resize(50, 1);
+        assert(v.size() == 50);
+        assert(v.capacity() == 100);
+        assert((v == std::vector<int, min_allocator<int>>(50)));
+        v.resize(200, 1);
+        assert(v.size() == 200);
+        assert(v.capacity() >= 200);
+        for (unsigned i = 0; i < 50; ++i)
+            assert(v[i] == 0);
+        for (unsigned i = 50; i < 200; ++i)
+            assert(v[i] == 1);
+    }
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        v.resize(50, 1);
+        assert(v.size() == 50);
+        assert(v.capacity() == 100);
+        v.resize(200, 1);
+        assert(v.size() == 200);
+        assert(v.capacity() >= 200);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp b/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp
index 896026d..7a8d0c7 100644
--- a/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -40,4 +41,13 @@
         assert(v.size() == 101);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        v.push_back(1);
+        v.shrink_to_fit();
+        assert(v.capacity() == 101);
+        assert(v.size() == 101);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/swap.pass.cpp b/test/containers/sequences/vector/vector.capacity/swap.pass.cpp
index a2673ea..8152802 100644
--- a/test/containers/sequences/vector/vector.capacity/swap.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/swap.pass.cpp
@@ -14,6 +14,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -25,4 +27,15 @@
         assert(v2.size() == 100);
         assert(v2.capacity() == 100);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v1(100);
+        std::vector<int, min_allocator<int>> v2(200);
+        v1.swap(v2);
+        assert(v1.size() == 200);
+        assert(v1.capacity() == 200);
+        assert(v2.size() == 100);
+        assert(v2.capacity() == 100);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/assign_copy.pass.cpp b/test/containers/sequences/vector/vector.cons/assign_copy.pass.cpp
index f80040f..9623d0f 100644
--- a/test/containers/sequences/vector/vector.cons/assign_copy.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/assign_copy.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -31,4 +32,13 @@
         assert(l2 == l);
         assert(l2.get_allocator() == other_allocator<int>(5));
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int> > l(3, 2, min_allocator<int>());
+        std::vector<int, min_allocator<int> > l2(l, min_allocator<int>());
+        l2 = l;
+        assert(l2 == l);
+        assert(l2.get_allocator() == min_allocator<int>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
index 5508056..13c3e49 100644
--- a/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::vector<int> d;
     d.assign({3, 4, 5, 6});
     assert(d.size() == 4);
@@ -24,5 +27,17 @@
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<int, min_allocator<int>> d;
+    d.assign({3, 4, 5, 6});
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp b/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp
index 433ba99..1a29db9 100644
--- a/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -61,5 +62,21 @@
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
+        std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::vector<MoveOnly, min_allocator<MoveOnly> > l2(min_allocator<MoveOnly>{});
+        l2 = std::move(l);
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == lo.get_allocator());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp
index 0c55fd6..ec66c0d 100644
--- a/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp
@@ -17,6 +17,7 @@
 #include "../../../test_allocator.h"
 #include "../../../NotConstructible.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -51,4 +52,17 @@
         std::vector<int, stack_allocator<int, 10> > v;
         assert(v.empty());
     }
+#if __cplusplus >= 201103L
+    {
+    test0<std::vector<int, min_allocator<int>> >();
+    test0<std::vector<NotConstructible, min_allocator<NotConstructible>> >();
+    test1<std::vector<int, min_allocator<int> > >(min_allocator<int>{});
+    test1<std::vector<NotConstructible, min_allocator<NotConstructible> > >
+        (min_allocator<NotConstructible>{});
+    }
+    {
+        std::vector<int, min_allocator<int> > v;
+        assert(v.empty());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
index 9c9b88e..6841319 100644
--- a/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_iterators.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C, class Iterator>
 void
@@ -43,4 +44,11 @@
     test<std::vector<int, stack_allocator<int, 18> > >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an));
     test<std::vector<int, stack_allocator<int, 18> > >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an));
     test<std::vector<int, stack_allocator<int, 18> > >(a, an);
+#if __cplusplus >= 201103L
+    test<std::vector<int, min_allocator<int>> >(input_iterator<const int*>(a), input_iterator<const int*>(an));
+    test<std::vector<int, min_allocator<int>> >(forward_iterator<const int*>(a), forward_iterator<const int*>(an));
+    test<std::vector<int, min_allocator<int>> >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an));
+    test<std::vector<int, min_allocator<int>> >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an));
+    test<std::vector<int> >(a, an);
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
index 17bba91..afc8ea5 100644
--- a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
@@ -17,10 +17,11 @@
 
 #include "test_iterators.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
-template <class C, class Iterator>
+template <class C, class Iterator, class A>
 void
-test(Iterator first, Iterator last, const typename C::allocator_type& a)
+test(Iterator first, Iterator last, const A& a)
 {
     C c(first, last, a);
     assert(c.__invariants());
@@ -29,8 +30,20 @@
         assert(*i == *first);
 }
 
+#if __cplusplus >= 201103L
+
+template <class T>
+struct implicit_conv_allocator : min_allocator<T>
+{
+    implicit_conv_allocator(void* p) {}
+    implicit_conv_allocator(const implicit_conv_allocator&) = default;
+};
+
+#endif
+
 int main()
 {
+    {
     int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
     int* an = a + sizeof(a)/sizeof(a[0]);
     std::allocator<int> alloc;
@@ -39,4 +52,18 @@
     test<std::vector<int> >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an), alloc);
     test<std::vector<int> >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an), alloc);
     test<std::vector<int> >(a, an, alloc);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
+    int* an = a + sizeof(a)/sizeof(a[0]);
+    min_allocator<int> alloc;
+    test<std::vector<int, min_allocator<int>> >(input_iterator<const int*>(a), input_iterator<const int*>(an), alloc);
+    test<std::vector<int, min_allocator<int>> >(forward_iterator<const int*>(a), forward_iterator<const int*>(an), alloc);
+    test<std::vector<int, min_allocator<int>> >(bidirectional_iterator<const int*>(a), bidirectional_iterator<const int*>(an), alloc);
+    test<std::vector<int, min_allocator<int>> >(random_access_iterator<const int*>(a), random_access_iterator<const int*>(an), alloc);
+    test<std::vector<int, min_allocator<int>> >(a, an, alloc);
+    test<std::vector<int, implicit_conv_allocator<int>> >(a, an, nullptr);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp
index 9be5eb6..19d2760 100644
--- a/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp
@@ -15,10 +15,28 @@
 #include <cassert>
 
 #include "../../../DefaultOnly.h"
+#include "../../../min_allocator.h"
+#include "../../../test_allocator.h"
 
 template <class C>
 void
-test(typename C::size_type n)
+test2(typename C::size_type n, typename C::allocator_type const& a = typename C::allocator_type ())
+{
+#if _LIBCPP_STD_VER > 11
+    C c(n, a);
+    assert(c.__invariants());
+    assert(c.size() == n);
+    assert(c.get_allocator() == a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i)
+        assert(*i == typename C::value_type());
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
+}
+
+template <class C>
+void
+test1(typename C::size_type n)
 {
     C c(n);
     assert(c.__invariants());
@@ -30,9 +48,23 @@
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
 
+template <class C>
+void
+test(typename C::size_type n)
+{
+    test1<C> ( n );
+    test2<C> ( n );
+}
+
 int main()
 {
     test<std::vector<int> >(50);
     test<std::vector<DefaultOnly> >(500);
     assert(DefaultOnly::count == 0);
+#if __cplusplus >= 201103L
+    test<std::vector<int, min_allocator<int>> >(50);
+    test<std::vector<DefaultOnly, min_allocator<DefaultOnly>> >(500);
+    test2<std::vector<DefaultOnly, test_allocator<DefaultOnly>> >( 100, test_allocator<DefaultOnly>(23));
+    assert(DefaultOnly::count == 0);
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp
index e71197b..35adaed 100644
--- a/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -31,4 +32,7 @@
 {
     test<std::vector<int> >(50, 3);
     test<std::vector<int, stack_allocator<int, 50> > >(50, 5);
+#if __cplusplus >= 201103L
+    test<std::vector<int, min_allocator<int>> >(50, 3);
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp
index e6a0157..27da426 100644
--- a/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp
@@ -13,6 +13,7 @@
 
 #include <vector>
 #include <cassert>
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -30,4 +31,7 @@
 int main()
 {
     test<std::vector<int> >(50, 3, std::allocator<int>());
+#if __cplusplus >= 201103L
+    test<std::vector<int, min_allocator<int>> >(50, 3, min_allocator<int>());
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/copy.pass.cpp b/test/containers/sequences/vector/vector.cons/copy.pass.cpp
index 4dc2ab7..34008ae 100644
--- a/test/containers/sequences/vector/vector.cons/copy.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/copy.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -47,4 +48,17 @@
         assert(v2.get_allocator() == other_allocator<int>(-2));
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
+        int* an = a + sizeof(a)/sizeof(a[0]);
+        test(std::vector<int, min_allocator<int>>(a, an));
+    }
+    {
+        std::vector<int, min_allocator<int> > v(3, 2, min_allocator<int>());
+        std::vector<int, min_allocator<int> > v2 = v;
+        assert(v2 == v);
+        assert(v2.get_allocator() == v.get_allocator());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp
index 47fc008..22fca55 100644
--- a/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 template <class C>
 void
@@ -45,4 +46,17 @@
         assert(l2 == l);
         assert(l2.get_allocator() == other_allocator<int>(3));
     }
+#if __cplusplus >= 201103L
+    {
+        int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
+        int* an = a + sizeof(a)/sizeof(a[0]);
+        test(std::vector<int, min_allocator<int>>(a, an), min_allocator<int>());
+    }
+    {
+        std::vector<int, min_allocator<int> > l(3, 2, min_allocator<int>());
+        std::vector<int, min_allocator<int> > l2(l, min_allocator<int>());
+        assert(l2 == l);
+        assert(l2.get_allocator() == min_allocator<int>());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp
index 5c33ad7..938c036 100644
--- a/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp
@@ -13,15 +13,28 @@
 
 #include <vector>
 #include <cassert>
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::vector<int> d = {3, 4, 5, 6};
     assert(d.size() == 4);
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<int, min_allocator<int>> d = {3, 4, 5, 6};
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp
index f993526..12d27c6 100644
--- a/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp
@@ -15,10 +15,12 @@
 #include <cassert>
 
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::vector<int, test_allocator<int>> d({3, 4, 5, 6}, test_allocator<int>(3));
     assert(d.get_allocator() == test_allocator<int>(3));
     assert(d.size() == 4);
@@ -26,5 +28,17 @@
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<int, min_allocator<int>> d({3, 4, 5, 6}, min_allocator<int>());
+    assert(d.get_allocator() == min_allocator<int>());
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector/vector.cons/move.pass.cpp b/test/containers/sequences/vector/vector.cons/move.pass.cpp
index b036405..0514f31 100644
--- a/test/containers/sequences/vector/vector.cons/move.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/move.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -53,5 +54,28 @@
         std::vector<int>::iterator j = c2.erase(i);
         assert(*j == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
+        std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::vector<MoveOnly, min_allocator<MoveOnly> > l2 = std::move(l);
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == lo.get_allocator());
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::vector<int, min_allocator<int>>::const_iterator i = c1.begin();
+        std::vector<int, min_allocator<int>> c2 = std::move(c1);
+        std::vector<int, min_allocator<int>>::iterator j = c2.erase(i);
+        assert(*j == 3);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp
index f2a63d1..2f590dc 100644
--- a/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../MoveOnly.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -58,5 +59,20 @@
         assert(!l.empty());
         assert(l2.get_allocator() == other_allocator<MoveOnly>(4));
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
+        std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        for (int i = 1; i <= 3; ++i)
+        {
+            l.push_back(i);
+            lo.push_back(i);
+        }
+        std::vector<MoveOnly, min_allocator<MoveOnly> > l2(std::move(l), min_allocator<MoveOnly>());
+        assert(l2 == lo);
+        assert(l.empty());
+        assert(l2.get_allocator() == min_allocator<MoveOnly>());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp
index 8b28fe5..916ddaa 100644
--- a/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::vector<int> d;
     d = {3, 4, 5, 6};
     assert(d.size() == 4);
@@ -24,5 +27,17 @@
     assert(d[1] == 4);
     assert(d[2] == 5);
     assert(d[3] == 6);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<int, min_allocator<int>> d;
+    d = {3, 4, 5, 6};
+    assert(d.size() == 4);
+    assert(d[0] == 3);
+    assert(d[1] == 4);
+    assert(d[2] == 5);
+    assert(d[3] == 6);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector/vector.data/data.pass.cpp b/test/containers/sequences/vector/vector.data/data.pass.cpp
index 0359ff9..9ae3243 100644
--- a/test/containers/sequences/vector/vector.data/data.pass.cpp
+++ b/test/containers/sequences/vector/vector.data/data.pass.cpp
@@ -14,6 +14,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -24,4 +26,14 @@
         std::vector<int> v(100);
         assert(v.data() == &v.front());
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v;
+        assert(v.data() == 0);
+    }
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        assert(v.data() == &v.front());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.data/data_const.pass.cpp b/test/containers/sequences/vector/vector.data/data_const.pass.cpp
index 60232f2..77e8b83 100644
--- a/test/containers/sequences/vector/vector.data/data_const.pass.cpp
+++ b/test/containers/sequences/vector/vector.data/data_const.pass.cpp
@@ -14,6 +14,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -24,4 +26,14 @@
         const std::vector<int> v(100);
         assert(v.data() == &v.front());
     }
+#if __cplusplus >= 201103L
+    {
+        const std::vector<int, min_allocator<int>> v;
+        assert(v.data() == 0);
+    }
+    {
+        const std::vector<int, min_allocator<int>> v(100);
+        assert(v.data() == &v.front());
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp
index d85b8f2..7cca940 100644
--- a/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp
@@ -11,13 +11,14 @@
 
 // template <class... Args> iterator emplace(const_iterator pos, Args&&... args);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
@@ -106,7 +107,7 @@
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::vector<A> c1;
         std::vector<A> c2;
@@ -114,5 +115,39 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::vector<A, min_allocator<A>> c;
+        std::vector<A, min_allocator<A>>::iterator i = c.emplace(c.cbegin(), 2, 3.5);
+        assert(i == c.begin());
+        assert(c.size() == 1);
+        assert(c.front().geti() == 2);
+        assert(c.front().getd() == 3.5);
+        i = c.emplace(c.cend(), 3, 4.5);
+        assert(i == c.end()-1);
+        assert(c.size() == 2);
+        assert(c.front().geti() == 2);
+        assert(c.front().getd() == 3.5);
+        assert(c.back().geti() == 3);
+        assert(c.back().getd() == 4.5);
+        i = c.emplace(c.cbegin()+1, 4, 6.5);
+        assert(i == c.begin()+1);
+        assert(c.size() == 3);
+        assert(c.front().geti() == 2);
+        assert(c.front().getd() == 3.5);
+        assert(c[1].geti() == 4);
+        assert(c[1].getd() == 6.5);
+        assert(c.back().geti() == 3);
+        assert(c.back().getd() == 4.5);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::vector<A, min_allocator<A>> c1;
+        std::vector<A, min_allocator<A>> c2;
+        std::vector<A, min_allocator<A>>::iterator i = c1.emplace(c2.cbegin(), 2, 3.5);
+        assert(false);
+    }
+#endif
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp
index 5b6aae7..1d024d4 100644
--- a/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
@@ -80,5 +81,20 @@
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<A, min_allocator<A>> c;
+        c.emplace_back(2, 3.5);
+        assert(c.size() == 1);
+        assert(c.front().geti() == 2);
+        assert(c.front().getd() == 3.5);
+        c.emplace_back(3, 4.5);
+        assert(c.size() == 2);
+        assert(c.front().geti() == 2);
+        assert(c.front().getd() == 3.5);
+        assert(c.back().geti() == 3);
+        assert(c.back().getd() == 4.5);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp
index 26a394f..d703207 100644
--- a/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp
@@ -13,6 +13,9 @@
 
 #include <vector>
 #include <cassert>
+
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -30,5 +33,21 @@
         v.emplace(v.begin(), v.back());
         assert(v[0] == 3);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v;
+        v.reserve(3);
+        v = { 1, 2, 3 };
+        v.emplace(v.begin(), v.back());
+        assert(v[0] == 3);
+    }
+    {
+        std::vector<int, min_allocator<int>> v;
+        v.reserve(4);
+        v = { 1, 2, 3 };
+        v.emplace(v.begin(), v.back());
+        assert(v[0] == 3);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
index 6489c2b..6fcd189 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
@@ -14,8 +14,11 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int>::const_iterator i = l1.begin();
@@ -35,4 +38,28 @@
     assert(j == l1.end());
     assert(l1.size() == 0);
     assert(distance(l1.begin(), l1.end()) == 0);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::vector<int, min_allocator<int>> l1(a1, a1+3);
+    std::vector<int, min_allocator<int>>::const_iterator i = l1.begin();
+    ++i;
+    std::vector<int, min_allocator<int>>::iterator j = l1.erase(i);
+    assert(l1.size() == 2);
+    assert(distance(l1.begin(), l1.end()) == 2);
+    assert(*j == 3);
+    assert(*l1.begin() == 1);
+    assert(*next(l1.begin()) == 3);
+    j = l1.erase(j);
+    assert(j == l1.end());
+    assert(l1.size() == 1);
+    assert(distance(l1.begin(), l1.end()) == 1);
+    assert(*l1.begin() == 1);
+    j = l1.erase(l1.begin());
+    assert(j == l1.end());
+    assert(l1.size() == 0);
+    assert(distance(l1.begin(), l1.end()) == 0);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp
index 81f1354..bd20844 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_db1.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator position) with end()
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <cstdlib>
 #include <exception>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int>::const_iterator i = l1.end();
     l1.erase(i);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::vector<int, min_allocator<int>> l1(a1, a1+3);
+    std::vector<int, min_allocator<int>>::const_iterator i = l1.end();
+    l1.erase(i);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp
index 15fa5a3..bbad13b 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_db2.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator position) with iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,14 +20,28 @@
 #include <cstdlib>
 #include <exception>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int> l2(a1, a1+3);
     std::vector<int>::const_iterator i = l2.begin();
     l1.erase(i);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::vector<int, min_allocator<int>> l1(a1, a1+3);
+    std::vector<int, min_allocator<int>> l2(a1, a1+3);
+    std::vector<int, min_allocator<int>>::const_iterator i = l2.begin();
+    l1.erase(i);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
index 5fdcb87..8a382ed 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
@@ -14,6 +14,8 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     int a1[] = {1, 2, 3};
@@ -54,4 +56,43 @@
         assert(outer[0].size() == 1);
         assert(outer[1].size() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), l1.cbegin());
+        assert(l1.size() == 3);
+        assert(distance(l1.cbegin(), l1.cend()) == 3);
+        assert(i == l1.begin());
+    }
+    {
+        std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin()));
+        assert(l1.size() == 2);
+        assert(distance(l1.cbegin(), l1.cend()) == 2);
+        assert(i == l1.begin());
+        assert((l1 == std::vector<int, min_allocator<int>>(a1+1, a1+3)));
+    }
+    {
+        std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2));
+        assert(l1.size() == 1);
+        assert(distance(l1.cbegin(), l1.cend()) == 1);
+        assert(i == l1.begin());
+        assert((l1 == std::vector<int, min_allocator<int>>(a1+2, a1+3)));
+    }
+    {
+        std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3));
+        assert(l1.size() == 0);
+        assert(distance(l1.cbegin(), l1.cend()) == 0);
+        assert(i == l1.begin());
+    }
+    {
+        std::vector<std::vector<int, min_allocator<int>>, min_allocator<std::vector<int, min_allocator<int>>>> outer(2, std::vector<int, min_allocator<int>>(1));
+        outer.erase(outer.begin(), outer.begin());
+        assert(outer.size() == 2);
+        assert(outer[0].size() == 1);
+        assert(outer[1].size() == 1);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp
index 846e111..395d97b 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db1.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with first iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int> l2(a1, a1+3);
     std::vector<int>::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::vector<int, min_allocator<int>> l1(a1, a1+3);
+    std::vector<int, min_allocator<int>> l2(a1, a1+3);
+    std::vector<int, min_allocator<int>>::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp
index 04cb5dc..1f87c80 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db2.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with second iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int> l2(a1, a1+3);
     std::vector<int>::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::vector<int, min_allocator<int>> l1(a1, a1+3);
+    std::vector<int, min_allocator<int>> l2(a1, a1+3);
+    std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp
index a614a11..ab9cc37 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db3.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with both iterators from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,13 +20,26 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int> l2(a1, a1+3);
     std::vector<int>::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1);
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::vector<int, min_allocator<int>> l1(a1, a1+3);
+    std::vector<int, min_allocator<int>> l2(a1, a1+3);
+    std::vector<int, min_allocator<int>>::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1);
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp
index 9818024..141598e 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter_db4.pass.cpp
@@ -11,7 +11,7 @@
 
 // Call erase(const_iterator first, const_iterator last); with a bad range
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
@@ -20,12 +20,24 @@
 #include <exception>
 #include <cstdlib>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
+    {
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int>::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin());
     assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    int a1[] = {1, 2, 3};
+    std::vector<int, min_allocator<int>> l1(a1, a1+3);
+    std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin());
+    assert(false);
+    }
+#endif
 }
 
 #else
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp
index 65247bf..caba784 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp
@@ -14,9 +14,12 @@
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    {
     std::vector<int> d(10, 1);
     std::vector<int>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6});
     assert(d.size() == 14);
@@ -35,5 +38,28 @@
     assert(d[11] == 1);
     assert(d[12] == 1);
     assert(d[13] == 1);
+    }
+#if __cplusplus >= 201103L
+    {
+    std::vector<int, min_allocator<int>> d(10, 1);
+    std::vector<int, min_allocator<int>>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6});
+    assert(d.size() == 14);
+    assert(i == d.begin() + 2);
+    assert(d[0] == 1);
+    assert(d[1] == 1);
+    assert(d[2] == 3);
+    assert(d[3] == 4);
+    assert(d[4] == 5);
+    assert(d[5] == 6);
+    assert(d[6] == 1);
+    assert(d[7] == 1);
+    assert(d[8] == 1);
+    assert(d[9] == 1);
+    assert(d[10] == 1);
+    assert(d[11] == 1);
+    assert(d[12] == 1);
+    assert(d[13] == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
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 9f68aef..41566a8 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
@@ -12,7 +12,7 @@
 // template <class Iter>
 //   iterator insert(const_iterator position, Iter first, Iter last);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
@@ -20,6 +20,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -87,7 +88,7 @@
         for (; j < 105; ++j)
             assert(v[j] == 0);
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::vector<int> v(100);
         std::vector<int> v2(100);
@@ -98,4 +99,49 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        int a[] = {1, 2, 3, 4, 5};
+        const int N = sizeof(a)/sizeof(a[0]);
+        std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
+                                        input_iterator<const int*>(a+N));
+        assert(v.size() == 100 + N);
+        assert(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 < 105; ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        int a[] = {1, 2, 3, 4, 5};
+        const int N = sizeof(a)/sizeof(a[0]);
+        std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
+                                        forward_iterator<const int*>(a+N));
+        assert(v.size() == 100 + N);
+        assert(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 < 105; ++j)
+            assert(v[j] == 0);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        std::vector<int, min_allocator<int>> v2(100);
+        int a[] = {1, 2, 3, 4, 5};
+        const int N = sizeof(a)/sizeof(a[0]);
+        std::vector<int, min_allocator<int>>::iterator i = v.insert(v2.cbegin() + 10, input_iterator<const int*>(a),
+                                        input_iterator<const int*>(a+N));
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp
index e34dc36..2f4b8e8 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp
@@ -11,7 +11,7 @@
 
 // iterator insert(const_iterator position, value_type&& x);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
@@ -19,6 +19,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -47,7 +48,7 @@
         for (++j; j < 101; ++j)
             assert(v[j] == MoveOnly());
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::vector<int> v1(3);
         std::vector<int> v2(3);
@@ -55,5 +56,27 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::vector<MoveOnly, min_allocator<MoveOnly>> v(100);
+        std::vector<MoveOnly, min_allocator<MoveOnly>>::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3));
+        assert(v.size() == 101);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == MoveOnly());
+        assert(v[j] == MoveOnly(3));
+        for (++j; j < 101; ++j)
+            assert(v[j] == MoveOnly());
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::vector<int, min_allocator<int>> v1(3);
+        std::vector<int, min_allocator<int>> v2(3);
+        v1.insert(v2.begin(), 4);
+        assert(false);
+    }
+#endif
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
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 ed94057..e4232ff 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
@@ -11,13 +11,14 @@
 
 // iterator insert(const_iterator position, size_type n, const value_type& x);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -47,7 +48,7 @@
         for (++j; j < 105; ++j)
             assert(v[j] == 0);
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::vector<int> c1(100);
         std::vector<int> c2;
@@ -55,4 +56,40 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
+        assert(v.size() == 105);
+        assert(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 < 105; ++j)
+            assert(v[j] == 0);
+    }
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
+        assert(v.size() == 105);
+        assert(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 < 105; ++j)
+            assert(v[j] == 0);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::vector<int, min_allocator<int>> c1(100);
+        std::vector<int, min_allocator<int>> c2;
+        std::vector<int, min_allocator<int>>::iterator i = c1.insert(c2.cbegin() + 10, 5, 1);
+        assert(false);
+    }
+#endif
+#endif
 }
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 5bc87fd..d24847b 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
@@ -11,13 +11,14 @@
 
 // iterator insert(const_iterator position, const value_type& x);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -45,7 +46,7 @@
         for (++j; j < 101; ++j)
             assert(v[j] == 0);
     }
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         std::vector<int> v1(3);
         std::vector<int> v2(3);
@@ -54,4 +55,27 @@
         assert(false);
     }
 #endif
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> v(100);
+        std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 1);
+        assert(v.size() == 101);
+        assert(i == v.begin() + 10);
+        int j;
+        for (j = 0; j < 10; ++j)
+            assert(v[j] == 0);
+        assert(v[j] == 1);
+        for (++j; j < 101; ++j)
+            assert(v[j] == 0);
+    }
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::vector<int, min_allocator<int>> v1(3);
+        std::vector<int, min_allocator<int>> v2(3);
+        int i = 4;
+        v1.insert(v2.begin(), i);
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp b/test/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp
index abfefb0..16891ae 100644
--- a/test/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/pop_back.pass.cpp
@@ -11,15 +11,16 @@
 
 // void pop_back();
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #include <cstdlib>
 #include <exception>
 
@@ -33,9 +34,22 @@
         assert(c.size() == 1);
         c.pop_back();
         assert(c.size() == 0);
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
         c.pop_back();
         assert(false);
 #endif        
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> c;
+        c.push_back(1);
+        assert(c.size() == 1);
+        c.pop_back();
+        assert(c.size() == 0);
+#if _LIBCPP_DEBUG >= 1
+        c.pop_back();
+        assert(false);
+#endif        
+    }
+#endif        
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp
index fba4d0b..3170fe8 100644
--- a/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -63,4 +64,29 @@
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<int, min_allocator<int>> c;
+        c.push_back(0);
+        assert(c.size() == 1);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == j);
+        c.push_back(1);
+        assert(c.size() == 2);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == j);
+        c.push_back(2);
+        assert(c.size() == 3);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == j);
+        c.push_back(3);
+        assert(c.size() == 4);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == j);
+        c.push_back(4);
+        assert(c.size() == 5);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == j);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
index 17a13a8..cd81e60 100644
--- a/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
@@ -19,14 +19,14 @@
 
 
 class CMyClass {
-	public: CMyClass();
-	public: CMyClass(const CMyClass& iOther);
-	public: ~CMyClass();
+    public: CMyClass();
+    public: CMyClass(const CMyClass& iOther);
+    public: ~CMyClass();
 
-	private: int fMagicValue;
+    private: int fMagicValue;
 
-	private: static int kStartedConstructionMagicValue;
-	private: static int kFinishedConstructionMagicValue;
+    private: static int kStartedConstructionMagicValue;
+    private: static int kFinishedConstructionMagicValue;
 };
 
 // Value for fMagicValue when the constructor has started running, but not yet finished
@@ -35,39 +35,39 @@
 int CMyClass::kFinishedConstructionMagicValue = 12345;
 
 CMyClass::CMyClass() :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::CMyClass(const CMyClass& /*iOther*/) :
-	fMagicValue(kStartedConstructionMagicValue)
+    fMagicValue(kStartedConstructionMagicValue)
 {
-	// If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
-	if (gCopyConstructorShouldThow) {
-		throw std::exception();
-	}
-	// Signal that the constructor has finished running
-	fMagicValue = kFinishedConstructionMagicValue;
+    // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
+    if (gCopyConstructorShouldThow) {
+        throw std::exception();
+    }
+    // Signal that the constructor has finished running
+    fMagicValue = kFinishedConstructionMagicValue;
 }
 
 CMyClass::~CMyClass() {
-	// Only instances for which the constructor has finished running should be destructed
-	assert(fMagicValue == kFinishedConstructionMagicValue);
+    // Only instances for which the constructor has finished running should be destructed
+    assert(fMagicValue == kFinishedConstructionMagicValue);
 }
 
 int main()
 {
-	CMyClass instance;
-	std::vector<CMyClass> vec;
+    CMyClass instance;
+    std::vector<CMyClass> vec;
 
-	vec.push_back(instance);
+    vec.push_back(instance);
 
-	gCopyConstructorShouldThow = true;
-	try {
-		vec.push_back(instance);
-	}
-	catch (...) {
-	}
+    gCopyConstructorShouldThow = true;
+    try {
+        vec.push_back(instance);
+    }
+    catch (...) {
+    }
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp
index 1f0bc76..0127dbc 100644
--- a/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../MoveOnly.h"
 #include "../../../stack_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -65,5 +66,30 @@
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
     }
+#if __cplusplus >= 201103L
+    {
+        std::vector<MoveOnly, min_allocator<MoveOnly>> c;
+        c.push_back(MoveOnly(0));
+        assert(c.size() == 1);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == MoveOnly(j));
+        c.push_back(MoveOnly(1));
+        assert(c.size() == 2);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == MoveOnly(j));
+        c.push_back(MoveOnly(2));
+        assert(c.size() == 3);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == MoveOnly(j));
+        c.push_back(MoveOnly(3));
+        assert(c.size() == 4);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == MoveOnly(j));
+        c.push_back(MoveOnly(4));
+        assert(c.size() == 5);
+        for (int j = 0; j < c.size(); ++j)
+            assert(c[j] == MoveOnly(j));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/sequences/vector/vector.special/db_swap_1.pass.cpp b/test/containers/sequences/vector/vector.special/db_swap_1.pass.cpp
index e0ae808..7443fec 100644
--- a/test/containers/sequences/vector/vector.special/db_swap_1.pass.cpp
+++ b/test/containers/sequences/vector/vector.special/db_swap_1.pass.cpp
@@ -12,16 +12,18 @@
 // template <class T, class Alloc>
 //   void swap(vector<T,Alloc>& x, vector<T,Alloc>& y);
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 #endif
 
 #include <vector>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
@@ -35,5 +37,20 @@
         c1.erase(i1);
         assert(false);
     }
+#if __cplusplus >= 201103L
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::vector<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        std::vector<int, min_allocator<int>>::iterator i1 = c1.begin();
+        std::vector<int, min_allocator<int>>::iterator i2 = c2.begin();
+        swap(c1, c2);
+        c1.erase(i2);
+        c2.erase(i1);
+        c1.erase(i1);
+        assert(false);
+    }
+#endif
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.special/swap.pass.cpp b/test/containers/sequences/vector/vector.special/swap.pass.cpp
index 7cad0f4..8e2ea37 100644
--- a/test/containers/sequences/vector/vector.special/swap.pass.cpp
+++ b/test/containers/sequences/vector/vector.special/swap.pass.cpp
@@ -15,6 +15,7 @@
 #include <vector>
 #include <cassert>
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -85,4 +86,61 @@
         assert((c2 == std::vector<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
         assert(c2.get_allocator() == A(1));
     }
+#if __cplusplus >= 201103L
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::vector<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        swap(c1, c2);
+        assert((c1 == std::vector<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+        assert((c2 == std::vector<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::vector<int, min_allocator<int>> c1(a1, a1);
+        std::vector<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        swap(c1, c2);
+        assert((c1 == std::vector<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+        assert(c2.empty());
+        assert(distance(c2.begin(), c2.end()) == 0);
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::vector<int, min_allocator<int>> c2(a2, a2);
+        swap(c1, c2);
+        assert(c1.empty());
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert((c2 == std::vector<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+    }
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::vector<int, min_allocator<int>> c1(a1, a1);
+        std::vector<int, min_allocator<int>> c2(a2, a2);
+        swap(c1, c2);
+        assert(c1.empty());
+        assert(distance(c1.begin(), c1.end()) == 0);
+        assert(c2.empty());
+        assert(distance(c2.begin(), c2.end()) == 0);
+    }
+#ifndef _LIBCPP_DEBUG_LEVEL
+// This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        typedef min_allocator<int> A;
+        std::vector<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A());
+        std::vector<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A());
+        swap(c1, c2);
+        assert((c1 == std::vector<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
+        assert(c1.get_allocator() == A());
+        assert((c2 == std::vector<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+        assert(c2.get_allocator() == A());
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.map/bucket.pass.cpp b/test/containers/unord/unord.map/bucket.pass.cpp
index 6cb6fbb..aa69708 100644
--- a/test/containers/unord/unord.map/bucket.pass.cpp
+++ b/test/containers/unord/unord.map/bucket.pass.cpp
@@ -15,10 +15,16 @@
 
 // size_type bucket(const key_type& __k) const;
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -39,4 +45,33 @@
         for (size_t i = 0; i < 13; ++i)
             assert(c.bucket(i) == i % bc);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(std::begin(a), std::end(a));
+        size_t bc = c.bucket_count();
+        assert(bc >= 5);
+        for (size_t i = 0; i < 13; ++i)
+            assert(c.bucket(i) == i % bc);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_map<int, std::string> C;
+        C c;
+        C::size_type i = c.bucket(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/bucket_count.pass.cpp b/test/containers/unord/unord.map/bucket_count.pass.cpp
index 478f9ad..dbc24ee 100644
--- a/test/containers/unord/unord.map/bucket_count.pass.cpp
+++ b/test/containers/unord/unord.map/bucket_count.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -46,4 +48,33 @@
         const C c(std::begin(a), std::end(a));
         assert(c.bucket_count() >= 11);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::const_iterator I;
+        typedef std::pair<int, std::string> P;
+        const C c;
+        assert(c.bucket_count() == 0);
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::const_iterator I;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.bucket_count() >= 11);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/bucket_size.pass.cpp b/test/containers/unord/unord.map/bucket_size.pass.cpp
index ab1f684..6000ab9 100644
--- a/test/containers/unord/unord.map/bucket_size.pass.cpp
+++ b/test/containers/unord/unord.map/bucket_size.pass.cpp
@@ -15,10 +15,16 @@
 
 // size_type bucket_size(size_type n) const
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -41,4 +47,35 @@
         assert(c.bucket_size(3) == 1);
         assert(c.bucket_size(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.bucket_count() >= 5);
+        assert(c.bucket_size(0) == 0);
+        assert(c.bucket_size(1) == 1);
+        assert(c.bucket_size(2) == 1);
+        assert(c.bucket_size(3) == 1);
+        assert(c.bucket_size(4) == 1);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_map<int, std::string> C;
+        C c;
+        C::size_type i = c.bucket_size(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/compare.pass.cpp b/test/containers/unord/unord.map/compare.pass.cpp
new file mode 100644
index 0000000..8979a3a
--- /dev/null
+++ b/test/containers/unord/unord.map/compare.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+//           class Alloc = allocator<pair<const Key, T>>>
+// class unordered_map
+
+// http://llvm.org/bugs/show_bug.cgi?id=16538
+// http://llvm.org/bugs/show_bug.cgi?id=16549
+
+#include <unordered_map>
+
+struct Key {
+  template <typename T> Key(const T&) {}
+  bool operator== (const Key&) const { return true; }
+};
+
+namespace std
+{
+    template <>
+    struct hash<Key>
+    {
+        size_t operator()(Key const &) const {return 0;}
+    };
+}
+
+int
+main()
+{
+    std::unordered_map<Key, int>::iterator it =
+        std::unordered_map<Key, int>().find(Key(0));
+    std::pair<std::unordered_map<Key, int>::iterator, bool> result =
+        std::unordered_map<Key, int>().insert(std::make_pair(Key(0), 0));
+}
diff --git a/test/containers/unord/unord.map/count.pass.cpp b/test/containers/unord/unord.map/count.pass.cpp
index fa40d0a..04d1699 100644
--- a/test/containers/unord/unord.map/count.pass.cpp
+++ b/test/containers/unord/unord.map/count.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -39,4 +41,25 @@
         assert(c.count(30) == 1);
         assert(c.count(5) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.count(30) == 1);
+        assert(c.count(5) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/db_iterators_7.pass.cpp b/test/containers/unord/unord.map/db_iterators_7.pass.cpp
new file mode 100644
index 0000000..4e1ad1e
--- /dev/null
+++ b/test/containers/unord/unord.map/db_iterators_7.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_map<int, std::string> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/db_iterators_8.pass.cpp b/test/containers/unord/unord.map/db_iterators_8.pass.cpp
new file mode 100644
index 0000000..dbf0dde
--- /dev/null
+++ b/test/containers/unord/unord.map/db_iterators_8.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_map<int, std::string> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.end();
+    C::value_type j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.end();
+    C::value_type j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/db_local_iterators_7.pass.cpp b/test/containers/unord/unord.map/db_local_iterators_7.pass.cpp
new file mode 100644
index 0000000..95797f2
--- /dev/null
+++ b/test/containers/unord/unord.map/db_local_iterators_7.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment local_iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_map<int, std::string> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#endif
+
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/db_local_iterators_8.pass.cpp b/test/containers/unord/unord.map/db_local_iterators_8.pass.cpp
new file mode 100644
index 0000000..8a2ae76
--- /dev/null
+++ b/test/containers/unord/unord.map/db_local_iterators_8.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_map<int, std::string> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    C::value_type j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    C::value_type j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/eq.pass.cpp b/test/containers/unord/unord.map/eq.pass.cpp
index 8e7ed99..ec13785 100644
--- a/test/containers/unord/unord.map/eq.pass.cpp
+++ b/test/containers/unord/unord.map/eq.pass.cpp
@@ -23,6 +23,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -89,4 +91,73 @@
         assert( (c1 == c2));
         assert(!(c1 != c2));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2;
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2 = c1;
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(std::begin(a), std::end(a));
+        C c2 = c1;
+        c2.rehash(30);
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+        c2.insert(P(90, "ninety"));
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+        c1.insert(P(90, "ninety"));
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/equal_range_const.pass.cpp b/test/containers/unord/unord.map/equal_range_const.pass.cpp
index 766d740..8f9c58e 100644
--- a/test/containers/unord/unord.map/equal_range_const.pass.cpp
+++ b/test/containers/unord/unord.map/equal_range_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -44,4 +46,30 @@
         r = c.equal_range(5);
         assert(std::distance(r.first, r.second) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::const_iterator I;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(r.first->first == 30);
+        assert(r.first->second == "thirty");
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/equal_range_non_const.pass.cpp b/test/containers/unord/unord.map/equal_range_non_const.pass.cpp
index ddc930f..9291eb4 100644
--- a/test/containers/unord/unord.map/equal_range_non_const.pass.cpp
+++ b/test/containers/unord/unord.map/equal_range_non_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -44,4 +46,30 @@
         r = c.equal_range(5);
         assert(std::distance(r.first, r.second) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::iterator I;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(r.first->first == 30);
+        assert(r.first->second == "thirty");
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/find_const.pass.cpp b/test/containers/unord/unord.map/find_const.pass.cpp
index 5d4eefb..c049d23 100644
--- a/test/containers/unord/unord.map/find_const.pass.cpp
+++ b/test/containers/unord/unord.map/find_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,28 @@
         i = c.find(5);
         assert(i == c.cend());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        C::const_iterator i = c.find(30);
+        assert(i->first == 30);
+        assert(i->second == "thirty");
+        i = c.find(5);
+        assert(i == c.cend());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/find_non_const.pass.cpp b/test/containers/unord/unord.map/find_non_const.pass.cpp
index c6ebe63..0412693 100644
--- a/test/containers/unord/unord.map/find_non_const.pass.cpp
+++ b/test/containers/unord/unord.map/find_non_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,28 @@
         i = c.find(5);
         assert(i == c.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c(std::begin(a), std::end(a));
+        C::iterator i = c.find(30);
+        assert(i->first == 30);
+        assert(i->second == "thirty");
+        i = c.find(5);
+        assert(i == c.end());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/iterators.pass.cpp b/test/containers/unord/unord.map/iterators.pass.cpp
index c8a5266..c780a66 100644
--- a/test/containers/unord/unord.map/iterators.pass.cpp
+++ b/test/containers/unord/unord.map/iterators.pass.cpp
@@ -24,6 +24,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -64,4 +66,60 @@
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
         C::const_iterator i;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        assert(c.size() == 4);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::iterator i;
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        assert(c.size() == 4);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::const_iterator i;
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::unordered_map<int,double> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+        
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/load_factor.pass.cpp b/test/containers/unord/unord.map/load_factor.pass.cpp
index fcb2b9b..70e6048 100644
--- a/test/containers/unord/unord.map/load_factor.pass.cpp
+++ b/test/containers/unord/unord.map/load_factor.pass.cpp
@@ -20,6 +20,8 @@
 #include <cassert>
 #include <cfloat>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -45,4 +47,31 @@
         const C c;
         assert(c.load_factor() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        const C c;
+        assert(c.load_factor() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/local_iterators.pass.cpp b/test/containers/unord/unord.map/local_iterators.pass.cpp
index c9812d0..ec10f50 100644
--- a/test/containers/unord/unord.map/local_iterators.pass.cpp
+++ b/test/containers/unord/unord.map/local_iterators.pass.cpp
@@ -24,6 +24,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -218,4 +220,202 @@
         assert(i->first == 4);
         assert(i->second == "four");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 1);
+        assert(i->second == "one");
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 2);
+        assert(i->second == "two");
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 1);
+        assert(i->second == "one");
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 2);
+        assert(i->second == "two");
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 1);
+        assert(i->second == "one");
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 2);
+        assert(i->second == "two");
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 1);
+        assert(i->second == "one");
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 2);
+        assert(i->second == "two");
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/max_bucket_count.pass.cpp b/test/containers/unord/unord.map/max_bucket_count.pass.cpp
index 2a89f5c..a1f1c3c 100644
--- a/test/containers/unord/unord.map/max_bucket_count.pass.cpp
+++ b/test/containers/unord/unord.map/max_bucket_count.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -28,4 +30,14 @@
         const C c;
         assert(c.max_bucket_count() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::const_iterator I;
+        typedef std::pair<int, std::string> P;
+        const C c;
+        assert(c.max_bucket_count() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/max_load_factor.pass.cpp b/test/containers/unord/unord.map/max_load_factor.pass.cpp
index 57b64b2..925997b 100644
--- a/test/containers/unord/unord.map/max_load_factor.pass.cpp
+++ b/test/containers/unord/unord.map/max_load_factor.pass.cpp
@@ -16,10 +16,16 @@
 // float max_load_factor() const;
 // void max_load_factor(float mlf);
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -36,4 +42,30 @@
         c.max_load_factor(2.5);
         assert(c.max_load_factor() == 2.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        const C c;
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        C c;
+        assert(c.max_load_factor() == 1);
+        c.max_load_factor(2.5);
+        assert(c.max_load_factor() == 2.5);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_map<int, std::string> C;
+        C c;
+        c.max_load_factor(0);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/max_size.pass.cpp b/test/containers/unord/unord.map/max_size.pass.cpp
index bde1e2d..1993741 100644
--- a/test/containers/unord/unord.map/max_size.pass.cpp
+++ b/test/containers/unord/unord.map/max_size.pass.cpp
@@ -18,10 +18,19 @@
 #include <unordered_map>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
         std::unordered_map<int, int> u;
         assert(u.max_size() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::unordered_map<int, int, std::hash<int>, std::equal_to<int>,
+                                    min_allocator<std::pair<const int, int>>> u;
+        assert(u.max_size() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/rehash.pass.cpp b/test/containers/unord/unord.map/rehash.pass.cpp
index 61cd4f5..c516872 100644
--- a/test/containers/unord/unord.map/rehash.pass.cpp
+++ b/test/containers/unord/unord.map/rehash.pass.cpp
@@ -19,7 +19,10 @@
 #include <string>
 #include <cassert>
 
-void test(const std::unordered_map<int, std::string>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
     assert(c.size() == 4);
     assert(c.at(1) == "one");
@@ -56,4 +59,33 @@
         assert(c.bucket_count() == 31);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 5);
+        c.rehash(3);
+        assert(c.bucket_count() == 5);
+        test(c);
+        c.max_load_factor(2);
+        c.rehash(3);
+        assert(c.bucket_count() == 3);
+        test(c);
+        c.rehash(31);
+        assert(c.bucket_count() == 31);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/reserve.pass.cpp b/test/containers/unord/unord.map/reserve.pass.cpp
index 9a8eb8b..753316f 100644
--- a/test/containers/unord/unord.map/reserve.pass.cpp
+++ b/test/containers/unord/unord.map/reserve.pass.cpp
@@ -19,7 +19,10 @@
 #include <string>
 #include <cassert>
 
-void test(const std::unordered_map<int, std::string>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
     assert(c.size() == 4);
     assert(c.at(1) == "one");
@@ -56,4 +59,33 @@
         assert(c.bucket_count() >= 16);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 5);
+        c.reserve(3);
+        assert(c.bucket_count() == 5);
+        test(c);
+        c.max_load_factor(2);
+        c.reserve(3);
+        assert(c.bucket_count() >= 2);
+        test(c);
+        c.reserve(31);
+        assert(c.bucket_count() >= 16);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/swap_member.pass.cpp b/test/containers/unord/unord.map/swap_member.pass.cpp
index 871815b..311a9a5 100644
--- a/test/containers/unord/unord.map/swap_member.pass.cpp
+++ b/test/containers/unord/unord.map/swap_member.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../test_compare.h"
 #include "../../test_hash.h"
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -386,4 +387,186 @@
         assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
         assert(c2.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.at(10) == "ten");
+        assert(c1.at(20) == "twenty");
+        assert(c1.at(30) == "thirty");
+        assert(c1.at(40) == "fourty");
+        assert(c1.at(50) == "fifty");
+        assert(c1.at(60) == "sixty");
+        assert(c1.at(70) == "seventy");
+        assert(c1.at(80) == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 5);
+        assert(c2.size() == 4);
+        assert(c2.at(1) == "one");
+        assert(c2.at(2) == "two");
+        assert(c2.at(3) == "three");
+        assert(c2.at(4) == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.at(10) == "ten");
+        assert(c1.at(20) == "twenty");
+        assert(c1.at(30) == "thirty");
+        assert(c1.at(40) == "fourty");
+        assert(c1.at(50) == "fifty");
+        assert(c1.at(60) == "sixty");
+        assert(c1.at(70) == "seventy");
+        assert(c1.at(80) == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 5);
+        assert(c2.size() == 4);
+        assert(c2.at(1) == "one");
+        assert(c2.at(2) == "two");
+        assert(c2.at(3) == "three");
+        assert(c2.at(4) == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/types.pass.cpp b/test/containers/unord/unord.map/types.pass.cpp
index da7d569..4bf4591 100644
--- a/test/containers/unord/unord.map/types.pass.cpp
+++ b/test/containers/unord/unord.map/types.pass.cpp
@@ -31,6 +31,8 @@
 #include <unordered_map>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -48,4 +50,22 @@
         static_assert((std::is_same<C::size_type, std::size_t>::value), "");
         static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<char, short, std::hash<char>, std::equal_to<char>,
+                            min_allocator<std::pair<const char, short>>> C;
+        static_assert((std::is_same<C::key_type, char>::value), "");
+        static_assert((std::is_same<C::mapped_type, short>::value), "");
+        static_assert((std::is_same<C::hasher, std::hash<C::key_type> >::value), "");
+        static_assert((std::is_same<C::key_equal, std::equal_to<C::key_type> >::value), "");
+        static_assert((std::is_same<C::allocator_type, min_allocator<C::value_type> >::value), "");
+        static_assert((std::is_same<C::value_type, std::pair<const C::key_type, C::mapped_type> >::value), "");
+        static_assert((std::is_same<C::reference, C::value_type&>::value), "");
+        static_assert((std::is_same<C::const_reference, const C::value_type&>::value), "");
+        static_assert((std::is_same<C::pointer, min_pointer<C::value_type>>::value), "");
+        static_assert((std::is_same<C::const_pointer, min_pointer<const C::value_type>>::value), "");
+        static_assert((std::is_same<C::size_type, std::size_t>::value), "");
+        static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp
index 7bb7355..b49d6bf 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/allocator.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,67 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(min_allocator<std::pair<const NotConstructible, NotConstructible> >{});
+        assert(c.bucket_count() == 0);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef NotConstructible T;
+        typedef test_allocator<std::pair<const T, T>> A;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef std::unordered_map<T, T, HF, Comp, A> C;
+        
+        A a(10);
+        C c(2, a);
+        assert(c.bucket_count() == 2);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef NotConstructible T;
+        typedef test_allocator<std::pair<const T, T>> A;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef std::unordered_map<T, T, HF, Comp, A> C;
+
+        A a(10);
+        HF hf(12);
+        C c(2, hf, a);
+        assert(c.bucket_count() == 2);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
index dda88e3..8e8f97d 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -116,4 +117,51 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<std::pair<const int, std::string> > A;
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(a, a + 2,
+            7,
+            test_hash<std::hash<int> >(2),
+            test_compare<std::equal_to<int> >(3),
+            A()
+           );
+        c = c0;
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp
index 54e41e4..86d44f2 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/assign_init.pass.cpp
@@ -22,6 +22,7 @@
 
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -58,5 +59,39 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<std::pair<const int, std::string> > A;
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c =   {
+                    P(4, "four"),
+                    P(1, "four"),
+                    P(2, "four"),
+                };
+        c =     {
+                    P(1, "one"),
+                    P(2, "two"),
+                    P(3, "three"),
+                    P(4, "four"),
+                    P(1, "four"),
+                    P(2, "four"),
+                };
+        assert(c.bucket_count() >= 5);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp
index 826ccb4..f722249 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/assign_move.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -164,5 +165,65 @@
         assert(c.max_load_factor() == 1);
         assert(c0.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<std::pair<const int, std::string> > A;
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(a, a + 2,
+            7,
+            test_hash<std::hash<int> >(2),
+            test_compare<std::equal_to<int> >(3),
+            A()
+           );
+        c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c0.size() == 0);
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::unordered_map<int, int> s1 = {{1, 1}, {2, 2}, {3, 3}};
+        std::unordered_map<int, int>::iterator i = s1.begin();
+        std::pair<const int, int> k = *i;
+        std::unordered_map<int, int> s2;
+        s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp
index 7bb294c..398f2fd 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/copy.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -106,4 +107,45 @@
         assert(c.max_load_factor() == 1);
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c = c0;
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp
index 87dc249..c7d5396 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/copy_alloc.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -65,4 +66,45 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c(c0, min_allocator<std::pair<const int, std::string> >());
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp
index 762d528..b32c260 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/default.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,25 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                  NotConstructible> >
+                                   > C;
+        C c;
+        assert(c.bucket_count() == 0);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp
index 7f426fd..ebf8e13 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp
@@ -49,12 +49,12 @@
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_default_constructible<C>::value, "");
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(!std::is_nothrow_default_constructible<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp
index e605b66..5d2e4c4 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp
@@ -46,12 +46,12 @@
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp
index 5b3fe7e..594331c 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/init.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -58,5 +59,104 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c = {
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+              };
+        assert(c.bucket_count() >= 5);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_map<int, std::string, HF, Comp, A> C;
+
+        A a(42);
+        C c ( {
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+              }, 12, a);
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == a);
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_map<int, std::string, HF, Comp, A> C;
+
+        HF hf(42);
+        A a(43);
+        C c ( {
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+              }, 12, hf, a);
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == test_hash<std::hash<int> >()));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == a);
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp
index 4aa1ea6..fd28845 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/init_size.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -60,5 +61,40 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp
index d499adc..bcc97b6 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -61,5 +62,41 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7,
+            test_hash<std::hash<int> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp
index 25c212e..5e21873 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal.pass.cpp
@@ -24,6 +24,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -63,5 +64,42 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp
index d33efee..0f5e7b5 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/init_size_hash_equal_allocator.pass.cpp
@@ -24,6 +24,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -64,5 +65,43 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
index b094330..41055c4 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -104,5 +105,95 @@
 
         assert(c0.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 0);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::unordered_map<int, int> s1 = {{1, 1}, {2, 2}, {3, 3}};
+        std::unordered_map<int, int>::iterator i = s1.begin();
+        std::pair<const int, int> k = *i;
+        std::unordered_map<int, int> s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp
index a1434a5..0f73480 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/move_alloc.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -109,5 +110,48 @@
 
         assert(c0.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<int, std::string> P;
+        typedef min_allocator<std::pair<const int, std::string>> A;
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(std::move(c0), A());
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp
index 758a786..27174b3 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp
@@ -48,12 +48,12 @@
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_move_assignable<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp
index 952c478..3a97097 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp
@@ -45,12 +45,12 @@
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp
index 0c4ccec..bc316d3 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/range.pass.cpp
@@ -26,6 +26,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -62,4 +63,108 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])));
+        assert(c.bucket_count() >= 5);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_map<int, std::string, HF, Comp, A> C;
+
+        P arr[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(arr), input_iterator<P*>(arr + sizeof(arr)/sizeof(arr[0])), 14);
+        assert(c.bucket_count() >= 14);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_map<int, std::string, HF, Comp, A> C;
+
+        P arr[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        HF hf(42);
+        A a(43);
+        C c(input_iterator<P*>(arr), input_iterator<P*>(arr + sizeof(arr)/sizeof(arr[0])), 14, hf, a);
+        assert(c.bucket_count() >= 14);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp
index 0d8b1a7..42822bc 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/range_size.pass.cpp
@@ -26,6 +26,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -64,4 +65,41 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            10
+           );
+        assert(c.bucket_count() == 11);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp
index 0d55b26..f6f294f 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash.pass.cpp
@@ -27,6 +27,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -66,4 +67,42 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp
index 0c81503..16b7f8b 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal.pass.cpp
@@ -27,6 +27,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -67,4 +68,43 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp
index c8371ce..82825ce 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/range_size_hash_equal_allocator.pass.cpp
@@ -28,6 +28,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -69,4 +70,44 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp b/test/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp
index ce19c17..7130366 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/size.fail.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,25 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c = 7;
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp
index ab2b186..81cb07d 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/size.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,25 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7);
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp
index 0d4d7a1..783189c 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/size_hash.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,27 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp
index 44fcc30..9c7f2b5 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -47,4 +48,28 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8),
+            test_compare<std::equal_to<NotConstructible> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp
index be08978..139ffad 100644
--- a/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.cnstr/size_hash_equal_allocator.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -48,4 +49,29 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8),
+            test_compare<std::equal_to<NotConstructible> >(9),
+            min_allocator<std::pair<const NotConstructible, NotConstructible> >()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.elem/at.pass.cpp b/test/containers/unord/unord.map/unord.map.elem/at.pass.cpp
index 720a7c5..c8eade2 100644
--- a/test/containers/unord/unord.map/unord.map.elem/at.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.elem/at.pass.cpp
@@ -21,6 +21,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -75,4 +76,59 @@
         }
         assert(c.size() == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.size() == 4);
+        c.at(1) = "ONE";
+        assert(c.at(1) == "ONE");
+        try
+        {
+            c.at(11) = "eleven";
+            assert(false);
+        }
+        catch (std::out_of_range&)
+        {
+        }
+        assert(c.size() == 4);
+    }
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        try
+        {
+            c.at(11);
+            assert(false);
+        }
+        catch (std::out_of_range&)
+        {
+        }
+        assert(c.size() == 4);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.elem/index.pass.cpp b/test/containers/unord/unord.map/unord.map.elem/index.pass.cpp
index 071e059..bbee80d 100644
--- a/test/containers/unord/unord.map/unord.map.elem/index.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.elem/index.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -65,4 +66,50 @@
         assert(c.at(11) == "eleven");
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.size() == 4);
+        c[1] = "ONE";
+        assert(c.at(1) == "ONE");
+        c[11] = "eleven";
+        assert(c.size() == 5);
+        assert(c.at(11) == "eleven");
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_map<MoveOnly, std::string, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
+                            min_allocator<std::pair<const MoveOnly, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.size() == 4);
+        c[1] = "ONE";
+        assert(c.at(1) == "ONE");
+        c[11] = "eleven";
+        assert(c.size() == 5);
+        assert(c.at(11) == "eleven");
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp b/test/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp
new file mode 100644
index 0000000..c319b5c
--- /dev/null
+++ b/test/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+//           class Alloc = allocator<pair<const Key, T>>>
+// class unordered_map
+
+// mapped_type& operator[](const key_type& k);
+
+// http://llvm.org/bugs/show_bug.cgi?id=16542
+
+#include <unordered_map>
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+#include <tuple>
+
+using namespace std;
+
+struct my_hash
+{
+    size_t operator()(const tuple<int,int>&) const {return 0;}
+};
+
+#endif
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    unordered_map<tuple<int,int>, size_t, my_hash> m;
+    m[make_tuple(2,3)]=7;
+#endif
+}
diff --git a/test/containers/unord/unord.map/unord.map.swap/db_swap_1.pass.cpp b/test/containers/unord/unord.map/unord.map.swap/db_swap_1.pass.cpp
new file mode 100644
index 0000000..6ab9c92
--- /dev/null
+++ b/test/containers/unord/unord.map/unord.map.swap/db_swap_1.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class Value, class Hash = hash<Key>, class Pred = equal_to<Key>,
+//           class Alloc = allocator<pair<const Key, Value>>>
+// class unordered_map
+
+// void swap(unordered_map& x, unordered_map& y);
+
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <unordered_map>
+#include <cassert>
+
+int main()
+{
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::pair<int, int> P;
+        P a1[] = {P(1, 1), P(3, 3), P(7, 7), P(9, 9), P(10, 10)};
+        P a2[] = {P(0, 0), P(2, 2), P(4, 4), P(5, 5), P(6, 6), P(8, 8), P(11, 11)};
+        std::unordered_map<int, int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::unordered_map<int, int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        std::unordered_map<int, int>::iterator i1 = c1.begin();
+        std::unordered_map<int, int>::iterator i2 = c2.begin();
+        swap(c1, c2);
+        c1.erase(i2);
+        c2.erase(i1);
+        std::unordered_map<int, int>::iterator j = i1;
+        c1.erase(i1);
+        assert(false);
+    }
+#endif
+}
diff --git a/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp
index 3786f18..579b6d5 100644
--- a/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp
@@ -48,13 +48,13 @@
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
     {
         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
diff --git a/test/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp b/test/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp
index 450fed3..224286a 100644
--- a/test/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp
+++ b/test/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -386,4 +387,186 @@
         assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
         assert(c2.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.at(10) == "ten");
+        assert(c1.at(20) == "twenty");
+        assert(c1.at(30) == "thirty");
+        assert(c1.at(40) == "fourty");
+        assert(c1.at(50) == "fifty");
+        assert(c1.at(60) == "sixty");
+        assert(c1.at(70) == "seventy");
+        assert(c1.at(80) == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 5);
+        assert(c2.size() == 4);
+        assert(c2.at(1) == "one");
+        assert(c2.at(2) == "two");
+        assert(c2.at(3) == "three");
+        assert(c2.at(4) == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.at(10) == "ten");
+        assert(c1.at(20) == "twenty");
+        assert(c1.at(30) == "thirty");
+        assert(c1.at(40) == "fourty");
+        assert(c1.at(50) == "fifty");
+        assert(c1.at(60) == "sixty");
+        assert(c1.at(70) == "seventy");
+        assert(c1.at(80) == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 5);
+        assert(c2.size() == 4);
+        assert(c2.at(1) == "one");
+        assert(c2.at(2) == "two");
+        assert(c2.at(3) == "three");
+        assert(c2.at(4) == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/clear.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/clear.pass.cpp
index c51e3d0..0e0f188 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/clear.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/clear.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -37,4 +39,23 @@
         c.clear();
         assert(c.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        c.clear();
+        assert(c.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/emplace.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/emplace.pass.cpp
index 488d2ba..a115101 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/emplace.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/emplace.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -28,7 +29,8 @@
         typedef std::unordered_map<int, Emplaceable> C;
         typedef std::pair<C::iterator, bool> R;
         C c;
-        R r = c.emplace(3);
+        R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
+                                                  std::forward_as_tuple());
         assert(r.second);
         assert(c.size() == 1);
         assert(r.first->first == 3);
@@ -47,5 +49,32 @@
         assert(r.first->first == 5);
         assert(r.first->second == Emplaceable(6, 7));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, Emplaceable, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, Emplaceable>>> C;
+        typedef std::pair<C::iterator, bool> R;
+        C c;
+        R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
+                                                  std::forward_as_tuple());
+        assert(r.second);
+        assert(c.size() == 1);
+        assert(r.first->first == 3);
+        assert(r.first->second == Emplaceable());
+
+        r = c.emplace(std::pair<const int, Emplaceable>(4, Emplaceable(5, 6)));
+        assert(r.second);
+        assert(c.size() == 2);
+        assert(r.first->first == 4);
+        assert(r.first->second == Emplaceable(5, 6));
+
+        r = c.emplace(std::piecewise_construct, std::forward_as_tuple(5),
+                                               std::forward_as_tuple(6, 7));
+        assert(r.second);
+        assert(c.size() == 3);
+        assert(r.first->first == 5);
+        assert(r.first->second == Emplaceable(6, 7));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/emplace_hint.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/emplace_hint.pass.cpp
index 463fc3b..7cd14c6 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/emplace_hint.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/emplace_hint.pass.cpp
@@ -16,10 +16,15 @@
 // template <class... Args>
 //     iterator emplace_hint(const_iterator p, Args&&... args);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -29,21 +34,60 @@
         typedef C::iterator R;
         C c;
         C::const_iterator e = c.end();
-        R r = c.emplace_hint(e, 3);
+        R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
+                                                          std::forward_as_tuple());
         assert(c.size() == 1);
         assert(r->first == 3);
         assert(r->second == Emplaceable());
 
-        r = c.emplace_hint(e, std::pair<const int, Emplaceable>(4, Emplaceable(5, 6)));
+        r = c.emplace_hint(c.end(), std::pair<const int, Emplaceable>(4, Emplaceable(5, 6)));
         assert(c.size() == 2);
         assert(r->first == 4);
         assert(r->second == Emplaceable(5, 6));
 
-        r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(5),
+        r = c.emplace_hint(c.end(), std::piecewise_construct, std::forward_as_tuple(5),
                                                        std::forward_as_tuple(6, 7));
         assert(c.size() == 3);
         assert(r->first == 5);
         assert(r->second == Emplaceable(6, 7));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, Emplaceable, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, Emplaceable>>> C;
+        typedef C::iterator R;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
+                                                          std::forward_as_tuple());
+        assert(c.size() == 1);
+        assert(r->first == 3);
+        assert(r->second == Emplaceable());
+
+        r = c.emplace_hint(c.end(), std::pair<const int, Emplaceable>(4, Emplaceable(5, 6)));
+        assert(c.size() == 2);
+        assert(r->first == 4);
+        assert(r->second == Emplaceable(5, 6));
+
+        r = c.emplace_hint(c.end(), std::piecewise_construct, std::forward_as_tuple(5),
+                                                       std::forward_as_tuple(6, 7));
+        assert(c.size() == 3);
+        assert(r->first == 5);
+        assert(r->second == Emplaceable(6, 7));
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_map<int, Emplaceable> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        R r = c.emplace_hint(c2.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(3),
+                                       std::forward_as_tuple());
+        assert(false);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_const_iter.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_const_iter.pass.cpp
index f7127d5..977581c 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/erase_const_iter.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_const_iter.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -41,4 +43,27 @@
         assert(c.at(3) == "three");
         assert(c.at(4) == "four");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::iterator j = c.erase(i);
+        assert(c.size() == 3);
+        assert(c.at(1) == "one");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db1.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db1.pass.cpp
new file mode 100644
index 0000000..60b0935
--- /dev/null
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db1.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator position) with end()
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_map<int, int> l1(a1, a1+3);
+    std::unordered_map<int, int>::const_iterator i = l1.end();
+    l1.erase(i);
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db2.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db2.pass.cpp
new file mode 100644
index 0000000..05046f5
--- /dev/null
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db2.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator position) with iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <cstdlib>
+#include <exception>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_map<int, int> l1(a1, a1+3);
+    std::unordered_map<int, int> l2(a1, a1+3);
+    std::unordered_map<int, int>::const_iterator i = l2.begin();
+    l1.erase(i);
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db1.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db1.pass.cpp
new file mode 100644
index 0000000..81a8d3d
--- /dev/null
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db1.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with first iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_map<int, int> l1(a1, a1+3);
+    std::unordered_map<int, int> l2(a1, a1+3);
+    std::unordered_map<int, int>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db2.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db2.pass.cpp
new file mode 100644
index 0000000..4b103a0
--- /dev/null
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db2.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with second iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_map<int, int> l1(a1, a1+3);
+    std::unordered_map<int, int> l2(a1, a1+3);
+    std::unordered_map<int, int>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db3.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db3.pass.cpp
new file mode 100644
index 0000000..6ef1e07
--- /dev/null
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db3.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with both iterators from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_map<int, int> l1(a1, a1+3);
+    std::unordered_map<int, int> l2(a1, a1+3);
+    std::unordered_map<int, int>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db4.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db4.pass.cpp
new file mode 100644
index 0000000..1185ddf
--- /dev/null
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db4.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with a bad range
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_map<int, int> l1(a1, a1+3);
+    std::unordered_map<int, int>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin());
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp
index cc59bb9..c2a8666 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -77,4 +79,63 @@
         assert(c.erase(3) == 0);
         assert(c.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.erase(5) == 0);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+
+        assert(c.erase(2) == 1);
+        assert(c.size() == 3);
+        assert(c.at(1) == "one");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+
+        assert(c.erase(2) == 0);
+        assert(c.size() == 3);
+        assert(c.at(1) == "one");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+
+        assert(c.erase(4) == 1);
+        assert(c.size() == 2);
+        assert(c.at(1) == "one");
+        assert(c.at(3) == "three");
+
+        assert(c.erase(4) == 0);
+        assert(c.size() == 2);
+        assert(c.at(1) == "one");
+        assert(c.at(3) == "three");
+
+        assert(c.erase(1) == 1);
+        assert(c.size() == 1);
+        assert(c.at(3) == "three");
+
+        assert(c.erase(1) == 0);
+        assert(c.size() == 1);
+        assert(c.at(3) == "three");
+
+        assert(c.erase(3) == 1);
+        assert(c.size() == 0);
+
+        assert(c.erase(3) == 0);
+        assert(c.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/erase_range.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/erase_range.pass.cpp
index b5c4383..ad915fd 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/erase_range.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/erase_range.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -56,4 +58,42 @@
         assert(c.size() == 0);
         assert(k == c.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::const_iterator j = next(i, 1);
+        C::iterator k = c.erase(i, i);
+        assert(k == i);
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+
+        k = c.erase(i, j);
+        assert(c.size() == 3);
+        assert(k == j);
+        assert(c.at(1) == "one");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+
+        k = c.erase(c.cbegin(), c.cend());
+        assert(k == c.cend());
+        assert(c.size() == 0);
+        assert(k == c.end());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/insert_const_lvalue.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/insert_const_lvalue.pass.cpp
index d9ab415..8bf66ca 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/insert_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/insert_const_lvalue.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -49,4 +51,36 @@
         assert(r.first->first == 5.5);
         assert(r.first->second == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef std::pair<C::iterator, bool> R;
+        typedef C::value_type P;
+        C c;
+        R r = c.insert(P(3.5, 3));
+        assert(r.second);
+        assert(c.size() == 1);
+        assert(r.first->first == 3.5);
+        assert(r.first->second == 3);
+
+        r = c.insert(P(3.5, 4));
+        assert(!r.second);
+        assert(c.size() == 1);
+        assert(r.first->first == 3.5);
+        assert(r.first->second == 3);
+
+        r = c.insert(P(4.5, 4));
+        assert(r.second);
+        assert(c.size() == 2);
+        assert(r.first->first == 4.5);
+        assert(r.first->second == 4);
+
+        r = c.insert(P(5.5, 4));
+        assert(r.second);
+        assert(c.size() == 3);
+        assert(r.first->first == 5.5);
+        assert(r.first->second == 4);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_const_lvalue.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_const_lvalue.pass.cpp
index 0d2ffe3..2e4230a 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_const_lvalue.pass.cpp
@@ -15,9 +15,15 @@
 
 // iterator insert(const_iterator p, const value_type& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -31,19 +37,61 @@
         assert(r->first == 3.5);
         assert(r->second == 3);
 
-        r = c.insert(e, P(3.5, 4));
+        r = c.insert(c.end(), P(3.5, 4));
         assert(c.size() == 1);
         assert(r->first == 3.5);
         assert(r->second == 3);
 
-        r = c.insert(e, P(4.5, 4));
+        r = c.insert(c.end(), P(4.5, 4));
         assert(c.size() == 2);
         assert(r->first == 4.5);
         assert(r->second == 4);
 
-        r = c.insert(e, P(5.5, 4));
+        r = c.insert(c.end(), P(5.5, 4));
         assert(c.size() == 3);
         assert(r->first == 5.5);
         assert(r->second == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(c.end(), P(3.5, 4));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(c.end(), P(4.5, 4));
+        assert(c.size() == 2);
+        assert(r->first == 4.5);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(5.5, 4));
+        assert(c.size() == 3);
+        assert(r->first == 5.5);
+        assert(r->second == 4);
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_map<double, int> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        P v(3.5, 3);
+        R r = c.insert(e, v);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_rvalue.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_rvalue.pass.cpp
index 6fc6e8e..5a4fd23 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_rvalue.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/insert_hint_rvalue.pass.cpp
@@ -17,10 +17,15 @@
 //           class = typename enable_if<is_convertible<P, value_type>::value>::type>
 //     iterator insert(const_iterator p, P&& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -35,17 +40,17 @@
         assert(r->first == 3.5);
         assert(r->second == 3);
 
-        r = c.insert(e, P(3.5, 4));
+        r = c.insert(c.end(), P(3.5, 4));
         assert(c.size() == 1);
         assert(r->first == 3.5);
         assert(r->second == 3);
 
-        r = c.insert(e, P(4.5, 4));
+        r = c.insert(c.end(), P(4.5, 4));
         assert(c.size() == 2);
         assert(r->first == 4.5);
         assert(r->second == 4);
 
-        r = c.insert(e, P(5.5, 4));
+        r = c.insert(c.end(), P(5.5, 4));
         assert(c.size() == 3);
         assert(r->first == 5.5);
         assert(r->second == 4);
@@ -62,20 +67,90 @@
         assert(r->first == 3);
         assert(r->second == 3);
 
-        r = c.insert(e, P(3, 4));
+        r = c.insert(c.end(), P(3, 4));
         assert(c.size() == 1);
         assert(r->first == 3);
         assert(r->second == 3);
 
-        r = c.insert(e, P(4, 4));
+        r = c.insert(c.end(), P(4, 4));
         assert(c.size() == 2);
         assert(r->first == 4);
         assert(r->second == 4);
 
-        r = c.insert(e, P(5, 4));
+        r = c.insert(c.end(), P(5, 4));
         assert(c.size() == 3);
         assert(r->first == 5);
         assert(r->second == 4);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef C::iterator R;
+        typedef std::pair<double, short> P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(c.end(), P(3.5, 4));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(c.end(), P(4.5, 4));
+        assert(c.size() == 2);
+        assert(r->first == 4.5);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(5.5, 4));
+        assert(c.size() == 3);
+        assert(r->first == 5.5);
+        assert(r->second == 4);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
+                            min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+        typedef C::iterator R;
+        typedef std::pair<MoveOnly, MoveOnly> P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3);
+        assert(r->second == 3);
+
+        r = c.insert(c.end(), P(3, 4));
+        assert(c.size() == 1);
+        assert(r->first == 3);
+        assert(r->second == 3);
+
+        r = c.insert(c.end(), P(4, 4));
+        assert(c.size() == 2);
+        assert(r->first == 4);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(5, 4));
+        assert(c.size() == 3);
+        assert(r->first == 5);
+        assert(r->second == 4);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_map<double, int> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        R r = c.insert(e, P(3.5, 3));
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/insert_init.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/insert_init.pass.cpp
index 532c7cb..b667c7e 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/insert_init.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/insert_init.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,5 +45,28 @@
         assert(c.at(3) == "three");
         assert(c.at(4) == "four");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        C c;
+        c.insert(
+                    {
+                        P(1, "one"),
+                        P(2, "two"),
+                        P(3, "three"),
+                        P(4, "four"),
+                        P(1, "four"),
+                        P(2, "four"),
+                    }
+                );
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/insert_range.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/insert_range.pass.cpp
index eda189a..68cb25c 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/insert_range.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/insert_range.pass.cpp
@@ -21,6 +21,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,27 @@
         assert(c.at(3) == "three");
         assert(c.at(4) == "four");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c;
+        c.insert(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])));
+        assert(c.size() == 4);
+        assert(c.at(1) == "one");
+        assert(c.at(2) == "two");
+        assert(c.at(3) == "three");
+        assert(c.at(4) == "four");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.map/unorder.map.modifiers/insert_rvalue.pass.cpp b/test/containers/unord/unord.map/unorder.map.modifiers/insert_rvalue.pass.cpp
index 3b156ff..3e050e9 100644
--- a/test/containers/unord/unord.map/unorder.map.modifiers/insert_rvalue.pass.cpp
+++ b/test/containers/unord/unord.map/unorder.map.modifiers/insert_rvalue.pass.cpp
@@ -21,6 +21,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -84,4 +85,68 @@
         assert(r.first->second == 4);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef std::pair<C::iterator, bool> R;
+        typedef std::pair<double, short> P;
+        C c;
+        R r = c.insert(P(3.5, 3));
+        assert(r.second);
+        assert(c.size() == 1);
+        assert(r.first->first == 3.5);
+        assert(r.first->second == 3);
+
+        r = c.insert(P(3.5, 4));
+        assert(!r.second);
+        assert(c.size() == 1);
+        assert(r.first->first == 3.5);
+        assert(r.first->second == 3);
+
+        r = c.insert(P(4.5, 4));
+        assert(r.second);
+        assert(c.size() == 2);
+        assert(r.first->first == 4.5);
+        assert(r.first->second == 4);
+
+        r = c.insert(P(5.5, 4));
+        assert(r.second);
+        assert(c.size() == 3);
+        assert(r.first->first == 5.5);
+        assert(r.first->second == 4);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
+                            min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+        typedef std::pair<C::iterator, bool> R;
+        typedef std::pair<MoveOnly, MoveOnly> P;
+        C c;
+        R r = c.insert(P(3, 3));
+        assert(r.second);
+        assert(c.size() == 1);
+        assert(r.first->first == 3);
+        assert(r.first->second == 3);
+
+        r = c.insert(P(3, 4));
+        assert(!r.second);
+        assert(c.size() == 1);
+        assert(r.first->first == 3);
+        assert(r.first->second == 3);
+
+        r = c.insert(P(4, 4));
+        assert(r.second);
+        assert(c.size() == 2);
+        assert(r.first->first == 4);
+        assert(r.first->second == 4);
+
+        r = c.insert(P(5, 4));
+        assert(r.second);
+        assert(c.size() == 3);
+        assert(r.first->first == 5);
+        assert(r.first->second == 4);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/bucket.pass.cpp b/test/containers/unord/unord.multimap/bucket.pass.cpp
index b1f9d36..46f7334 100644
--- a/test/containers/unord/unord.multimap/bucket.pass.cpp
+++ b/test/containers/unord/unord.multimap/bucket.pass.cpp
@@ -15,10 +15,16 @@
 
 // size_type bucket(const key_type& __k) const;
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -39,4 +45,33 @@
         for (size_t i = 0; i < 13; ++i)
             assert(c.bucket(i) == i % bc);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(std::begin(a), std::end(a));
+        size_t bc = c.bucket_count();
+        assert(bc >= 7);
+        for (size_t i = 0; i < 13; ++i)
+            assert(c.bucket(i) == i % bc);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multimap<int, std::string> C;
+        C c;
+        C::size_type i = c.bucket(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/bucket_size.pass.cpp b/test/containers/unord/unord.multimap/bucket_size.pass.cpp
index d8f784a..1528a34 100644
--- a/test/containers/unord/unord.multimap/bucket_size.pass.cpp
+++ b/test/containers/unord/unord.multimap/bucket_size.pass.cpp
@@ -15,10 +15,16 @@
 
 // size_type bucket_size(size_type n) const
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -43,4 +49,37 @@
         assert(c.bucket_size(5) == 0);
         assert(c.bucket_size(6) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.bucket_count() >= 7);
+        assert(c.bucket_size(0) == 0);
+        assert(c.bucket_size(1) == 2);
+        assert(c.bucket_size(2) == 2);
+        assert(c.bucket_size(3) == 1);
+        assert(c.bucket_size(4) == 1);
+        assert(c.bucket_size(5) == 0);
+        assert(c.bucket_size(6) == 0);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multimap<int, std::string> C;
+        C c;
+        C::size_type i = c.bucket_size(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/count.pass.cpp b/test/containers/unord/unord.multimap/count.pass.cpp
index 3bfac4d..a1d0432 100644
--- a/test/containers/unord/unord.multimap/count.pass.cpp
+++ b/test/containers/unord/unord.multimap/count.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,28 @@
         assert(c.count(50) == 3);
         assert(c.count(5) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(50, "fiftyA"),
+            P(50, "fiftyB"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.count(30) == 1);
+        assert(c.count(50) == 3);
+        assert(c.count(5) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/db_iterators_7.pass.cpp b/test/containers/unord/unord.multimap/db_iterators_7.pass.cpp
new file mode 100644
index 0000000..e7f06fe
--- /dev/null
+++ b/test/containers/unord/unord.multimap/db_iterators_7.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_multimap<int, std::string> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/db_iterators_8.pass.cpp b/test/containers/unord/unord.multimap/db_iterators_8.pass.cpp
new file mode 100644
index 0000000..2f7a0d9
--- /dev/null
+++ b/test/containers/unord/unord.multimap/db_iterators_8.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_multimap<int, std::string> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.end();
+    C::value_type j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c;
+    c.insert(std::make_pair(1, "one"));
+    C::iterator i = c.end();
+    C::value_type j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp b/test/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp
new file mode 100644
index 0000000..330374f
--- /dev/null
+++ b/test/containers/unord/unord.multimap/db_local_iterators_7.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Increment local_iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_multimap<int, std::string> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#endif
+
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp b/test/containers/unord/unord.multimap/db_local_iterators_8.pass.cpp
new file mode 100644
index 0000000..9185147
--- /dev/null
+++ b/test/containers/unord/unord.multimap/db_local_iterators_8.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::unordered_multimap<int, std::string> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    C::value_type j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                        min_allocator<std::pair<const int, std::string>>> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    C::value_type j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/eq.pass.cpp b/test/containers/unord/unord.multimap/eq.pass.cpp
index 6461cae..b069ded 100644
--- a/test/containers/unord/unord.multimap/eq.pass.cpp
+++ b/test/containers/unord/unord.multimap/eq.pass.cpp
@@ -23,6 +23,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -98,4 +100,82 @@
         assert( (c1 == c2));
         assert(!(c1 != c2));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(20, "twenty 2"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(50, "fifty 2"),
+            P(50, "fifty 3"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2;
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(20, "twenty 2"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(50, "fifty 2"),
+            P(50, "fifty 3"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2 = c1;
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(20, "twenty 2"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(50, "fifty 2"),
+            P(50, "fifty 3"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(std::begin(a), std::end(a));
+        C c2 = c1;
+        c2.rehash(30);
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+        c2.insert(P(90, "ninety"));
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+        c1.insert(P(90, "ninety"));
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/equal_range_const.pass.cpp b/test/containers/unord/unord.multimap/equal_range_const.pass.cpp
index 394ebb8..bc0c703 100644
--- a/test/containers/unord/unord.multimap/equal_range_const.pass.cpp
+++ b/test/containers/unord/unord.multimap/equal_range_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -55,4 +57,41 @@
         assert(r.first->first == 50);
         assert(r.first->second == "fiftyB");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::const_iterator I;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(50, "fiftyA"),
+            P(50, "fiftyB"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(r.first->first == 30);
+        assert(r.first->second == "thirty");
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+        r = c.equal_range(50);
+        assert(r.first->first == 50);
+        assert(r.first->second == "fifty");
+        ++r.first;
+        assert(r.first->first == 50);
+        assert(r.first->second == "fiftyA");
+        ++r.first;
+        assert(r.first->first == 50);
+        assert(r.first->second == "fiftyB");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/equal_range_non_const.pass.cpp b/test/containers/unord/unord.multimap/equal_range_non_const.pass.cpp
index 3fe83fa..8b78f70 100644
--- a/test/containers/unord/unord.multimap/equal_range_non_const.pass.cpp
+++ b/test/containers/unord/unord.multimap/equal_range_non_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -55,4 +57,41 @@
         assert(r.first->first == 50);
         assert(r.first->second == "fiftyB");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::iterator I;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(50, "fiftyA"),
+            P(50, "fiftyB"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(r.first->first == 30);
+        assert(r.first->second == "thirty");
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+        r = c.equal_range(50);
+        assert(r.first->first == 50);
+        assert(r.first->second == "fifty");
+        ++r.first;
+        assert(r.first->first == 50);
+        assert(r.first->second == "fiftyA");
+        ++r.first;
+        assert(r.first->first == 50);
+        assert(r.first->second == "fiftyB");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/find_const.pass.cpp b/test/containers/unord/unord.multimap/find_const.pass.cpp
index 8700dcf..b967a51 100644
--- a/test/containers/unord/unord.multimap/find_const.pass.cpp
+++ b/test/containers/unord/unord.multimap/find_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,28 @@
         i = c.find(5);
         assert(i == c.cend());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        C::const_iterator i = c.find(30);
+        assert(i->first == 30);
+        assert(i->second == "thirty");
+        i = c.find(5);
+        assert(i == c.cend());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/find_non_const.pass.cpp b/test/containers/unord/unord.multimap/find_non_const.pass.cpp
index cb3aab9..8da85ba 100644
--- a/test/containers/unord/unord.multimap/find_non_const.pass.cpp
+++ b/test/containers/unord/unord.multimap/find_non_const.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +44,28 @@
         i = c.find(5);
         assert(i == c.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c(std::begin(a), std::end(a));
+        C::iterator i = c.find(30);
+        assert(i->first == 30);
+        assert(i->second == "thirty");
+        i = c.find(5);
+        assert(i == c.end());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/iterators.pass.cpp b/test/containers/unord/unord.multimap/iterators.pass.cpp
index 573fc63..9abb196 100644
--- a/test/containers/unord/unord.multimap/iterators.pass.cpp
+++ b/test/containers/unord/unord.multimap/iterators.pass.cpp
@@ -24,6 +24,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -67,4 +69,63 @@
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
         C::const_iterator i;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::iterator i;
+        i = c.begin();
+        i->second = "ONE";
+        assert(i->second == "ONE");
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::const_iterator i;
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::unordered_multimap<int,double> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/load_factor.pass.cpp b/test/containers/unord/unord.multimap/load_factor.pass.cpp
index 250509d..29cf689 100644
--- a/test/containers/unord/unord.multimap/load_factor.pass.cpp
+++ b/test/containers/unord/unord.multimap/load_factor.pass.cpp
@@ -20,6 +20,8 @@
 #include <cassert>
 #include <cfloat>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -45,4 +47,31 @@
         const C c;
         assert(c.load_factor() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        const C c;
+        assert(c.load_factor() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/local_iterators.pass.cpp b/test/containers/unord/unord.multimap/local_iterators.pass.cpp
index 7a292f9..695953d 100644
--- a/test/containers/unord/unord.multimap/local_iterators.pass.cpp
+++ b/test/containers/unord/unord.multimap/local_iterators.pass.cpp
@@ -24,6 +24,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -282,4 +284,266 @@
         j = c.cend(b);
         assert(std::distance(i, j) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+
+        b = c.bucket(5);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+
+        b = c.bucket(5);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+
+        b = c.bucket(5);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 3);
+        assert(i->second == "three");
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(i->first == 4);
+        assert(i->second == "four");
+
+        b = c.bucket(5);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/max_bucket_count.pass.cpp b/test/containers/unord/unord.multimap/max_bucket_count.pass.cpp
index e512eb8..0504db0 100644
--- a/test/containers/unord/unord.multimap/max_bucket_count.pass.cpp
+++ b/test/containers/unord/unord.multimap/max_bucket_count.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -28,4 +30,14 @@
         const C c;
         assert(c.max_bucket_count() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef C::const_iterator I;
+        typedef std::pair<int, std::string> P;
+        const C c;
+        assert(c.max_bucket_count() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/max_load_factor.pass.cpp b/test/containers/unord/unord.multimap/max_load_factor.pass.cpp
index 1d30084..0a20845 100644
--- a/test/containers/unord/unord.multimap/max_load_factor.pass.cpp
+++ b/test/containers/unord/unord.multimap/max_load_factor.pass.cpp
@@ -16,10 +16,16 @@
 // float max_load_factor() const;
 // void max_load_factor(float mlf);
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -36,4 +42,30 @@
         c.max_load_factor(2.5);
         assert(c.max_load_factor() == 2.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        const C c;
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        C c;
+        assert(c.max_load_factor() == 1);
+        c.max_load_factor(2.5);
+        assert(c.max_load_factor() == 2.5);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multimap<int, std::string> C;
+        C c;
+        c.max_load_factor(0);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/max_size.pass.cpp b/test/containers/unord/unord.multimap/max_size.pass.cpp
index b9e72a8..ac247d7 100644
--- a/test/containers/unord/unord.multimap/max_size.pass.cpp
+++ b/test/containers/unord/unord.multimap/max_size.pass.cpp
@@ -18,10 +18,19 @@
 #include <unordered_map>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
         std::unordered_multimap<int, int> u;
         assert(u.max_size() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::unordered_multimap<int, int, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, int>>> u;
+        assert(u.max_size() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/rehash.pass.cpp b/test/containers/unord/unord.multimap/rehash.pass.cpp
index 4276436..e722c04 100644
--- a/test/containers/unord/unord.multimap/rehash.pass.cpp
+++ b/test/containers/unord/unord.multimap/rehash.pass.cpp
@@ -20,14 +20,16 @@
 #include <cassert>
 #include <cfloat>
 
-void test(const std::unordered_multimap<int, std::string>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
-    typedef std::unordered_multimap<int, std::string> C;
     assert(c.size() == 6);
-    typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+    typedef std::pair<typename C::const_iterator, typename C::const_iterator> Eq;
     Eq eq = c.equal_range(1);
     assert(std::distance(eq.first, eq.second) == 2);
-    C::const_iterator i = eq.first;
+    typename C::const_iterator i = eq.first;
     assert(i->first == 1);
     assert(i->second == "one");
     ++i;
@@ -85,4 +87,33 @@
         assert(c.bucket_count() == 31);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 7);
+        c.rehash(3);
+        assert(c.bucket_count() == 7);
+        test(c);
+        c.max_load_factor(2);
+        c.rehash(3);
+        assert(c.bucket_count() == 3);
+        test(c);
+        c.rehash(31);
+        assert(c.bucket_count() == 31);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/reserve.pass.cpp b/test/containers/unord/unord.multimap/reserve.pass.cpp
index 3f652ad..f13ae73 100644
--- a/test/containers/unord/unord.multimap/reserve.pass.cpp
+++ b/test/containers/unord/unord.multimap/reserve.pass.cpp
@@ -19,7 +19,10 @@
 #include <string>
 #include <cassert>
 
-void test(const std::unordered_multimap<int, std::string>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
     assert(c.size() == 6);
     assert(c.find(1)->second == "one");
@@ -58,4 +61,33 @@
         assert(c.bucket_count() >= 16);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 7);
+        c.reserve(3);
+        assert(c.bucket_count() == 7);
+        test(c);
+        c.max_load_factor(2);
+        c.reserve(3);
+        assert(c.bucket_count() == 3);
+        test(c);
+        c.reserve(31);
+        assert(c.bucket_count() >= 16);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/scary.pass.cpp b/test/containers/unord/unord.multimap/scary.pass.cpp
new file mode 100644
index 0000000..e619a7a
--- /dev/null
+++ b/test/containers/unord/unord.multimap/scary.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// class unordered_map class unordered_multimap
+
+// Extension:  SCARY/N2913 iterator compatibility between unordered_map and unordered_multimap
+
+#include <unordered_map>
+
+int main()
+{
+    typedef std::unordered_map<int, int> M1;
+    typedef std::unordered_multimap<int, int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}
diff --git a/test/containers/unord/unord.multimap/swap_member.pass.cpp b/test/containers/unord/unord.multimap/swap_member.pass.cpp
index 2388e52..41b34dd 100644
--- a/test/containers/unord/unord.multimap/swap_member.pass.cpp
+++ b/test/containers/unord/unord.multimap/swap_member.pass.cpp
@@ -23,6 +23,8 @@
 #include "../../test_hash.h"
 #include "../../test_allocator.h"
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -394,4 +396,190 @@
         assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
         assert(c2.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.find(10)->second == "ten");
+        assert(c1.find(20)->second == "twenty");
+        assert(c1.find(30)->second == "thirty");
+        assert(c1.find(40)->second == "fourty");
+        assert(c1.find(50)->second == "fifty");
+        assert(c1.find(60)->second == "sixty");
+        assert(c1.find(70)->second == "seventy");
+        assert(c1.find(80)->second == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.find(1)->second == "one");
+        assert(next(c2.find(1))->second == "four");
+        assert(c2.find(2)->second == "two");
+        assert(next(c2.find(2))->second == "four");
+        assert(c2.find(3)->second == "three");
+        assert(c2.find(4)->second == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.find(10)->second == "ten");
+        assert(c1.find(20)->second == "twenty");
+        assert(c1.find(30)->second == "thirty");
+        assert(c1.find(40)->second == "fourty");
+        assert(c1.find(50)->second == "fifty");
+        assert(c1.find(60)->second == "sixty");
+        assert(c1.find(70)->second == "seventy");
+        assert(c1.find(80)->second == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.find(1)->second == "one");
+        assert(next(c2.find(1))->second == "four");
+        assert(c2.find(2)->second == "two");
+        assert(next(c2.find(2))->second == "four");
+        assert(c2.find(3)->second == "three");
+        assert(c2.find(4)->second == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/types.pass.cpp b/test/containers/unord/unord.multimap/types.pass.cpp
index 13cd3d7..369063c 100644
--- a/test/containers/unord/unord.multimap/types.pass.cpp
+++ b/test/containers/unord/unord.multimap/types.pass.cpp
@@ -31,6 +31,8 @@
 #include <unordered_map>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -48,4 +50,22 @@
         static_assert((std::is_same<C::size_type, std::size_t>::value), "");
         static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<char, short, std::hash<char>, std::equal_to<char>,
+                            min_allocator<std::pair<const char, short>>> C;
+        static_assert((std::is_same<C::key_type, char>::value), "");
+        static_assert((std::is_same<C::mapped_type, short>::value), "");
+        static_assert((std::is_same<C::hasher, std::hash<C::key_type> >::value), "");
+        static_assert((std::is_same<C::key_equal, std::equal_to<C::key_type> >::value), "");
+        static_assert((std::is_same<C::allocator_type, min_allocator<C::value_type> >::value), "");
+        static_assert((std::is_same<C::value_type, std::pair<const C::key_type, C::mapped_type> >::value), "");
+        static_assert((std::is_same<C::reference, C::value_type&>::value), "");
+        static_assert((std::is_same<C::const_reference, const C::value_type&>::value), "");
+        static_assert((std::is_same<C::pointer, min_pointer<C::value_type>>::value), "");
+        static_assert((std::is_same<C::const_pointer, min_pointer<const C::value_type>>::value), "");
+        static_assert((std::is_same<C::size_type, std::size_t>::value), "");
+        static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp
index bc3a2fe..dbcdca4 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/allocator.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,67 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                  NotConstructible> >
+                                   > C;
+        C c(min_allocator<std::pair<const NotConstructible, NotConstructible> >{});
+        assert(c.bucket_count() == 0);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef NotConstructible T;
+        typedef test_allocator<std::pair<const T, T>> A;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef std::unordered_multimap<T, T, HF, Comp, A> C;
+        
+        A a(10);
+        C c(2, a);
+        assert(c.bucket_count() == 2);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef NotConstructible T;
+        typedef test_allocator<std::pair<const T, T>> A;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef std::unordered_multimap<T, T, HF, Comp, A> C;
+
+        A a(10);
+        HF hf(12);
+        C c(2, hf, a);
+        assert(c.bucket_count() == 2);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
index 54d42dc..5c074ec 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -144,4 +145,65 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<std::pair<const int, std::string> > A;
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(a, a + 2,
+            7,
+            test_hash<std::hash<int> >(2),
+            test_compare<std::equal_to<int> >(3),
+            A()
+           );
+        c = c0;
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+        ++i;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        ++i;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp
index a808708..a48f2ea 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_init.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -83,5 +84,63 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<std::pair<const int, std::string> > A;
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c =   {
+                    P(4, "four"),
+                    P(1, "four"),
+                    P(2, "four"),
+                };
+        c =     {
+                    P(1, "one"),
+                    P(2, "two"),
+                    P(3, "three"),
+                    P(4, "four"),
+                    P(1, "four"),
+                    P(2, "four"),
+                };
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp
index f01b6fd..8c7bc76 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_move.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -222,5 +223,84 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<std::pair<const int, std::string> > A;
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(a, a + 2,
+            7,
+            test_hash<std::hash<int> >(2),
+            test_compare<std::equal_to<int> >(3),
+            A()
+           );
+        c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::unordered_multimap<int, int> s1 = {{1, 1}, {2, 2}, {3, 3}};
+        std::unordered_multimap<int, int>::iterator i = s1.begin();
+        std::pair<const int, int> k = *i;
+        std::unordered_multimap<int, int> s2;
+        s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp
index 9dc9014..d46ba1c 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -134,4 +135,59 @@
         assert(c.max_load_factor() == 1);
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c = c0;
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+        ++i;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        ++i;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp
index 4160a9f..0e0d864 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/copy_alloc.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -79,4 +80,59 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c(c0, min_allocator<std::pair<const int, std::string> >());
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+        ++i;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        ++i;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp
index b40d43d..f450455 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,25 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c;
+        assert(c.bucket_count() == 0);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp
index cbf7a0d..cc8bb72 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp
@@ -49,12 +49,12 @@
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_default_constructible<C>::value, "");
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(!std::is_nothrow_default_constructible<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp
index 2833f7e..f6c8551 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp
@@ -46,12 +46,12 @@
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_destructible<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp
index a8c9e6b..bcde666 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -80,5 +81,174 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c = {
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+              };
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_multimap<int, std::string, HF, Comp, A> C;
+
+        A a(42);
+        C c ({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+              }, 12, a );
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+    }
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_multimap<int, std::string, HF, Comp, A> C;
+
+        HF hf(42);
+        A a(43);
+        C c ({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+              }, 12, hf, a );
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+    }
+#endif
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp
index a4a265a..7cb2927 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -82,5 +83,62 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp
index 21155e6..7a2faaa 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -83,5 +84,63 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7,
+            test_hash<std::hash<int> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp
index 79936ff..73c0ec2 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal.pass.cpp
@@ -24,6 +24,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -85,5 +86,64 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp
index 53c7090..bc59d64 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_equal_allocator.pass.cpp
@@ -24,6 +24,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -86,5 +87,65 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >(10)));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        C c({
+                P(1, "one"),
+                P(2, "two"),
+                P(3, "three"),
+                P(4, "four"),
+                P(1, "four"),
+                P(2, "four"),
+            },
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp
index 5ebb217..b4983ea 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -126,5 +127,117 @@
 
         assert(c0.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 0);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const int, std::string> >()));
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        C c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+
+        assert(c0.empty());
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::unordered_multimap<int, int> s1 = {{1, 1}, {2, 2}, {3, 3}};
+        std::unordered_multimap<int, int>::iterator i = s1.begin();
+        std::pair<const int, int> k = *i;
+        std::unordered_multimap<int, int> s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp
index e40dc8b..6f0cba8 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_alloc.pass.cpp
@@ -25,6 +25,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -157,5 +158,71 @@
 
         assert(c0.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::pair<int, std::string> P;
+        typedef min_allocator<std::pair<const int, std::string>> A;
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(std::move(c0), A());
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+
+        assert(c0.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp
index d53c5cd..ee69b33 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp
@@ -48,12 +48,12 @@
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(!std::is_nothrow_move_assignable<C>::value, "");
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_move_assignable<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp
index b6e7c4d..7eb5f32 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp
@@ -45,12 +45,12 @@
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         static_assert(std::is_nothrow_move_constructible<C>::value, "");
     }
     {
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp
index 5894e63..a431481 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range.pass.cpp
@@ -26,6 +26,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -84,4 +85,179 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])));
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_multimap<int, std::string, HF, Comp, A> C;
+
+        P arr[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+         A a(42);
+       C c(input_iterator<P*>(arr), input_iterator<P*>(arr + sizeof(arr)/sizeof(arr[0])), 14, a);
+        assert(c.bucket_count() >= 14);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+    }
+    {
+        typedef std::pair<int, std::string> P;
+        typedef test_allocator<std::pair<const int, std::string>> A;
+        typedef test_hash<std::hash<int>> HF;
+        typedef test_compare<std::equal_to<int>> Comp;
+        typedef std::unordered_multimap<int, std::string, HF, Comp, A> C;
+
+        P arr[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        A a(42);
+        HF hf (43);
+        C c(input_iterator<P*>(arr), input_iterator<P*>(arr + sizeof(arr)/sizeof(arr[0])), 12, hf, a );
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp
index c02aa53..53a50de 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size.pass.cpp
@@ -26,6 +26,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -86,4 +87,63 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            10
+           );
+        assert(c.bucket_count() == 11);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp
index c3ce618..02cfb2f 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash.pass.cpp
@@ -27,6 +27,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -88,4 +89,64 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >());
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp
index a13eba0..e4fdfd3 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal.pass.cpp
@@ -27,6 +27,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -89,4 +90,65 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >()));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp
index 402ef6b..640de35 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/range_size_hash_equal_allocator.pass.cpp
@@ -28,6 +28,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -91,4 +92,66 @@
         assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
         assert((c.get_allocator() == test_allocator<std::pair<const int, std::string> >(10)));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<std::pair<const int, std::string> >
+                                   > C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<std::pair<const int, std::string> >()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator i = eq.first;
+        assert(i->first == 1);
+        assert(i->second == "one");
+        ++i;
+        assert(i->first == 1);
+        assert(i->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        i = eq.first;
+        assert(i->first == 2);
+        assert(i->second == "two");
+        ++i;
+        assert(i->first == 2);
+        assert(i->second == "four");
+
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 3);
+        assert(i->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        i = eq.first;
+        assert(i->first == 4);
+        assert(i->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert((c.get_allocator() == min_allocator<std::pair<const int, std::string> >()));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp
index f9b7eb7..95ba70b 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.fail.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,25 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c = 7;
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp
index d16957c..d9fac2f 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,25 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7);
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp
index afa2551..d691dd9 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,27 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp
index 5a3c262..9f90275 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -47,4 +48,28 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8),
+            test_compare<std::equal_to<NotConstructible> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp
index 6394ad4..23fae57 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_equal_allocator.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -48,4 +49,29 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<NotConstructible, NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<std::pair<const NotConstructible,
+                                                                 NotConstructible> >
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8),
+            test_compare<std::equal_to<NotConstructible> >(9),
+            min_allocator<std::pair<const NotConstructible, NotConstructible> >()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9));
+        assert(c.get_allocator() ==
+               (min_allocator<std::pair<const NotConstructible, NotConstructible> >()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp
index e2071fb..a731f5b 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/clear.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -37,4 +39,23 @@
         c.clear();
         assert(c.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        c.clear();
+        assert(c.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp
index f05edd8..80453b1 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -28,7 +29,8 @@
         typedef std::unordered_multimap<int, Emplaceable> C;
         typedef C::iterator R;
         C c;
-        R r = c.emplace(3);
+        R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
+                                                  std::forward_as_tuple());
         assert(c.size() == 1);
         assert(r->first == 3);
         assert(r->second == Emplaceable());
@@ -44,5 +46,29 @@
         assert(r->first == 5);
         assert(r->second == Emplaceable(6, 7));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, Emplaceable, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, Emplaceable>>> C;
+        typedef C::iterator R;
+        C c;
+        R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
+                                                  std::forward_as_tuple());
+        assert(c.size() == 1);
+        assert(r->first == 3);
+        assert(r->second == Emplaceable());
+
+        r = c.emplace(std::pair<const int, Emplaceable>(4, Emplaceable(5, 6)));
+        assert(c.size() == 2);
+        assert(r->first == 4);
+        assert(r->second == Emplaceable(5, 6));
+
+        r = c.emplace(std::piecewise_construct, std::forward_as_tuple(5),
+                                                std::forward_as_tuple(6, 7));
+        assert(c.size() == 3);
+        assert(r->first == 5);
+        assert(r->second == Emplaceable(6, 7));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp
index 302451f..13776de 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp
@@ -16,10 +16,15 @@
 // template <class... Args>
 //     iterator emplace_hint(const_iterator p, Args&&... args);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <cassert>
 
 #include "../../../Emplaceable.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -29,12 +34,13 @@
         typedef C::iterator R;
         C c;
         C::const_iterator e = c.end();
-        R r = c.emplace_hint(e, 3);
+        R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
+                                                          std::forward_as_tuple());
         assert(c.size() == 1);
         assert(r->first == 3);
         assert(r->second == Emplaceable());
 
-        r = c.emplace_hint(e, std::pair<const int, Emplaceable>(3, Emplaceable(5, 6)));
+        r = c.emplace_hint(c.end(), std::pair<const int, Emplaceable>(3, Emplaceable(5, 6)));
         assert(c.size() == 2);
         assert(r->first == 3);
         assert(r->second == Emplaceable(5, 6));
@@ -53,5 +59,51 @@
         assert(r->first == 3);
         assert(r->second == Emplaceable(5, 6));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, Emplaceable, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, Emplaceable>>> C;
+        typedef C::iterator R;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
+                                                          std::forward_as_tuple());
+        assert(c.size() == 1);
+        assert(r->first == 3);
+        assert(r->second == Emplaceable());
+
+        r = c.emplace_hint(c.end(), std::pair<const int, Emplaceable>(3, Emplaceable(5, 6)));
+        assert(c.size() == 2);
+        assert(r->first == 3);
+        assert(r->second == Emplaceable(5, 6));
+        assert(r == next(c.begin()));
+
+        r = c.emplace_hint(r, std::piecewise_construct, std::forward_as_tuple(3),
+                                                        std::forward_as_tuple(6, 7));
+        assert(c.size() == 3);
+        assert(r->first == 3);
+        assert(r->second == Emplaceable(6, 7));
+        assert(r == next(c.begin()));
+        r = c.begin();
+        assert(r->first == 3);
+        assert(r->second == Emplaceable());
+        r = next(r, 2);
+        assert(r->first == 3);
+        assert(r->second == Emplaceable(5, 6));
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_multimap<int, Emplaceable> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        R r = c.emplace_hint(c2.end(), std::piecewise_construct,
+                                       std::forward_as_tuple(3),
+                                       std::forward_as_tuple());
+        assert(false);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp
index b1df0f5..2b1d4d2 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -65,4 +67,51 @@
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::iterator j = c.erase(i);
+
+        assert(c.size() == 5);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 2);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db1.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db1.pass.cpp
new file mode 100644
index 0000000..83ccf3b
--- /dev/null
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db1.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator position) with end()
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_multimap<int, int> l1(a1, a1+3);
+    std::unordered_multimap<int, int>::const_iterator i = l1.end();
+    l1.erase(i);
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db2.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db2.pass.cpp
new file mode 100644
index 0000000..fffcfa6
--- /dev/null
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_db2.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator position) with iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <cstdlib>
+#include <exception>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_multimap<int, int> l1(a1, a1+3);
+    std::unordered_multimap<int, int> l2(a1, a1+3);
+    std::unordered_multimap<int, int>::const_iterator i = l2.begin();
+    l1.erase(i);
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db1.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db1.pass.cpp
new file mode 100644
index 0000000..be6caba
--- /dev/null
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db1.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with first iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_multimap<int, int> l1(a1, a1+3);
+    std::unordered_multimap<int, int> l2(a1, a1+3);
+    std::unordered_multimap<int, int>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db2.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db2.pass.cpp
new file mode 100644
index 0000000..a6d5408
--- /dev/null
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db2.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with second iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_multimap<int, int> l1(a1, a1+3);
+    std::unordered_multimap<int, int> l2(a1, a1+3);
+    std::unordered_multimap<int, int>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db3.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db3.pass.cpp
new file mode 100644
index 0000000..301cfb4
--- /dev/null
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db3.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with both iterators from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_multimap<int, int> l1(a1, a1+3);
+    std::unordered_multimap<int, int> l2(a1, a1+3);
+    std::unordered_multimap<int, int>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db4.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db4.pass.cpp
new file mode 100644
index 0000000..b53b486
--- /dev/null
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_iter_iter_db4.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// Call erase(const_iterator first, const_iterator last); with a bad range
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_map>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    typedef std::pair<int, int> P;
+    P a1[] = {P(1, 1), P(2, 2), P(3, 3)};
+    std::unordered_multimap<int, int> l1(a1, a1+3);
+    std::unordered_multimap<int, int>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin());
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp
index 07f423b..d59609a 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_key.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -182,4 +184,168 @@
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.erase(5) == 0);
+        assert(c.size() == 6);
+        typedef std::pair<C::const_iterator, C::const_iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::const_iterator k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 2);
+        assert(k->second == "two");
+        ++k;
+        assert(k->first == 2);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(2) == 2);
+        assert(c.size() == 4);
+        eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(2) == 0);
+        assert(c.size() == 4);
+        eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(4) == 1);
+        assert(c.size() == 3);
+        eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(4) == 0);
+        assert(c.size() == 3);
+        eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(1) == 2);
+        assert(c.size() == 1);
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(1) == 0);
+        assert(c.size() == 1);
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(3) == 1);
+        assert(c.size() == 0);
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 0);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        assert(c.erase(3) == 0);
+        assert(c.size() == 0);
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 0);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp
index 08e7726..3ca3a36 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/erase_range.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -96,4 +98,82 @@
         assert(c.size() == 0);
         assert(k == c.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::const_iterator j = next(i, 2);
+        C::iterator k = c.erase(i, i);
+        assert(k == i);
+        assert(c.size() == 6);
+        typedef std::pair<C::iterator, C::iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 2);
+        assert(k->second == "two");
+        ++k;
+        assert(k->first == 2);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        k = c.erase(i, j);
+        assert(c.size() == 4);
+        eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+
+        k = c.erase(c.cbegin(), c.cend());
+        assert(c.size() == 0);
+        assert(k == c.end());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp
index 39bcefe..0528714 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_const_lvalue.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -45,4 +47,32 @@
         assert(r->first == 5.5);
         assert(r->second == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        R r = c.insert(P(3.5, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(P(3.5, 4));
+        assert(c.size() == 2);
+        assert(r->first == 3.5);
+        assert(r->second == 4);
+
+        r = c.insert(P(4.5, 4));
+        assert(c.size() == 3);
+        assert(r->first == 4.5);
+        assert(r->second == 4);
+
+        r = c.insert(P(5.5, 4));
+        assert(c.size() == 4);
+        assert(r->first == 5.5);
+        assert(r->second == 4);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp
index 038a2f3..f7149a5 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp
@@ -15,9 +15,15 @@
 
 // iterator insert(const_iterator p, const value_type& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <cassert>
 
+#include "../../../min_allocator.h"
+
 int main()
 {
     {
@@ -31,19 +37,61 @@
         assert(r->first == 3.5);
         assert(r->second == 3);
 
-        r = c.insert(e, P(3.5, 4));
+        r = c.insert(c.end(), P(3.5, 4));
         assert(c.size() == 2);
         assert(r->first == 3.5);
         assert(r->second == 4);
 
-        r = c.insert(e, P(4.5, 4));
+        r = c.insert(c.end(), P(4.5, 4));
         assert(c.size() == 3);
         assert(r->first == 4.5);
         assert(r->second == 4);
 
-        r = c.insert(e, P(5.5, 4));
+        r = c.insert(c.end(), P(5.5, 4));
         assert(c.size() == 4);
         assert(r->first == 5.5);
         assert(r->second == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(c.end(), P(3.5, 4));
+        assert(c.size() == 2);
+        assert(r->first == 3.5);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(4.5, 4));
+        assert(c.size() == 3);
+        assert(r->first == 4.5);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(5.5, 4));
+        assert(c.size() == 4);
+        assert(r->first == 5.5);
+        assert(r->second == 4);
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_multimap<double, int> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        P v(3.5, 3);
+        R r = c.insert(e, v);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp
index fbcaa03..0489fc7 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp
@@ -17,10 +17,15 @@
 //           class = typename enable_if<is_convertible<P, value_type>::value>::type>
 //     iterator insert(const_iterator p, P&& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_map>
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -40,12 +45,12 @@
         assert(r->first == 3.5);
         assert(r->second == 4);
 
-        r = c.insert(e, P(4.5, 4));
+        r = c.insert(c.end(), P(4.5, 4));
         assert(c.size() == 3);
         assert(r->first == 4.5);
         assert(r->second == 4);
 
-        r = c.insert(e, P(5.5, 4));
+        r = c.insert(c.end(), P(5.5, 4));
         assert(c.size() == 4);
         assert(r->first == 5.5);
         assert(r->second == 4);
@@ -67,15 +72,85 @@
         assert(r->first == 3);
         assert(r->second == 4);
 
-        r = c.insert(e, P(4, 4));
+        r = c.insert(c.end(), P(4, 4));
         assert(c.size() == 3);
         assert(r->first == 4);
         assert(r->second == 4);
 
-        r = c.insert(e, P(5, 4));
+        r = c.insert(c.end(), P(5, 4));
         assert(c.size() == 4);
         assert(r->first == 5);
         assert(r->second == 4);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef C::iterator R;
+        typedef std::pair<double, short> P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(r, P(3.5, 4));
+        assert(c.size() == 2);
+        assert(r->first == 3.5);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(4.5, 4));
+        assert(c.size() == 3);
+        assert(r->first == 4.5);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(5.5, 4));
+        assert(c.size() == 4);
+        assert(r->first == 5.5);
+        assert(r->second == 4);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
+                            min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+        typedef C::iterator R;
+        typedef std::pair<MoveOnly, MoveOnly> P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3);
+        assert(r->second == 3);
+
+        r = c.insert(r, P(3, 4));
+        assert(c.size() == 2);
+        assert(r->first == 3);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(4, 4));
+        assert(c.size() == 3);
+        assert(r->first == 4);
+        assert(r->second == 4);
+
+        r = c.insert(c.end(), P(5, 4));
+        assert(c.size() == 4);
+        assert(r->first == 5);
+        assert(r->second == 4);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_multimap<double, int> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        R r = c.insert(e, P(3.5, 3));
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp
index cab8508..0a7d8ea 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_init.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -69,5 +70,53 @@
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        C c;
+        c.insert(
+                    {
+                        P(1, "one"),
+                        P(2, "two"),
+                        P(3, "three"),
+                        P(4, "four"),
+                        P(1, "four"),
+                        P(2, "four"),
+                    }
+                );
+        assert(c.size() == 6);
+        typedef std::pair<C::iterator, C::iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::iterator k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 2);
+        assert(k->second == "two");
+        ++k;
+        assert(k->first == 2);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp
index fa44547..bda1958 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_range.pass.cpp
@@ -21,6 +21,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -69,4 +70,52 @@
         assert(std::distance(c.begin(), c.end()) == c.size());
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<int, std::string, std::hash<int>, std::equal_to<int>,
+                            min_allocator<std::pair<const int, std::string>>> C;
+        typedef std::pair<int, std::string> P;
+        P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c;
+        c.insert(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])));
+        assert(c.size() == 6);
+        typedef std::pair<C::iterator, C::iterator> Eq;
+        Eq eq = c.equal_range(1);
+        assert(std::distance(eq.first, eq.second) == 2);
+        C::iterator k = eq.first;
+        assert(k->first == 1);
+        assert(k->second == "one");
+        ++k;
+        assert(k->first == 1);
+        assert(k->second == "four");
+        eq = c.equal_range(2);
+        assert(std::distance(eq.first, eq.second) == 2);
+        k = eq.first;
+        assert(k->first == 2);
+        assert(k->second == "two");
+        ++k;
+        assert(k->first == 2);
+        assert(k->second == "four");
+        eq = c.equal_range(3);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 3);
+        assert(k->second == "three");
+        eq = c.equal_range(4);
+        assert(std::distance(eq.first, eq.second) == 1);
+        k = eq.first;
+        assert(k->first == 4);
+        assert(k->second == "four");
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp
index dceada2..c8bd128 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_rvalue.pass.cpp
@@ -21,6 +21,7 @@
 #include <cassert>
 
 #include "../../../MoveOnly.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -76,4 +77,60 @@
         assert(r->second == 4);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>,
+                            min_allocator<std::pair<const double, int>>> C;
+        typedef C::iterator R;
+        typedef std::pair<double, short> P;
+        C c;
+        R r = c.insert(P(3.5, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3.5);
+        assert(r->second == 3);
+
+        r = c.insert(P(3.5, 4));
+        assert(c.size() == 2);
+        assert(r->first == 3.5);
+        assert(r->second == 4);
+
+        r = c.insert(P(4.5, 4));
+        assert(c.size() == 3);
+        assert(r->first == 4.5);
+        assert(r->second == 4);
+
+        r = c.insert(P(5.5, 4));
+        assert(c.size() == 4);
+        assert(r->first == 5.5);
+        assert(r->second == 4);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
+                            min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+        typedef C::iterator R;
+        typedef std::pair<MoveOnly, MoveOnly> P;
+        C c;
+        R r = c.insert(P(3, 3));
+        assert(c.size() == 1);
+        assert(r->first == 3);
+        assert(r->second == 3);
+
+        r = c.insert(P(3, 4));
+        assert(c.size() == 2);
+        assert(r->first == 3);
+        assert(r->second == 4);
+
+        r = c.insert(P(4, 4));
+        assert(c.size() == 3);
+        assert(r->first == 4);
+        assert(r->second == 4);
+
+        r = c.insert(P(5, 4));
+        assert(c.size() == 4);
+        assert(r->first == 5);
+        assert(r->second == 4);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.swap/db_swap_1.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.swap/db_swap_1.pass.cpp
new file mode 100644
index 0000000..a332b6f
--- /dev/null
+++ b/test/containers/unord/unord.multimap/unord.multimap.swap/db_swap_1.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class Value, class Hash = hash<Key>, class Pred = equal_to<Key>,
+//           class Alloc = allocator<pair<const Key, Value>>>
+// class unordered_multimap
+
+// void swap(unordered_multimap& x, unordered_multimap& y);
+
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <unordered_map>
+#include <cassert>
+
+int main()
+{
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::pair<int, int> P;
+        P a1[] = {P(1, 1), P(3, 3), P(7, 7), P(9, 9), P(10, 10)};
+        P a2[] = {P(0, 0), P(2, 2), P(4, 4), P(5, 5), P(6, 6), P(8, 8), P(11, 11)};
+        std::unordered_multimap<int, int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::unordered_multimap<int, int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        std::unordered_multimap<int, int>::iterator i1 = c1.begin();
+        std::unordered_multimap<int, int>::iterator i2 = c2.begin();
+        swap(c1, c2);
+        c1.erase(i2);
+        c2.erase(i1);
+        std::unordered_multimap<int, int>::iterator j = i1;
+        c1.erase(i1);
+        assert(false);
+    }
+#endif
+}
diff --git a/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp
index 2560919..227a700 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp
@@ -48,13 +48,13 @@
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                           std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C;
+                           std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
     {
         typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
-                          std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C;
+                          std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
         C c1, c2;
         static_assert(noexcept(swap(c1, c2)), "");
     }
diff --git a/test/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp
index d7f2570..0b5c5c3 100644
--- a/test/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp
+++ b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_non_member.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -394,4 +395,190 @@
         assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
         assert(c2.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.find(10)->second == "ten");
+        assert(c1.find(20)->second == "twenty");
+        assert(c1.find(30)->second == "thirty");
+        assert(c1.find(40)->second == "fourty");
+        assert(c1.find(50)->second == "fifty");
+        assert(c1.find(60)->second == "sixty");
+        assert(c1.find(70)->second == "seventy");
+        assert(c1.find(80)->second == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.find(1)->second == "one");
+        assert(next(c2.find(1))->second == "four");
+        assert(c2.find(2)->second == "two");
+        assert(next(c2.find(2))->second == "four");
+        assert(c2.find(3)->second == "three");
+        assert(c2.find(4)->second == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<std::pair<const int, std::string> > Alloc;
+        typedef std::unordered_multimap<int, std::string, Hash, Compare, Alloc> C;
+        typedef std::pair<int, std::string> P;
+        P a1[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        P a2[] =
+        {
+            P(10, "ten"),
+            P(20, "twenty"),
+            P(30, "thirty"),
+            P(40, "fourty"),
+            P(50, "fifty"),
+            P(60, "sixty"),
+            P(70, "seventy"),
+            P(80, "eighty"),
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(c1.find(10)->second == "ten");
+        assert(c1.find(20)->second == "twenty");
+        assert(c1.find(30)->second == "thirty");
+        assert(c1.find(40)->second == "fourty");
+        assert(c1.find(50)->second == "fifty");
+        assert(c1.find(60)->second == "sixty");
+        assert(c1.find(70)->second == "seventy");
+        assert(c1.find(80)->second == "eighty");
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.find(1)->second == "one");
+        assert(next(c2.find(1))->second == "four");
+        assert(c2.find(2)->second == "two");
+        assert(next(c2.find(2))->second == "four");
+        assert(c2.find(3)->second == "three");
+        assert(c2.find(4)->second == "four");
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/bucket.pass.cpp b/test/containers/unord/unord.multiset/bucket.pass.cpp
index cab661b..2d8927d 100644
--- a/test/containers/unord/unord.multiset/bucket.pass.cpp
+++ b/test/containers/unord/unord.multiset/bucket.pass.cpp
@@ -15,9 +15,15 @@
 
 // size_type bucket(const key_type& __k) const;
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -38,4 +44,33 @@
         for (size_t i = 0; i < 13; ++i)
             assert(c.bucket(i) == i % bc);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(std::begin(a), std::end(a));
+        size_t bc = c.bucket_count();
+        assert(bc >= 7);
+        for (size_t i = 0; i < 13; ++i)
+            assert(c.bucket(i) == i % bc);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multiset<int> C;
+        C c;
+        C::size_type i = c.bucket(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/bucket_count.pass.cpp b/test/containers/unord/unord.multiset/bucket_count.pass.cpp
index d2469b6..36c45b0 100644
--- a/test/containers/unord/unord.multiset/bucket_count.pass.cpp
+++ b/test/containers/unord/unord.multiset/bucket_count.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -45,4 +47,33 @@
         const C c(std::begin(a), std::end(a));
         assert(c.bucket_count() >= 11);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef C::const_iterator I;
+        typedef int P;
+        const C c;
+        assert(c.bucket_count() == 0);
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef C::const_iterator I;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.bucket_count() >= 11);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/bucket_size.pass.cpp b/test/containers/unord/unord.multiset/bucket_size.pass.cpp
index 6e04ccf..8718223 100644
--- a/test/containers/unord/unord.multiset/bucket_size.pass.cpp
+++ b/test/containers/unord/unord.multiset/bucket_size.pass.cpp
@@ -15,9 +15,15 @@
 
 // size_type bucket_size(size_type n) const
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +48,37 @@
         assert(c.bucket_size(5) == 0);
         assert(c.bucket_size(6) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.bucket_count() >= 7);
+        assert(c.bucket_size(0) == 0);
+        assert(c.bucket_size(1) == 2);
+        assert(c.bucket_size(2) == 2);
+        assert(c.bucket_size(3) == 1);
+        assert(c.bucket_size(4) == 1);
+        assert(c.bucket_size(5) == 0);
+        assert(c.bucket_size(6) == 0);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multiset<int> C;
+        C c;
+        C::size_type i = c.bucket_size(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/clear.pass.cpp b/test/containers/unord/unord.multiset/clear.pass.cpp
index 21c9a90..7391631 100644
--- a/test/containers/unord/unord.multiset/clear.pass.cpp
+++ b/test/containers/unord/unord.multiset/clear.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -36,4 +38,23 @@
         c.clear();
         assert(c.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        c.clear();
+        assert(c.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/count.pass.cpp b/test/containers/unord/unord.multiset/count.pass.cpp
index 74447ef..426b5f8 100644
--- a/test/containers/unord/unord.multiset/count.pass.cpp
+++ b/test/containers/unord/unord.multiset/count.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -41,4 +43,28 @@
         assert(c.count(50) == 3);
         assert(c.count(5) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.count(30) == 1);
+        assert(c.count(50) == 3);
+        assert(c.count(5) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp b/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp
new file mode 100644
index 0000000..92611ca
--- /dev/null
+++ b/test/containers/unord/unord.multiset/db_iterators_7.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> C;
+    C c(1);
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp b/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp
new file mode 100644
index 0000000..635e211
--- /dev/null
+++ b/test/containers/unord/unord.multiset/db_iterators_8.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp b/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp
new file mode 100644
index 0000000..8bfe0fc
--- /dev/null
+++ b/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment local_iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T, min_allocator<T>> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#endif
+
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp b/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp
new file mode 100644
index 0000000..1adc686
--- /dev/null
+++ b/test/containers/unord/unord.multiset/db_local_iterators_8.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    T j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T, min_allocator<T>> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    T j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multiset/emplace.pass.cpp b/test/containers/unord/unord.multiset/emplace.pass.cpp
index b151305..7847883 100644
--- a/test/containers/unord/unord.multiset/emplace.pass.cpp
+++ b/test/containers/unord/unord.multiset/emplace.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "../../Emplaceable.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -40,5 +41,24 @@
         assert(c.size() == 3);
         assert(*r == Emplaceable(5, 6));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<Emplaceable, std::hash<Emplaceable>,
+                      std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C;
+        typedef C::iterator R;
+        C c;
+        R r = c.emplace();
+        assert(c.size() == 1);
+        assert(*r == Emplaceable());
+
+        r = c.emplace(Emplaceable(5, 6));
+        assert(c.size() == 2);
+        assert(*r == Emplaceable(5, 6));
+
+        r = c.emplace(5, 6);
+        assert(c.size() == 3);
+        assert(*r == Emplaceable(5, 6));
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multiset/emplace_hint.pass.cpp b/test/containers/unord/unord.multiset/emplace_hint.pass.cpp
index 1e529b0..eddffc4 100644
--- a/test/containers/unord/unord.multiset/emplace_hint.pass.cpp
+++ b/test/containers/unord/unord.multiset/emplace_hint.pass.cpp
@@ -16,10 +16,15 @@
 // template <class... Args>
 //     iterator emplace_hint(const_iterator p, Args&&... args);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
 #include "../../Emplaceable.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -33,7 +38,7 @@
         assert(c.size() == 1);
         assert(*r == Emplaceable());
 
-        r = c.emplace_hint(e, Emplaceable(5, 6));
+        r = c.emplace_hint(c.end(), Emplaceable(5, 6));
         assert(c.size() == 2);
         assert(*r == Emplaceable(5, 6));
 
@@ -41,5 +46,35 @@
         assert(c.size() == 3);
         assert(*r == Emplaceable(5, 6));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<Emplaceable, std::hash<Emplaceable>,
+                      std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C;
+        typedef C::iterator R;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.emplace_hint(e);
+        assert(c.size() == 1);
+        assert(*r == Emplaceable());
+
+        r = c.emplace_hint(c.end(), Emplaceable(5, 6));
+        assert(c.size() == 2);
+        assert(*r == Emplaceable(5, 6));
+
+        r = c.emplace_hint(r, 5, 6);
+        assert(c.size() == 3);
+        assert(*r == Emplaceable(5, 6));
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_multiset<Emplaceable> C;
+        typedef C::iterator R;
+        C c1;
+        C c2;
+        R r = c1.emplace_hint(c2.begin(), 5, 6);
+        assert(false);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multiset/eq.pass.cpp b/test/containers/unord/unord.multiset/eq.pass.cpp
index 6ac9ac8..7350e44 100644
--- a/test/containers/unord/unord.multiset/eq.pass.cpp
+++ b/test/containers/unord/unord.multiset/eq.pass.cpp
@@ -22,6 +22,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -97,4 +99,82 @@
         assert( (c1 == c2));
         assert(!(c1 != c2));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2;
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2 = c1;
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(std::begin(a), std::end(a));
+        C c2 = c1;
+        c2.rehash(30);
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+        c2.insert(P(90));
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+        c1.insert(P(90));
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/equal_range_const.pass.cpp b/test/containers/unord/unord.multiset/equal_range_const.pass.cpp
index 91df127..3fe242f 100644
--- a/test/containers/unord/unord.multiset/equal_range_const.pass.cpp
+++ b/test/containers/unord/unord.multiset/equal_range_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -51,4 +53,38 @@
         ++r.first;
         assert(*r.first == 50);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef C::const_iterator I;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(*r.first == 30);
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+        r = c.equal_range(50);
+        assert(std::distance(r.first, r.second) == 3);
+        assert(*r.first == 50);
+        ++r.first;
+        assert(*r.first == 50);
+        ++r.first;
+        assert(*r.first == 50);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/equal_range_non_const.pass.cpp b/test/containers/unord/unord.multiset/equal_range_non_const.pass.cpp
index c0f974a..ebda719 100644
--- a/test/containers/unord/unord.multiset/equal_range_non_const.pass.cpp
+++ b/test/containers/unord/unord.multiset/equal_range_non_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -51,4 +53,38 @@
         ++r.first;
         assert(*r.first == 50);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef C::iterator I;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(*r.first == 30);
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+        r = c.equal_range(50);
+        assert(std::distance(r.first, r.second) == 3);
+        assert(*r.first == 50);
+        ++r.first;
+        assert(*r.first == 50);
+        ++r.first;
+        assert(*r.first == 50);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/erase_const_iter.pass.cpp b/test/containers/unord/unord.multiset/erase_const_iter.pass.cpp
index 658f50f..6cb2c72 100644
--- a/test/containers/unord/unord.multiset/erase_const_iter.pass.cpp
+++ b/test/containers/unord/unord.multiset/erase_const_iter.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -41,4 +43,28 @@
         assert(c.count(3) == 1);
         assert(c.count(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::iterator j = c.erase(i);
+        assert(c.size() == 5);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+    }
+#endif
 }
diff --git a/test/containers/sequences/vector/db_iterators_1.pass.cpp b/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp
similarity index 63%
rename from test/containers/sequences/vector/db_iterators_1.pass.cpp
rename to test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp
index fbcb40f..baad385 100644
--- a/test/containers/sequences/vector/db_iterators_1.pass.cpp
+++ b/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp
@@ -7,28 +7,26 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_set>
 
-// Compare iterators from different containers with == or !=.
+// Call erase(const_iterator position) with end()
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
-#include <vector>
+#include <unordered_set>
 #include <cassert>
-#include <iterator>
-#include <exception>
-#include <cstdlib>
 
 int main()
 {
-    typedef int T;
-    typedef std::vector<T> C;
-    C c1;
-    C c2;
-    bool b = c1.begin() != c2.begin();
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int>::const_iterator i = l1.end();
+    l1.erase(i);
     assert(false);
+    }
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_1.pass.cpp b/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp
similarity index 60%
copy from test/containers/sequences/vector/db_iterators_1.pass.cpp
copy to test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp
index fbcb40f..a21f29e 100644
--- a/test/containers/sequences/vector/db_iterators_1.pass.cpp
+++ b/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp
@@ -7,28 +7,29 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_set>
 
-// Compare iterators from different containers with == or !=.
+// Call erase(const_iterator position) with iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
-#include <vector>
+#include <unordered_set>
 #include <cassert>
-#include <iterator>
-#include <exception>
 #include <cstdlib>
+#include <exception>
 
 int main()
 {
-    typedef int T;
-    typedef std::vector<T> C;
-    C c1;
-    C c2;
-    bool b = c1.begin() != c2.begin();
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::const_iterator i = l2.begin();
+    l1.erase(i);
     assert(false);
+    }
 }
 
 #else
diff --git a/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp b/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp
new file mode 100644
index 0000000..03c9ec5
--- /dev/null
+++ b/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with first iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp b/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp
new file mode 100644
index 0000000..4c6f209
--- /dev/null
+++ b/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with second iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp b/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp
new file mode 100644
index 0000000..5ce3789
--- /dev/null
+++ b/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with both iterators from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/sequences/vector/db_iterators_1.pass.cpp b/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp
similarity index 62%
copy from test/containers/sequences/vector/db_iterators_1.pass.cpp
copy to test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp
index fbcb40f..7c362a2 100644
--- a/test/containers/sequences/vector/db_iterators_1.pass.cpp
+++ b/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp
@@ -7,28 +7,27 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_set>
 
-// Compare iterators from different containers with == or !=.
+// Call erase(const_iterator first, const_iterator last); with a bad range
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
-#include <vector>
+#include <unordered_set>
 #include <cassert>
-#include <iterator>
 #include <exception>
 #include <cstdlib>
 
 int main()
 {
-    typedef int T;
-    typedef std::vector<T> C;
-    C c1;
-    C c2;
-    bool b = c1.begin() != c2.begin();
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin());
     assert(false);
+    }
 }
 
 #else
diff --git a/test/containers/unord/unord.multiset/erase_key.pass.cpp b/test/containers/unord/unord.multiset/erase_key.pass.cpp
index ecb974e..b0b6815 100644
--- a/test/containers/unord/unord.multiset/erase_key.pass.cpp
+++ b/test/containers/unord/unord.multiset/erase_key.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -77,4 +79,63 @@
         assert(c.erase(3) == 0);
         assert(c.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.erase(5) == 0);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        assert(c.erase(2) == 2);
+        assert(c.size() == 4);
+        assert(c.count(1) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        assert(c.erase(2) == 0);
+        assert(c.size() == 4);
+        assert(c.count(1) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        assert(c.erase(4) == 1);
+        assert(c.size() == 3);
+        assert(c.count(1) == 2);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(4) == 0);
+        assert(c.size() == 3);
+        assert(c.count(1) == 2);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(1) == 2);
+        assert(c.size() == 1);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(1) == 0);
+        assert(c.size() == 1);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(3) == 1);
+        assert(c.size() == 0);
+
+        assert(c.erase(3) == 0);
+        assert(c.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/erase_range.pass.cpp b/test/containers/unord/unord.multiset/erase_range.pass.cpp
index cf27775..601c4b3 100644
--- a/test/containers/unord/unord.multiset/erase_range.pass.cpp
+++ b/test/containers/unord/unord.multiset/erase_range.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -53,4 +55,40 @@
         assert(c.size() == 0);
         assert(k == c.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::const_iterator j = next(i, 2);
+        C::iterator k = c.erase(i, i);
+        assert(k == i);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        k = c.erase(i, j);
+        assert(c.size() == 4);
+        assert(c.count(1) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        k = c.erase(c.cbegin(), c.cend());
+        assert(c.size() == 0);
+        assert(k == c.end());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/find_const.pass.cpp b/test/containers/unord/unord.multiset/find_const.pass.cpp
index b39e46f..dbe4eae 100644
--- a/test/containers/unord/unord.multiset/find_const.pass.cpp
+++ b/test/containers/unord/unord.multiset/find_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -40,4 +42,27 @@
         i = c.find(5);
         assert(i == c.cend());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        C::const_iterator i = c.find(30);
+        assert(*i == 30);
+        i = c.find(5);
+        assert(i == c.cend());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/find_non_const.pass.cpp b/test/containers/unord/unord.multiset/find_non_const.pass.cpp
index e6ac855..af63018 100644
--- a/test/containers/unord/unord.multiset/find_non_const.pass.cpp
+++ b/test/containers/unord/unord.multiset/find_non_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -40,4 +42,27 @@
         i = c.find(5);
         assert(i == c.cend());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c(std::begin(a), std::end(a));
+        C::iterator i = c.find(30);
+        assert(*i == 30);
+        i = c.find(5);
+        assert(i == c.cend());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp b/test/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp
index 6e4b9a1..ce46997 100644
--- a/test/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.multiset/insert_const_lvalue.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -41,4 +43,28 @@
         assert(c.size() == 4);
         assert(*r == 5.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        R r = c.insert(P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(P(3.5));
+        assert(c.size() == 2);
+        assert(*r == 3.5);
+
+        r = c.insert(P(4.5));
+        assert(c.size() == 3);
+        assert(*r == 4.5);
+
+        r = c.insert(P(5.5));
+        assert(c.size() == 4);
+        assert(*r == 5.5);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp b/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp
index 4d949e4..d3a3d76 100644
--- a/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp
@@ -15,9 +15,15 @@
 
 // iterator insert(const_iterator p, const value_type& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -30,16 +36,54 @@
         assert(c.size() == 1);
         assert(*r == 3.5);
 
-        r = c.insert(e, P(3.5));
+        r = c.insert(c.end(), P(3.5));
         assert(c.size() == 2);
         assert(*r == 3.5);
 
-        r = c.insert(e, P(4.5));
+        r = c.insert(c.end(), P(4.5));
         assert(c.size() == 3);
         assert(*r == 4.5);
 
-        r = c.insert(e, P(5.5));
+        r = c.insert(c.end(), P(5.5));
         assert(c.size() == 4);
         assert(*r == 5.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(c.end(), P(3.5));
+        assert(c.size() == 2);
+        assert(*r == 3.5);
+
+        r = c.insert(c.end(), P(4.5));
+        assert(c.size() == 3);
+        assert(*r == 4.5);
+
+        r = c.insert(c.end(), P(5.5));
+        assert(c.size() == 4);
+        assert(*r == 5.5);
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_multiset<double> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        P v(3.5);
+        R r = c.insert(e, v);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp b/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp
index 8239b34..fb95ea3 100644
--- a/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp
+++ b/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp
@@ -15,10 +15,15 @@
 
 // iterator insert(const_iterator p, value_type&& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -36,11 +41,11 @@
         assert(c.size() == 2);
         assert(*r == 3.5);
 
-        r = c.insert(e, P(4.5));
+        r = c.insert(c.end(), P(4.5));
         assert(c.size() == 3);
         assert(*r == 4.5);
 
-        r = c.insert(e, P(5.5));
+        r = c.insert(c.end(), P(5.5));
         assert(c.size() == 4);
         assert(*r == 5.5);
     }
@@ -59,13 +64,75 @@
         assert(c.size() == 2);
         assert(*r == 3);
 
-        r = c.insert(e, P(4));
+        r = c.insert(c.end(), P(4));
         assert(c.size() == 3);
         assert(*r == 4);
 
-        r = c.insert(e, P(5));
+        r = c.insert(c.end(), P(5));
         assert(c.size() == 4);
         assert(*r == 5);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef C::iterator R;
+        typedef double P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(r, P(3.5));
+        assert(c.size() == 2);
+        assert(*r == 3.5);
+
+        r = c.insert(c.end(), P(4.5));
+        assert(c.size() == 3);
+        assert(*r == 4.5);
+
+        r = c.insert(c.end(), P(5.5));
+        assert(c.size() == 4);
+        assert(*r == 5.5);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_multiset<MoveOnly, std::hash<MoveOnly>,
+                            std::equal_to<MoveOnly>, min_allocator<MoveOnly>> C;
+        typedef C::iterator R;
+        typedef MoveOnly P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3));
+        assert(c.size() == 1);
+        assert(*r == 3);
+
+        r = c.insert(r, P(3));
+        assert(c.size() == 2);
+        assert(*r == 3);
+
+        r = c.insert(c.end(), P(4));
+        assert(c.size() == 3);
+        assert(*r == 4);
+
+        r = c.insert(c.end(), P(5));
+        assert(c.size() == 4);
+        assert(*r == 5);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_multiset<double> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        R r = c.insert(e, P(3.5));
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/insert_init.pass.cpp b/test/containers/unord/unord.multiset/insert_init.pass.cpp
index db82f65..7a9d3f7 100644
--- a/test/containers/unord/unord.multiset/insert_init.pass.cpp
+++ b/test/containers/unord/unord.multiset/insert_init.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -43,5 +44,28 @@
         assert(c.count(3) == 1);
         assert(c.count(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        C c;
+        c.insert(
+                    {
+                        P(1),
+                        P(2),
+                        P(3),
+                        P(4),
+                        P(1),
+                        P(2)
+                    }
+                );
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multiset/insert_range.pass.cpp b/test/containers/unord/unord.multiset/insert_range.pass.cpp
index 93d5e83..28637f5 100644
--- a/test/containers/unord/unord.multiset/insert_range.pass.cpp
+++ b/test/containers/unord/unord.multiset/insert_range.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -43,4 +44,27 @@
         assert(c.count(3) == 1);
         assert(c.count(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c;
+        c.insert(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])));
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/insert_rvalue.pass.cpp b/test/containers/unord/unord.multiset/insert_rvalue.pass.cpp
index dd33e4b..7cddb0d 100644
--- a/test/containers/unord/unord.multiset/insert_rvalue.pass.cpp
+++ b/test/containers/unord/unord.multiset/insert_rvalue.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -66,4 +67,52 @@
         assert(*r == 5);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef C::iterator R;
+        typedef double P;
+        C c;
+        R r = c.insert(P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(P(3.5));
+        assert(c.size() == 2);
+        assert(*r == 3.5);
+
+        r = c.insert(P(4.5));
+        assert(c.size() == 3);
+        assert(*r == 4.5);
+
+        r = c.insert(P(5.5));
+        assert(c.size() == 4);
+        assert(*r == 5.5);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_multiset<MoveOnly, std::hash<MoveOnly>,
+                            std::equal_to<MoveOnly>, min_allocator<MoveOnly>> C;
+        typedef C::iterator R;
+        typedef MoveOnly P;
+        C c;
+        R r = c.insert(P(3));
+        assert(c.size() == 1);
+        assert(*r == 3);
+
+        r = c.insert(P(3));
+        assert(c.size() == 2);
+        assert(*r == 3);
+
+        r = c.insert(P(4));
+        assert(c.size() == 3);
+        assert(*r == 4);
+
+        r = c.insert(P(5));
+        assert(c.size() == 4);
+        assert(*r == 5);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/iterators.pass.cpp b/test/containers/unord/unord.multiset/iterators.pass.cpp
index 1da8606..e51b3e1 100644
--- a/test/containers/unord/unord.multiset/iterators.pass.cpp
+++ b/test/containers/unord/unord.multiset/iterators.pass.cpp
@@ -23,6 +23,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -63,4 +65,60 @@
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
         C::const_iterator i;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::iterator i;
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::const_iterator i;
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::unordered_multiset<int> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/load_factor.pass.cpp b/test/containers/unord/unord.multiset/load_factor.pass.cpp
index 664a2a7..c6e4825 100644
--- a/test/containers/unord/unord.multiset/load_factor.pass.cpp
+++ b/test/containers/unord/unord.multiset/load_factor.pass.cpp
@@ -19,6 +19,8 @@
 #include <cassert>
 #include <cfloat>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -44,4 +46,31 @@
         const C c;
         assert(c.load_factor() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        const C c;
+        assert(c.load_factor() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/local_iterators.pass.cpp b/test/containers/unord/unord.multiset/local_iterators.pass.cpp
index 51481ac..6cc07b6 100644
--- a/test/containers/unord/unord.multiset/local_iterators.pass.cpp
+++ b/test/containers/unord/unord.multiset/local_iterators.pass.cpp
@@ -23,6 +23,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -257,4 +259,242 @@
         j = c.cend(b);
         assert(std::distance(i, j) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+
+        b = c.bucket(5);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+
+        b = c.bucket(5);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 0);
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+
+        b = c.bucket(5);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 7);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 2);
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+
+        b = c.bucket(5);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(6);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/max_bucket_count.pass.cpp b/test/containers/unord/unord.multiset/max_bucket_count.pass.cpp
index db6d988..fa55a1f 100644
--- a/test/containers/unord/unord.multiset/max_bucket_count.pass.cpp
+++ b/test/containers/unord/unord.multiset/max_bucket_count.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -25,4 +27,12 @@
         const C c;
         assert(c.max_bucket_count() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        const C c;
+        assert(c.max_bucket_count() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/max_load_factor.pass.cpp b/test/containers/unord/unord.multiset/max_load_factor.pass.cpp
index d1212d8..00cd1b1 100644
--- a/test/containers/unord/unord.multiset/max_load_factor.pass.cpp
+++ b/test/containers/unord/unord.multiset/max_load_factor.pass.cpp
@@ -16,9 +16,15 @@
 // float max_load_factor() const;
 // void max_load_factor(float mlf);
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -35,4 +41,30 @@
         c.max_load_factor(2.5);
         assert(c.max_load_factor() == 2.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        const C c;
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        C c;
+        assert(c.max_load_factor() == 1);
+        c.max_load_factor(2.5);
+        assert(c.max_load_factor() == 2.5);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multiset<int> C;
+        C c;
+        c.max_load_factor(0);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/max_size.pass.cpp b/test/containers/unord/unord.multiset/max_size.pass.cpp
index fa2938e..2317129 100644
--- a/test/containers/unord/unord.multiset/max_size.pass.cpp
+++ b/test/containers/unord/unord.multiset/max_size.pass.cpp
@@ -18,10 +18,19 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
         std::unordered_multiset<int> u;
         assert(u.max_size() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> u;
+        assert(u.max_size() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/rehash.pass.cpp b/test/containers/unord/unord.multiset/rehash.pass.cpp
index e82664b..9358c32 100644
--- a/test/containers/unord/unord.multiset/rehash.pass.cpp
+++ b/test/containers/unord/unord.multiset/rehash.pass.cpp
@@ -18,7 +18,10 @@
 #include <unordered_set>
 #include <cassert>
 
-void test(const std::unordered_multiset<int>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
     assert(c.size() == 6);
     assert(c.count(1) == 2);
@@ -55,4 +58,33 @@
         assert(c.bucket_count() == 31);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 7);
+        c.rehash(3);
+        assert(c.bucket_count() == 7);
+        test(c);
+        c.max_load_factor(2);
+        c.rehash(3);
+        assert(c.bucket_count() == 3);
+        test(c);
+        c.rehash(31);
+        assert(c.bucket_count() == 31);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/reserve.pass.cpp b/test/containers/unord/unord.multiset/reserve.pass.cpp
index bce8213..e1c9e0a 100644
--- a/test/containers/unord/unord.multiset/reserve.pass.cpp
+++ b/test/containers/unord/unord.multiset/reserve.pass.cpp
@@ -18,7 +18,10 @@
 #include <unordered_set>
 #include <cassert>
 
-void test(const std::unordered_multiset<int>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
     assert(c.size() == 6);
     assert(c.count(1) == 2);
@@ -55,4 +58,33 @@
         assert(c.bucket_count() >= 16);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 7);
+        c.reserve(3);
+        assert(c.bucket_count() == 7);
+        test(c);
+        c.max_load_factor(2);
+        c.reserve(3);
+        assert(c.bucket_count() == 3);
+        test(c);
+        c.reserve(31);
+        assert(c.bucket_count() >= 16);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/scary.pass.cpp b/test/containers/unord/unord.multiset/scary.pass.cpp
new file mode 100644
index 0000000..dfd144b
--- /dev/null
+++ b/test/containers/unord/unord.multiset/scary.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// class unordered_set class unordered_multiset
+
+// Extension:  SCARY/N2913 iterator compatibility between unordered_set and unordered_multiset
+
+#include <unordered_set>
+
+int main()
+{
+    typedef std::unordered_set<int> M1;
+    typedef std::unordered_multiset<int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}
diff --git a/test/containers/unord/unord.multiset/swap_member.pass.cpp b/test/containers/unord/unord.multiset/swap_member.pass.cpp
index 3392ecc..3a7c506 100644
--- a/test/containers/unord/unord.multiset/swap_member.pass.cpp
+++ b/test/containers/unord/unord.multiset/swap_member.pass.cpp
@@ -21,6 +21,7 @@
 #include "../../test_compare.h"
 #include "../../test_hash.h"
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -385,4 +386,186 @@
         assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
         assert(c2.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a2[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(*c1.find(10) == 10);
+        assert(*c1.find(20) == 20);
+        assert(*c1.find(30) == 30);
+        assert(*c1.find(40) == 40);
+        assert(*c1.find(50) == 50);
+        assert(*c1.find(60) == 60);
+        assert(*c1.find(70) == 70);
+        assert(*c1.find(80) == 80);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a1[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.count(1) == 2);
+        assert(c2.count(2) == 2);
+        assert(c2.count(3) == 1);
+        assert(c2.count(4) == 1);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a1[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        P a2[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(*c1.find(10) == 10);
+        assert(*c1.find(20) == 20);
+        assert(*c1.find(30) == 30);
+        assert(*c1.find(40) == 40);
+        assert(*c1.find(50) == 50);
+        assert(*c1.find(60) == 60);
+        assert(*c1.find(70) == 70);
+        assert(*c1.find(80) == 80);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.count(1) == 2);
+        assert(c2.count(2) == 2);
+        assert(c2.count(3) == 1);
+        assert(c2.count(4) == 1);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/types.pass.cpp b/test/containers/unord/unord.multiset/types.pass.cpp
index 67a8eb6..5d7fa3a 100644
--- a/test/containers/unord/unord.multiset/types.pass.cpp
+++ b/test/containers/unord/unord.multiset/types.pass.cpp
@@ -30,6 +30,8 @@
 #include <unordered_set>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -46,4 +48,21 @@
         static_assert((std::is_same<C::size_type, std::size_t>::value), "");
         static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<short, std::hash<short>,
+                                  std::equal_to<short>, min_allocator<short>> C;
+        static_assert((std::is_same<C::value_type, short>::value), "");
+        static_assert((std::is_same<C::key_type, short>::value), "");
+        static_assert((std::is_same<C::hasher, std::hash<C::key_type> >::value), "");
+        static_assert((std::is_same<C::key_equal, std::equal_to<C::key_type> >::value), "");
+        static_assert((std::is_same<C::allocator_type, min_allocator<C::value_type> >::value), "");
+        static_assert((std::is_same<C::reference, C::value_type&>::value), "");
+        static_assert((std::is_same<C::const_reference, const C::value_type&>::value), "");
+        static_assert((std::is_same<C::pointer, min_pointer<C::value_type>>::value), "");
+        static_assert((std::is_same<C::const_pointer, min_pointer<const C::value_type>>::value), "");
+        static_assert((std::is_same<C::size_type, std::size_t>::value), "");
+        static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp
index 2299b5e..af9dd01 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/allocator.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -42,4 +43,67 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c(min_allocator<NotConstructible>{});
+        assert(c.bucket_count() == 0);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() == min_allocator<NotConstructible>());
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef NotConstructible T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_multiset<T, HF, Comp, A> C;
+
+        A a(43);
+        C c(3, a);
+        assert(c.bucket_count() == 3);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp ());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef NotConstructible T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_multiset<T, HF, Comp, A> C;
+
+        HF hf(42);
+        A a(43);
+        C c(4, hf, a);
+        assert(c.bucket_count() == 4);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp ());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
index dbeda94..5f5cac2 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -131,4 +132,59 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<int> A;
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(a, a + 2,
+            7,
+            test_hash<std::hash<int> >(2),
+            test_compare<std::equal_to<int> >(3),
+            A()
+           );
+        c = c0;
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 4);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp
index d1c3cb1..23ca1fc 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_init.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -58,5 +59,39 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef min_allocator<int> A;
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef int P;
+        C c =   {
+                    P(4),
+                    P(1),
+                    P(2)
+                };
+        c =     {
+                    P(1),
+                    P(2),
+                    P(3),
+                    P(4),
+                    P(1),
+                    P(2)
+                };
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
index 881a0d7..942ab86 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -169,5 +170,117 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_allocator<int> A;
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(a, a + 2,
+            7,
+            test_hash<std::hash<int> >(2),
+            test_compare<std::equal_to<int> >(3),
+            A()
+           );
+        c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef min_allocator<int> A;
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(a, a + 2,
+            7,
+            test_hash<std::hash<int> >(2),
+            test_compare<std::equal_to<int> >(3),
+            A()
+           );
+        c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::unordered_multiset<int> s1 = {1, 2, 3};
+        std::unordered_multiset<int>::iterator i = s1.begin();
+        int k = *i;
+        std::unordered_multiset<int> s2;
+        s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp
index 20f5644..300a4db 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -119,4 +120,52 @@
         assert(c.max_load_factor() == 1);
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<int>()
+           );
+        C c = c0;
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 4);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp
index b3357a8..636f644 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/copy_alloc.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -71,4 +72,52 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<int>()
+           );
+        C c(c0, min_allocator<int>());
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 4);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp
index d2761b1..4546d59 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/default.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -42,4 +43,23 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c;
+        assert(c.bucket_count() == 0);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() == (min_allocator<NotConstructible>()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp
index ce16ebf..3578d35 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -56,5 +57,107 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        C c = {
+                P(1),
+                P(2),
+                P(3),
+                P(4),
+                P(1),
+                P(2)
+            };
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef int T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_multiset<T, HF, Comp, A> C;
+
+        A a(42);
+        C c({
+                T(1),
+                T(2),
+                T(3),
+                T(4),
+                T(1),
+                T(2)
+            }, 12, a);
+
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef int T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_multiset<T, HF, Comp, A> C;
+
+        A a(42);
+        HF hf(43);
+        C c({
+                T(1),
+                T(2),
+                T(3),
+                T(4),
+                T(1),
+                T(2)
+            }, 12, hf, a);
+
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp
index b473d26..f16c232 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -58,5 +59,39 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        C c({
+                P(1),
+                P(2),
+                P(3),
+                P(4),
+                P(1),
+                P(2)
+            },
+            7
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp
index 4b474fc..53bf195 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -60,5 +61,40 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        C c({
+                P(1),
+                P(2),
+                P(3),
+                P(4),
+                P(1),
+                P(2)
+            },
+            7,
+            test_hash<std::hash<int> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp
index ca8fde4..bd2c318 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -61,5 +62,41 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        C c({
+                P(1),
+                P(2),
+                P(3),
+                P(4),
+                P(1),
+                P(2)
+            },
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp
index ba1ec05..d7c6935 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_equal_allocator.pass.cpp
@@ -23,6 +23,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -62,5 +63,42 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        C c({
+                P(1),
+                P(2),
+                P(3),
+                P(4),
+                P(1),
+                P(2)
+            },
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<int>()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp
index 969d35d..593ba0d 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -101,5 +102,93 @@
 
         assert(c0.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<int>()
+           );
+        C c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 0);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<int>()
+           );
+        C c = std::move(c0);
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        std::unordered_multiset<int> s1 = {1, 2, 3};
+        std::unordered_multiset<int>::iterator i = s1.begin();
+        int k = *i;
+        std::unordered_multiset<int> s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp
index 77d6d81..e528316 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/move_alloc.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -116,5 +117,97 @@
 
         assert(c0.empty());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef int P;
+        typedef min_allocator<int> A;
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(std::move(c0), A());
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        C::const_iterator i = c.cbegin();
+        assert(*i == 4);
+        ++i;
+        assert(*i == 3);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 2);
+        ++i;
+        assert(*i == 1);
+        ++i;
+        assert(*i == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+    {
+        typedef int P;
+        typedef min_allocator<int> A;
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   A
+                                   > C;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c0(a, a + sizeof(a)/sizeof(a[0]),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            A()
+           );
+        C c(std::move(c0), A());
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == A());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+
+        assert(c0.empty());
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp
index 92a5e98..1286eee 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range.pass.cpp
@@ -24,6 +24,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -59,4 +60,108 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])));
+        assert(c.bucket_count() >= 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef int T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_multiset<T, HF, Comp, A> C;
+        T arr[] =
+        {
+            T(1),
+            T(2),
+            T(3),
+            T(4),
+            T(1),
+            T(2)
+        };
+        A a(42);
+        C c(input_iterator<T*>(arr), input_iterator<T*>(arr + sizeof(arr)/sizeof(arr[0])), 12, a);
+        assert(c.bucket_count() >= 12);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef int T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_multiset<T, HF, Comp, A> C;
+        T arr[] =
+        {
+            T(1),
+            T(2),
+            T(3),
+            T(4),
+            T(1),
+            T(2)
+        };
+        HF hf(43);
+        A a(42);
+        C c(input_iterator<T*>(arr), input_iterator<T*>(arr + sizeof(arr)/sizeof(arr[0])), 16, hf, a);
+        assert(c.bucket_count() >= 16);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp
index 6d2aff6..5fa494b 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size.pass.cpp
@@ -24,6 +24,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -61,4 +62,40 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >());
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp
index fbec983..bace36a 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash.pass.cpp
@@ -25,6 +25,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -63,4 +64,41 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >());
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp
index c701875..a97750e 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal.pass.cpp
@@ -25,6 +25,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -64,4 +65,42 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp
index ba94ac4..41f2e27 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/range_size_hash_equal_allocator.pass.cpp
@@ -26,6 +26,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -66,4 +67,43 @@
         assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<int,
+                                   test_hash<std::hash<int> >,
+                                   test_compare<std::equal_to<int> >,
+                                   min_allocator<int>
+                                   > C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])),
+            7,
+            test_hash<std::hash<int> >(8),
+            test_compare<std::equal_to<int> >(9),
+            min_allocator<int>()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.size() == 6);
+        assert(c.count(1) == 2);
+        assert(c.count(2) == 2);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+        assert(c.hash_function() == test_hash<std::hash<int> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<int> >(9));
+        assert(c.get_allocator() == min_allocator<int>());
+        assert(!c.empty());
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp
index 11010e4..1916b6b 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.fail.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -42,4 +43,23 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c = 7;
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() == (min_allocator<NotConstructible>()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp
index afeedb4..4e99037 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -42,4 +43,23 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c(7);
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() == (min_allocator<NotConstructible>()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp
index bc5b49a..19f4440 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -44,4 +45,25 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() == (min_allocator<NotConstructible>()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp
index 106775f..59eba53 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -45,4 +46,26 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8),
+            test_compare<std::equal_to<NotConstructible> >(9)
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9));
+        assert(c.get_allocator() == (min_allocator<NotConstructible>()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp
index b90044d..ca71ab3 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_equal_allocator.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -46,4 +47,27 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_multiset<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c(7,
+            test_hash<std::hash<NotConstructible> >(8),
+            test_compare<std::equal_to<NotConstructible> >(9),
+            min_allocator<std::pair<const NotConstructible, NotConstructible> >()
+           );
+        assert(c.bucket_count() == 7);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >(8));
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >(9));
+        assert(c.get_allocator() == (min_allocator<NotConstructible>()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp
new file mode 100644
index 0000000..9470b1a
--- /dev/null
+++ b/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+//           class Alloc = allocator<Value>>
+// class unordered_multiset
+
+// void swap(unordered_multiset& x, unordered_multiset& y);
+
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
+#include <unordered_set>
+#include <cassert>
+
+int main()
+{
+#if _LIBCPP_DEBUG >= 1
+    {
+        int a1[] = {1, 3, 7, 9, 10};
+        int a2[] = {0, 2, 4, 5, 6, 8, 11};
+        std::unordered_multiset<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::unordered_multiset<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        std::unordered_multiset<int>::iterator i1 = c1.begin();
+        std::unordered_multiset<int>::iterator i2 = c2.begin();
+        swap(c1, c2);
+        c1.erase(i2);
+        c2.erase(i1);
+        std::unordered_multiset<int>::iterator j = i1;
+        c1.erase(i1);
+        assert(false);
+    }
+#endif
+}
diff --git a/test/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp b/test/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp
index f56e247..b75816a 100644
--- a/test/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp
+++ b/test/containers/unord/unord.multiset/unord.multiset.swap/swap_non_member.pass.cpp
@@ -21,6 +21,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -385,4 +386,186 @@
         assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
         assert(c2.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a2[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(*c1.find(10) == 10);
+        assert(*c1.find(20) == 20);
+        assert(*c1.find(30) == 30);
+        assert(*c1.find(40) == 40);
+        assert(*c1.find(50) == 50);
+        assert(*c1.find(60) == 60);
+        assert(*c1.find(70) == 70);
+        assert(*c1.find(80) == 80);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a1[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.count(1) == 2);
+        assert(c2.count(2) == 2);
+        assert(c2.count(3) == 1);
+        assert(c2.count(4) == 1);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_multiset<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a1[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        P a2[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        swap(c1, c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(*c1.find(10) == 10);
+        assert(*c1.find(20) == 20);
+        assert(*c1.find(30) == 30);
+        assert(*c1.find(40) == 40);
+        assert(*c1.find(50) == 50);
+        assert(*c1.find(60) == 60);
+        assert(*c1.find(70) == 70);
+        assert(*c1.find(80) == 80);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 7);
+        assert(c2.size() == 6);
+        assert(c2.count(1) == 2);
+        assert(c2.count(2) == 2);
+        assert(c2.count(3) == 1);
+        assert(c2.count(4) == 1);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/bucket.pass.cpp b/test/containers/unord/unord.set/bucket.pass.cpp
index bdbd523..b2bf2e1 100644
--- a/test/containers/unord/unord.set/bucket.pass.cpp
+++ b/test/containers/unord/unord.set/bucket.pass.cpp
@@ -15,9 +15,15 @@
 
 // size_type bucket(const key_type& __k) const;
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -38,4 +44,32 @@
         for (size_t i = 0; i < 13; ++i)
             assert(c.bucket(i) == i % bc);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(std::begin(a), std::end(a));
+        size_t bc = c.bucket_count();
+        assert(bc >= 5);
+        for (size_t i = 0; i < 13; ++i)
+            assert(c.bucket(i) == i % bc);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_set<int> C;
+        C c;
+        C::size_type i = c.bucket(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/bucket_count.pass.cpp b/test/containers/unord/unord.set/bucket_count.pass.cpp
index 5cfc71d..649aaa1 100644
--- a/test/containers/unord/unord.set/bucket_count.pass.cpp
+++ b/test/containers/unord/unord.set/bucket_count.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -45,4 +47,31 @@
         const C c(std::begin(a), std::end(a));
         assert(c.bucket_count() >= 11);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef C::const_iterator I;
+        typedef int P;
+        const C c;
+        assert(c.bucket_count() == 0);
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef C::const_iterator I;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.bucket_count() >= 11);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/bucket_size.pass.cpp b/test/containers/unord/unord.set/bucket_size.pass.cpp
index 3c0f120..26f05db 100644
--- a/test/containers/unord/unord.set/bucket_size.pass.cpp
+++ b/test/containers/unord/unord.set/bucket_size.pass.cpp
@@ -15,9 +15,15 @@
 
 // size_type bucket_size(size_type n) const
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -40,4 +46,34 @@
         assert(c.bucket_size(3) == 1);
         assert(c.bucket_size(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.bucket_count() >= 5);
+        assert(c.bucket_size(0) == 0);
+        assert(c.bucket_size(1) == 1);
+        assert(c.bucket_size(2) == 1);
+        assert(c.bucket_size(3) == 1);
+        assert(c.bucket_size(4) == 1);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_set<int> C;
+        C c;
+        C::size_type i = c.bucket_size(3);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/clear.pass.cpp b/test/containers/unord/unord.set/clear.pass.cpp
index 3052087..1f97ab7 100644
--- a/test/containers/unord/unord.set/clear.pass.cpp
+++ b/test/containers/unord/unord.set/clear.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -36,4 +38,22 @@
         c.clear();
         assert(c.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        c.clear();
+        assert(c.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/count.pass.cpp b/test/containers/unord/unord.set/count.pass.cpp
index bbd02d6..d850a7e 100644
--- a/test/containers/unord/unord.set/count.pass.cpp
+++ b/test/containers/unord/unord.set/count.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -41,4 +43,27 @@
         assert(c.count(50) == 1);
         assert(c.count(5) == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(c.count(30) == 1);
+        assert(c.count(50) == 1);
+        assert(c.count(5) == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/db_iterators_7.pass.cpp b/test/containers/unord/unord.set/db_iterators_7.pass.cpp
new file mode 100644
index 0000000..3247f01
--- /dev/null
+++ b/test/containers/unord/unord.set/db_iterators_7.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_set<T> C;
+    C c(1);
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_set<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.set/db_iterators_8.pass.cpp b/test/containers/unord/unord.set/db_iterators_8.pass.cpp
new file mode 100644
index 0000000..4ee8883
--- /dev/null
+++ b/test/containers/unord/unord.set/db_iterators_8.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_set<T> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_set<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.set/db_local_iterators_7.pass.cpp b/test/containers/unord/unord.set/db_local_iterators_7.pass.cpp
new file mode 100644
index 0000000..e6df2a4
--- /dev/null
+++ b/test/containers/unord/unord.set/db_local_iterators_7.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment local_iterator past end.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_set<T> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_set<T, min_allocator<T>> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#endif
+
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.set/db_local_iterators_8.pass.cpp b/test/containers/unord/unord.set/db_local_iterators_8.pass.cpp
new file mode 100644
index 0000000..0c5a167
--- /dev/null
+++ b/test/containers/unord/unord.set/db_local_iterators_8.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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_set<T> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    T j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_set<T, min_allocator<T>> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    T j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.set/emplace.pass.cpp b/test/containers/unord/unord.set/emplace.pass.cpp
index 70ffeb9..a6faecb 100644
--- a/test/containers/unord/unord.set/emplace.pass.cpp
+++ b/test/containers/unord/unord.set/emplace.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "../../Emplaceable.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -43,5 +44,27 @@
         assert(*r.first == Emplaceable(5, 6));
         assert(!r.second);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<Emplaceable, std::hash<Emplaceable>,
+                      std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C;
+        typedef std::pair<C::iterator, bool> R;
+        C c;
+        R r = c.emplace();
+        assert(c.size() == 1);
+        assert(*r.first == Emplaceable());
+        assert(r.second);
+
+        r = c.emplace(Emplaceable(5, 6));
+        assert(c.size() == 2);
+        assert(*r.first == Emplaceable(5, 6));
+        assert(r.second);
+
+        r = c.emplace(5, 6);
+        assert(c.size() == 2);
+        assert(*r.first == Emplaceable(5, 6));
+        assert(!r.second);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.set/emplace_hint.pass.cpp b/test/containers/unord/unord.set/emplace_hint.pass.cpp
index 59cf445..0d8a57a 100644
--- a/test/containers/unord/unord.set/emplace_hint.pass.cpp
+++ b/test/containers/unord/unord.set/emplace_hint.pass.cpp
@@ -16,10 +16,15 @@
 // template <class... Args>
 //     iterator emplace_hint(const_iterator p, Args&&... args);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
 #include "../../Emplaceable.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -41,5 +46,35 @@
         assert(c.size() == 2);
         assert(*r == Emplaceable(5, 6));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<Emplaceable, std::hash<Emplaceable>,
+                      std::equal_to<Emplaceable>, min_allocator<Emplaceable>> C;
+        typedef C::iterator R;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.emplace_hint(e);
+        assert(c.size() == 1);
+        assert(*r == Emplaceable());
+
+        r = c.emplace_hint(e, Emplaceable(5, 6));
+        assert(c.size() == 2);
+        assert(*r == Emplaceable(5, 6));
+
+        r = c.emplace_hint(r, 5, 6);
+        assert(c.size() == 2);
+        assert(*r == Emplaceable(5, 6));
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_set<Emplaceable> C;
+        typedef C::iterator R;
+        C c1;
+        C c2;
+        R r = c1.emplace_hint(c2.begin(), 5, 6);
+        assert(false);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }
diff --git a/test/containers/unord/unord.set/eq.pass.cpp b/test/containers/unord/unord.set/eq.pass.cpp
index 52d8304..7b5569e 100644
--- a/test/containers/unord/unord.set/eq.pass.cpp
+++ b/test/containers/unord/unord.set/eq.pass.cpp
@@ -22,6 +22,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -88,4 +90,70 @@
         assert( (c1 == c2));
         assert(!(c1 != c2));
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2;
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c1(std::begin(a), std::end(a));
+        const C c2 = c1;
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(std::begin(a), std::end(a));
+        C c2 = c1;
+        c2.rehash(30);
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+        c2.insert(P(90));
+        assert(!(c1 == c2));
+        assert( (c1 != c2));
+        c1.insert(P(90));
+        assert( (c1 == c2));
+        assert(!(c1 != c2));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/equal_range_const.pass.cpp b/test/containers/unord/unord.set/equal_range_const.pass.cpp
index 98e4885..c64e0af 100644
--- a/test/containers/unord/unord.set/equal_range_const.pass.cpp
+++ b/test/containers/unord/unord.set/equal_range_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -47,4 +49,33 @@
         assert(std::distance(r.first, r.second) == 1);
         assert(*r.first == 50);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef C::const_iterator I;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(*r.first == 30);
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+        r = c.equal_range(50);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(*r.first == 50);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/equal_range_non_const.pass.cpp b/test/containers/unord/unord.set/equal_range_non_const.pass.cpp
index ba7ba0d..6d7e044 100644
--- a/test/containers/unord/unord.set/equal_range_non_const.pass.cpp
+++ b/test/containers/unord/unord.set/equal_range_non_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -47,4 +49,33 @@
         assert(std::distance(r.first, r.second) == 1);
         assert(*r.first == 50);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef C::iterator I;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(50),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c(std::begin(a), std::end(a));
+        std::pair<I, I> r = c.equal_range(30);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(*r.first == 30);
+        r = c.equal_range(5);
+        assert(std::distance(r.first, r.second) == 0);
+        r = c.equal_range(50);
+        assert(std::distance(r.first, r.second) == 1);
+        assert(*r.first == 50);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/erase_const_iter.pass.cpp b/test/containers/unord/unord.set/erase_const_iter.pass.cpp
index a6038a4..ff74601 100644
--- a/test/containers/unord/unord.set/erase_const_iter.pass.cpp
+++ b/test/containers/unord/unord.set/erase_const_iter.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -40,4 +42,26 @@
         assert(c.count(3) == 1);
         assert(c.count(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::iterator j = c.erase(i);
+        assert(c.size() == 3);
+        assert(c.count(1) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+    }
+#endif
 }
diff --git a/test/containers/sequences/list/db_iterators_1.pass.cpp b/test/containers/unord/unord.set/erase_iter_db1.pass.cpp
similarity index 64%
rename from test/containers/sequences/list/db_iterators_1.pass.cpp
rename to test/containers/unord/unord.set/erase_iter_db1.pass.cpp
index 7038ed4..231152d 100644
--- a/test/containers/sequences/list/db_iterators_1.pass.cpp
+++ b/test/containers/unord/unord.set/erase_iter_db1.pass.cpp
@@ -7,28 +7,26 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <list>
+// <unordered_set>
 
-// Compare iterators from different containers with == or !=.
+// Call erase(const_iterator position) with end()
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
-#include <list>
+#include <unordered_set>
 #include <cassert>
-#include <iterator>
-#include <exception>
-#include <cstdlib>
 
 int main()
 {
-    typedef int T;
-    typedef std::list<T> C;
-    C c1;
-    C c2;
-    bool b = c1.begin() != c2.begin();
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_set<int> l1(a1, a1+3);
+    std::unordered_set<int>::const_iterator i = l1.end();
+    l1.erase(i);
     assert(false);
+    }
 }
 
 #else
diff --git a/test/containers/sequences/vector/db_iterators_1.pass.cpp b/test/containers/unord/unord.set/erase_iter_db2.pass.cpp
similarity index 61%
copy from test/containers/sequences/vector/db_iterators_1.pass.cpp
copy to test/containers/unord/unord.set/erase_iter_db2.pass.cpp
index fbcb40f..06d61db 100644
--- a/test/containers/sequences/vector/db_iterators_1.pass.cpp
+++ b/test/containers/unord/unord.set/erase_iter_db2.pass.cpp
@@ -7,28 +7,29 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_set>
 
-// Compare iterators from different containers with == or !=.
+// Call erase(const_iterator position) with iterator from another container
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
-#include <vector>
+#include <unordered_set>
 #include <cassert>
-#include <iterator>
-#include <exception>
 #include <cstdlib>
+#include <exception>
 
 int main()
 {
-    typedef int T;
-    typedef std::vector<T> C;
-    C c1;
-    C c2;
-    bool b = c1.begin() != c2.begin();
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_set<int> l1(a1, a1+3);
+    std::unordered_set<int> l2(a1, a1+3);
+    std::unordered_set<int>::const_iterator i = l2.begin();
+    l1.erase(i);
     assert(false);
+    }
 }
 
 #else
diff --git a/test/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp
new file mode 100644
index 0000000..92c77f5
--- /dev/null
+++ b/test/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with first iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_set<int> l1(a1, a1+3);
+    std::unordered_set<int> l2(a1, a1+3);
+    std::unordered_set<int>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp
new file mode 100644
index 0000000..d606658
--- /dev/null
+++ b/test/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with second iterator from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_set<int> l1(a1, a1+3);
+    std::unordered_set<int> l2(a1, a1+3);
+    std::unordered_set<int>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp
new file mode 100644
index 0000000..f7ff426
--- /dev/null
+++ b/test/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator first, const_iterator last); with both iterators from another container
+
+#if _LIBCPP_DEBUG >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_set<int> l1(a1, a1+3);
+    std::unordered_set<int> l2(a1, a1+3);
+    std::unordered_set<int>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif
diff --git a/test/containers/sequences/vector/db_iterators_1.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp
similarity index 63%
copy from test/containers/sequences/vector/db_iterators_1.pass.cpp
copy to test/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp
index fbcb40f..6cde216 100644
--- a/test/containers/sequences/vector/db_iterators_1.pass.cpp
+++ b/test/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp
@@ -7,28 +7,27 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <vector>
+// <unordered_set>
 
-// Compare iterators from different containers with == or !=.
+// Call erase(const_iterator first, const_iterator last); with a bad range
 
-#if _LIBCPP_DEBUG2 >= 1
+#if _LIBCPP_DEBUG >= 1
 
 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
 
-#include <vector>
+#include <unordered_set>
 #include <cassert>
-#include <iterator>
 #include <exception>
 #include <cstdlib>
 
 int main()
 {
-    typedef int T;
-    typedef std::vector<T> C;
-    C c1;
-    C c2;
-    bool b = c1.begin() != c2.begin();
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_set<int> l1(a1, a1+3);
+    std::unordered_set<int>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin());
     assert(false);
+    }
 }
 
 #else
diff --git a/test/containers/unord/unord.set/erase_key.pass.cpp b/test/containers/unord/unord.set/erase_key.pass.cpp
index c4483ec..187f118 100644
--- a/test/containers/unord/unord.set/erase_key.pass.cpp
+++ b/test/containers/unord/unord.set/erase_key.pass.cpp
@@ -19,6 +19,8 @@
 #include <string>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -77,4 +79,62 @@
         assert(c.erase(3) == 0);
         assert(c.size() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.erase(5) == 0);
+        assert(c.size() == 4);
+        assert(c.count(1) == 1);
+        assert(c.count(2) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        assert(c.erase(2) == 1);
+        assert(c.size() == 3);
+        assert(c.count(1) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        assert(c.erase(2) == 0);
+        assert(c.size() == 3);
+        assert(c.count(1) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        assert(c.erase(4) == 1);
+        assert(c.size() == 2);
+        assert(c.count(1) == 1);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(4) == 0);
+        assert(c.size() == 2);
+        assert(c.count(1) == 1);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(1) == 1);
+        assert(c.size() == 1);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(1) == 0);
+        assert(c.size() == 1);
+        assert(c.count(3) == 1);
+
+        assert(c.erase(3) == 1);
+        assert(c.size() == 0);
+
+        assert(c.erase(3) == 0);
+        assert(c.size() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/erase_range.pass.cpp b/test/containers/unord/unord.set/erase_range.pass.cpp
index ba51efa..98b7d4d 100644
--- a/test/containers/unord/unord.set/erase_range.pass.cpp
+++ b/test/containers/unord/unord.set/erase_range.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -53,4 +55,39 @@
         assert(c.size() == 0);
         assert(k == c.end());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C::const_iterator i = c.find(2);
+        C::const_iterator j = next(i);
+        C::iterator k = c.erase(i, i);
+        assert(k == i);
+        assert(c.size() == 4);
+        assert(c.count(1) == 1);
+        assert(c.count(2) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        k = c.erase(i, j);
+        assert(c.size() == 3);
+        assert(c.count(1) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+
+        k = c.erase(c.cbegin(), c.cend());
+        assert(c.size() == 0);
+        assert(k == c.end());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/find_const.pass.cpp b/test/containers/unord/unord.set/find_const.pass.cpp
index 80dca54..ca8b9e6 100644
--- a/test/containers/unord/unord.set/find_const.pass.cpp
+++ b/test/containers/unord/unord.set/find_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -40,4 +42,26 @@
         i = c.find(5);
         assert(i == c.cend());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        C::const_iterator i = c.find(30);
+        assert(*i == 30);
+        i = c.find(5);
+        assert(i == c.cend());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/find_non_const.pass.cpp b/test/containers/unord/unord.set/find_non_const.pass.cpp
index 8ff0fe4..a2ab804 100644
--- a/test/containers/unord/unord.set/find_non_const.pass.cpp
+++ b/test/containers/unord/unord.set/find_non_const.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -40,4 +42,26 @@
         i = c.find(5);
         assert(i == c.cend());
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>, std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c(std::begin(a), std::end(a));
+        C::iterator i = c.find(30);
+        assert(*i == 30);
+        i = c.find(5);
+        assert(i == c.cend());
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/insert_const_lvalue.pass.cpp b/test/containers/unord/unord.set/insert_const_lvalue.pass.cpp
index 36ee2cf..b5d2733 100644
--- a/test/containers/unord/unord.set/insert_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.set/insert_const_lvalue.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -45,4 +47,32 @@
         assert(*r.first == 5.5);
         assert(r.second);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef std::pair<C::iterator, bool> R;
+        typedef C::value_type P;
+        C c;
+        R r = c.insert(P(3.5));
+        assert(c.size() == 1);
+        assert(*r.first == 3.5);
+        assert(r.second);
+
+        r = c.insert(P(3.5));
+        assert(c.size() == 1);
+        assert(*r.first == 3.5);
+        assert(!r.second);
+
+        r = c.insert(P(4.5));
+        assert(c.size() == 2);
+        assert(*r.first == 4.5);
+        assert(r.second);
+
+        r = c.insert(P(5.5));
+        assert(c.size() == 3);
+        assert(*r.first == 5.5);
+        assert(r.second);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp b/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp
index 88b317a..c195e52 100644
--- a/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp
+++ b/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp
@@ -15,9 +15,15 @@
 
 // iterator insert(const_iterator p, const value_type& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -42,4 +48,42 @@
         assert(c.size() == 3);
         assert(*r == 5.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(e, P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(e, P(4.5));
+        assert(c.size() == 2);
+        assert(*r == 4.5);
+
+        r = c.insert(e, P(5.5));
+        assert(c.size() == 3);
+        assert(*r == 5.5);
+    }
+#endif
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_set<double> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        P v(3.5);
+        R r = c.insert(e, v);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp b/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp
index 3d79fbc..ff7d742 100644
--- a/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp
+++ b/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp
@@ -15,10 +15,15 @@
 
 // iterator insert(const_iterator p, value_type&& x);
 
+#if _LIBCPP_DEBUG >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -68,4 +73,66 @@
         assert(*r == 5);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef C::iterator R;
+        typedef double P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(r, P(3.5));
+        assert(c.size() == 1);
+        assert(*r == 3.5);
+
+        r = c.insert(e, P(4.5));
+        assert(c.size() == 2);
+        assert(*r == 4.5);
+
+        r = c.insert(e, P(5.5));
+        assert(c.size() == 3);
+        assert(*r == 5.5);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>,
+                            std::equal_to<MoveOnly>, min_allocator<MoveOnly>> C;
+        typedef C::iterator R;
+        typedef MoveOnly P;
+        C c;
+        C::const_iterator e = c.end();
+        R r = c.insert(e, P(3));
+        assert(c.size() == 1);
+        assert(*r == 3);
+
+        r = c.insert(r, P(3));
+        assert(c.size() == 1);
+        assert(*r == 3);
+
+        r = c.insert(e, P(4));
+        assert(c.size() == 2);
+        assert(*r == 4);
+
+        r = c.insert(e, P(5));
+        assert(c.size() == 3);
+        assert(*r == 5);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if _LIBCPP_DEBUG >= 1
+    {
+        typedef std::unordered_set<double> C;
+        typedef C::iterator R;
+        typedef C::value_type P;
+        C c;
+        C c2;
+        C::const_iterator e = c2.end();
+        R r = c.insert(e, P(3.5));
+        assert(false);
+    }
+#endif
+#endif
 }
diff --git a/test/containers/unord/unord.set/insert_init.pass.cpp b/test/containers/unord/unord.set/insert_init.pass.cpp
index 3b1abdf..18a97a1 100644
--- a/test/containers/unord/unord.set/insert_init.pass.cpp
+++ b/test/containers/unord/unord.set/insert_init.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -43,5 +44,28 @@
         assert(c.count(3) == 1);
         assert(c.count(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        C c;
+        c.insert(
+                    {
+                        P(1),
+                        P(2),
+                        P(3),
+                        P(4),
+                        P(1),
+                        P(2)
+                    }
+                );
+        assert(c.size() == 4);
+        assert(c.count(1) == 1);
+        assert(c.count(2) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }
diff --git a/test/containers/unord/unord.set/insert_range.pass.cpp b/test/containers/unord/unord.set/insert_range.pass.cpp
index b0b8fc6..aa3b38b 100644
--- a/test/containers/unord/unord.set/insert_range.pass.cpp
+++ b/test/containers/unord/unord.set/insert_range.pass.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 
 #include "test_iterators.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -43,4 +44,27 @@
         assert(c.count(3) == 1);
         assert(c.count(4) == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c;
+        c.insert(input_iterator<P*>(a), input_iterator<P*>(a + sizeof(a)/sizeof(a[0])));
+        assert(c.size() == 4);
+        assert(c.count(1) == 1);
+        assert(c.count(2) == 1);
+        assert(c.count(3) == 1);
+        assert(c.count(4) == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/insert_rvalue.pass.cpp b/test/containers/unord/unord.set/insert_rvalue.pass.cpp
index e3268f0..9ed2cda 100644
--- a/test/containers/unord/unord.set/insert_rvalue.pass.cpp
+++ b/test/containers/unord/unord.set/insert_rvalue.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 
 #include "../../MoveOnly.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -74,4 +75,60 @@
         assert(r.second);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<double, std::hash<double>,
+                                std::equal_to<double>, min_allocator<double>> C;
+        typedef std::pair<C::iterator, bool> R;
+        typedef double P;
+        C c;
+        R r = c.insert(P(3.5));
+        assert(c.size() == 1);
+        assert(*r.first == 3.5);
+        assert(r.second);
+
+        r = c.insert(P(3.5));
+        assert(c.size() == 1);
+        assert(*r.first == 3.5);
+        assert(!r.second);
+
+        r = c.insert(P(4.5));
+        assert(c.size() == 2);
+        assert(*r.first == 4.5);
+        assert(r.second);
+
+        r = c.insert(P(5.5));
+        assert(c.size() == 3);
+        assert(*r.first == 5.5);
+        assert(r.second);
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>,
+                            std::equal_to<MoveOnly>, min_allocator<MoveOnly>> C;
+        typedef std::pair<C::iterator, bool> R;
+        typedef MoveOnly P;
+        C c;
+        R r = c.insert(P(3));
+        assert(c.size() == 1);
+        assert(*r.first == 3);
+        assert(r.second);
+
+        r = c.insert(P(3));
+        assert(c.size() == 1);
+        assert(*r.first == 3);
+        assert(!r.second);
+
+        r = c.insert(P(4));
+        assert(c.size() == 2);
+        assert(*r.first == 4);
+        assert(r.second);
+
+        r = c.insert(P(5));
+        assert(c.size() == 3);
+        assert(*r.first == 5);
+        assert(r.second);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 }
diff --git a/test/containers/unord/unord.set/iterators.pass.cpp b/test/containers/unord/unord.set/iterators.pass.cpp
index ef1ecb9..7bb9770 100644
--- a/test/containers/unord/unord.set/iterators.pass.cpp
+++ b/test/containers/unord/unord.set/iterators.pass.cpp
@@ -23,6 +23,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -63,4 +65,60 @@
         assert(std::distance(c.cbegin(), c.cend()) == c.size());
         C::const_iterator i;
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        assert(c.size() == 4);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::iterator i;
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        assert(c.size() == 4);
+        assert(std::distance(c.begin(), c.end()) == c.size());
+        assert(std::distance(c.cbegin(), c.cend()) == c.size());
+        C::const_iterator i;
+    }
+#endif
+#if _LIBCPP_STD_VER > 11
+    { // N3644 testing
+        typedef std::unordered_set<int> C;
+        C::iterator ii1{}, ii2{};
+        C::iterator ii4 = ii1;
+        C::const_iterator cii{};
+        assert ( ii1 == ii2 );
+        assert ( ii1 == ii4 );
+        assert ( ii1 == cii );
+
+        assert ( !(ii1 != ii2 ));
+        assert ( !(ii1 != cii ));
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/load_factor.pass.cpp b/test/containers/unord/unord.set/load_factor.pass.cpp
index 60b0f91..959f384 100644
--- a/test/containers/unord/unord.set/load_factor.pass.cpp
+++ b/test/containers/unord/unord.set/load_factor.pass.cpp
@@ -19,6 +19,8 @@
 #include <cassert>
 #include <cfloat>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -44,4 +46,31 @@
         const C c;
         assert(c.load_factor() == 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        const C c(std::begin(a), std::end(a));
+        assert(fabs(c.load_factor() - (float)c.size()/c.bucket_count()) < FLT_EPSILON);
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        const C c;
+        assert(c.load_factor() == 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/local_iterators.pass.cpp b/test/containers/unord/unord.set/local_iterators.pass.cpp
index 93d7ea8..5b82228 100644
--- a/test/containers/unord/unord.set/local_iterators.pass.cpp
+++ b/test/containers/unord/unord.set/local_iterators.pass.cpp
@@ -23,6 +23,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -201,4 +203,186 @@
         assert(std::distance(i, j) == 1);
         assert(*i == 4);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.begin(b);
+        I j = c.end(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.begin(b);
+        j = c.end(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        typedef C::const_local_iterator I;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        const C c(a, a + sizeof(a)/sizeof(a[0]));
+        assert(c.bucket_count() >= 5);
+        C::size_type b = c.bucket(0);
+        I i = c.cbegin(b);
+        I j = c.cend(b);
+        assert(std::distance(i, j) == 0);
+
+        b = c.bucket(1);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 1);
+
+        b = c.bucket(2);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 2);
+
+        b = c.bucket(3);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 3);
+
+        b = c.bucket(4);
+        i = c.cbegin(b);
+        j = c.cend(b);
+        assert(std::distance(i, j) == 1);
+        assert(*i == 4);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/max_bucket_count.pass.cpp b/test/containers/unord/unord.set/max_bucket_count.pass.cpp
index ee36c56..80398b8 100644
--- a/test/containers/unord/unord.set/max_bucket_count.pass.cpp
+++ b/test/containers/unord/unord.set/max_bucket_count.pass.cpp
@@ -18,6 +18,8 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -25,4 +27,12 @@
         const C c;
         assert(c.max_bucket_count() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        const C c;
+        assert(c.max_bucket_count() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/max_load_factor.pass.cpp b/test/containers/unord/unord.set/max_load_factor.pass.cpp
index 6647037..982c6b5 100644
--- a/test/containers/unord/unord.set/max_load_factor.pass.cpp
+++ b/test/containers/unord/unord.set/max_load_factor.pass.cpp
@@ -16,9 +16,15 @@
 // float max_load_factor() const;
 // void max_load_factor(float mlf);
 
+#ifdef _LIBCPP_DEBUG
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -35,4 +41,30 @@
         c.max_load_factor(2.5);
         assert(c.max_load_factor() == 2.5);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        const C c;
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        C c;
+        assert(c.max_load_factor() == 1);
+        c.max_load_factor(2.5);
+        assert(c.max_load_factor() == 2.5);
+    }
+#endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_set<int> C;
+        C c;
+        c.max_load_factor(-0.5f);
+        assert(false);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/max_size.pass.cpp b/test/containers/unord/unord.set/max_size.pass.cpp
index 2c5d3be..43d66bb 100644
--- a/test/containers/unord/unord.set/max_size.pass.cpp
+++ b/test/containers/unord/unord.set/max_size.pass.cpp
@@ -18,10 +18,19 @@
 #include <unordered_set>
 #include <cassert>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
         std::unordered_set<int> u;
         assert(u.max_size() > 0);
     }
+#if __cplusplus >= 201103L
+    {
+        std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> u;
+        assert(u.max_size() > 0);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/rehash.pass.cpp b/test/containers/unord/unord.set/rehash.pass.cpp
index ae962c9..bf4d317 100644
--- a/test/containers/unord/unord.set/rehash.pass.cpp
+++ b/test/containers/unord/unord.set/rehash.pass.cpp
@@ -18,7 +18,10 @@
 #include <unordered_set>
 #include <cassert>
 
-void test(const std::unordered_set<int>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
     assert(c.size() == 4);
     assert(c.count(1) == 1);
@@ -55,4 +58,33 @@
         assert(c.bucket_count() == 31);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 5);
+        c.rehash(3);
+        assert(c.bucket_count() == 5);
+        test(c);
+        c.max_load_factor(2);
+        c.rehash(3);
+        assert(c.bucket_count() == 3);
+        test(c);
+        c.rehash(31);
+        assert(c.bucket_count() == 31);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/reserve.pass.cpp b/test/containers/unord/unord.set/reserve.pass.cpp
index 7950774..525f943 100644
--- a/test/containers/unord/unord.set/reserve.pass.cpp
+++ b/test/containers/unord/unord.set/reserve.pass.cpp
@@ -18,7 +18,10 @@
 #include <unordered_set>
 #include <cassert>
 
-void test(const std::unordered_set<int>& c)
+#include "../../min_allocator.h"
+
+template <class C>
+void test(const C& c)
 {
     assert(c.size() == 4);
     assert(c.count(1) == 1);
@@ -55,4 +58,33 @@
         assert(c.bucket_count() >= 16);
         test(c);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<int, std::hash<int>,
+                                      std::equal_to<int>, min_allocator<int>> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        test(c);
+        assert(c.bucket_count() >= 5);
+        c.reserve(3);
+        assert(c.bucket_count() == 5);
+        test(c);
+        c.max_load_factor(2);
+        c.reserve(3);
+        assert(c.bucket_count() >= 2);
+        test(c);
+        c.reserve(31);
+        assert(c.bucket_count() >= 16);
+        test(c);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/swap_member.pass.cpp b/test/containers/unord/unord.set/swap_member.pass.cpp
index 3d90362..9a972b7 100644
--- a/test/containers/unord/unord.set/swap_member.pass.cpp
+++ b/test/containers/unord/unord.set/swap_member.pass.cpp
@@ -21,6 +21,7 @@
 #include "../../test_compare.h"
 #include "../../test_hash.h"
 #include "../../test_allocator.h"
+#include "../../min_allocator.h"
 
 int main()
 {
@@ -385,4 +386,186 @@
         assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
         assert(c2.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_set<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_set<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a2[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(*c1.find(10) == 10);
+        assert(*c1.find(20) == 20);
+        assert(*c1.find(30) == 30);
+        assert(*c1.find(40) == 40);
+        assert(*c1.find(50) == 50);
+        assert(*c1.find(60) == 60);
+        assert(*c1.find(70) == 70);
+        assert(*c1.find(80) == 80);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() == 0);
+        assert(c2.size() == 0);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_set<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a1[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() == 0);
+        assert(c1.size() == 0);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 5);
+        assert(c2.size() == 4);
+        assert(c2.count(1) == 1);
+        assert(c2.count(2) == 1);
+        assert(c2.count(3) == 1);
+        assert(c2.count(4) == 1);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+    {
+        typedef test_hash<std::hash<int> > Hash;
+        typedef test_compare<std::equal_to<int> > Compare;
+        typedef min_allocator<int> Alloc;
+        typedef std::unordered_set<int, Hash, Compare, Alloc> C;
+        typedef int P;
+        P a1[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        P a2[] =
+        {
+            P(10),
+            P(20),
+            P(30),
+            P(40),
+            P(50),
+            P(60),
+            P(70),
+            P(80)
+        };
+        C c1(std::begin(a1), std::end(a1), 0, Hash(1), Compare(1), Alloc());
+        C c2(std::begin(a2), std::end(a2), 0, Hash(2), Compare(2), Alloc());
+        c2.max_load_factor(2);
+        c1.swap(c2);
+
+        assert(c1.bucket_count() >= 11);
+        assert(c1.size() == 8);
+        assert(*c1.find(10) == 10);
+        assert(*c1.find(20) == 20);
+        assert(*c1.find(30) == 30);
+        assert(*c1.find(40) == 40);
+        assert(*c1.find(50) == 50);
+        assert(*c1.find(60) == 60);
+        assert(*c1.find(70) == 70);
+        assert(*c1.find(80) == 80);
+        assert(c1.hash_function() == Hash(2));
+        assert(c1.key_eq() == Compare(2));
+        assert(c1.get_allocator() == Alloc());
+        assert(std::distance(c1.begin(), c1.end()) == c1.size());
+        assert(std::distance(c1.cbegin(), c1.cend()) == c1.size());
+        assert(c1.max_load_factor() == 2);
+
+        assert(c2.bucket_count() >= 5);
+        assert(c2.size() == 4);
+        assert(c2.count(1) == 1);
+        assert(c2.count(2) == 1);
+        assert(c2.count(3) == 1);
+        assert(c2.count(4) == 1);
+        assert(c2.hash_function() == Hash(1));
+        assert(c2.key_eq() == Compare(1));
+        assert(c2.get_allocator() == Alloc());
+        assert(std::distance(c2.begin(), c2.end()) == c2.size());
+        assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
+        assert(c2.max_load_factor() == 1);
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/types.pass.cpp b/test/containers/unord/unord.set/types.pass.cpp
index a69eb0a..11d992f 100644
--- a/test/containers/unord/unord.set/types.pass.cpp
+++ b/test/containers/unord/unord.set/types.pass.cpp
@@ -30,6 +30,8 @@
 #include <unordered_set>
 #include <type_traits>
 
+#include "../../min_allocator.h"
+
 int main()
 {
     {
@@ -46,4 +48,21 @@
         static_assert((std::is_same<C::size_type, std::size_t>::value), "");
         static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<short, std::hash<short>,
+                                  std::equal_to<short>, min_allocator<short>> C;
+        static_assert((std::is_same<C::value_type, short>::value), "");
+        static_assert((std::is_same<C::key_type, short>::value), "");
+        static_assert((std::is_same<C::hasher, std::hash<C::key_type> >::value), "");
+        static_assert((std::is_same<C::key_equal, std::equal_to<C::key_type> >::value), "");
+        static_assert((std::is_same<C::allocator_type, min_allocator<C::value_type> >::value), "");
+        static_assert((std::is_same<C::reference, C::value_type&>::value), "");
+        static_assert((std::is_same<C::const_reference, const C::value_type&>::value), "");
+        static_assert((std::is_same<C::pointer, min_pointer<C::value_type>>::value), "");
+        static_assert((std::is_same<C::const_pointer, min_pointer<const C::value_type>>::value), "");
+        static_assert((std::is_same<C::size_type, std::size_t>::value), "");
+        static_assert((std::is_same<C::difference_type, std::ptrdiff_t>::value), "");
+    }
+#endif
 }
diff --git a/test/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp b/test/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp
index a5e2368..5d7897b 100644
--- a/test/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp
+++ b/test/containers/unord/unord.set/unord.set.cnstr/allocator.pass.cpp
@@ -22,6 +22,7 @@
 #include "../../../test_compare.h"
 #include "../../../test_hash.h"
 #include "../../../test_allocator.h"
+#include "../../../min_allocator.h"
 
 int main()
 {
@@ -42,4 +43,67 @@
         assert(c.load_factor() == 0);
         assert(c.max_load_factor() == 1);
     }
+#if __cplusplus >= 201103L
+    {
+        typedef std::unordered_set<NotConstructible,
+                                   test_hash<std::hash<NotConstructible> >,
+                                   test_compare<std::equal_to<NotConstructible> >,
+                                   min_allocator<NotConstructible>
+                                   > C;
+        C c(min_allocator<NotConstructible>{});
+        assert(c.bucket_count() == 0);
+        assert(c.hash_function() == test_hash<std::hash<NotConstructible> >());
+        assert(c.key_eq() == test_compare<std::equal_to<NotConstructible> >());
+        assert(c.get_allocator() == min_allocator<NotConstructible>());
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+#if _LIBCPP_STD_VER > 11
+    {
+        typedef NotConstructible T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_set<T, HF, Comp, A> C;
+
+        A a(43);
+        C c(3, a);
+        assert(c.bucket_count() == 3);
+        assert(c.hash_function() == HF());
+        assert(c.key_eq() == Comp ());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_factor() == 0);
+        assert(c.max_load_factor() == 1);
+    }
+    {
+        typedef NotConstructible T;
+        typedef test_hash<std::hash<T>> HF;
+        typedef test_compare<std::equal_to<T>> Comp;
+        typedef test_allocator<T> A;
+        typedef std::unordered_set<T, HF, Comp, A> C;
+
+        HF hf(42);
+        A a(43);
+        C c(4, hf, a);
+        assert(c.bucket_count() == 4);
+        assert(c.hash_function() == hf);
+        assert(!(c.hash_function() == HF()));
+        assert(c.key_eq() == Comp ());
+        assert(c.get_allocator() == a);
+        assert(!(c.get_allocator() == A()));
+        assert(c.size() == 0);
+        assert(c.empty());
+        assert(std::distance(c.begin(), c.end()) == 0);
+        assert(c.load_facto