libcxx initial import

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@103490 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
new file mode 100644
index 0000000..9f37e7f
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp
@@ -0,0 +1,112 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// template <class OuterA2>
+//   scoped_allocator_adaptor(OuterA2&& outerAlloc,
+//                            const InnerAllocs& ...innerAllocs);
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A1<int> a3(3);
+        A a(a3);
+        assert(a.outer_allocator() == A1<int>(3));
+        assert(a.inner_allocator() == a);
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+    }
+    A1<int>::copy_called = false;
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a(A1<int>(3));
+        assert(a.outer_allocator() == A1<int>(3));
+        assert(a.inner_allocator() == a);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+    }
+    A1<int>::move_called = false;
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A1<int> a4(4);
+        A a(a4, A2<int>(5));
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(a.outer_allocator() == A1<int>(4));
+        assert(a.inner_allocator() == std::scoped_allocator_adaptor<A2<int>>(A2<int>(5)));
+    }
+    A1<int>::copy_called = false;
+    A1<int>::move_called = false;
+    A2<int>::copy_called = false;
+    A2<int>::move_called = false;
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a(A1<int>(4), A2<int>(5));
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(a.outer_allocator() == A1<int>(4));
+        assert(a.inner_allocator() == std::scoped_allocator_adaptor<A2<int>>(A2<int>(5)));
+    }
+    A1<int>::copy_called = false;
+    A1<int>::move_called = false;
+    A2<int>::copy_called = false;
+    A2<int>::move_called = false;
+    A1<int>::move_called = false;
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A1<int> a4(4);
+        A a(a4, A2<int>(5), A3<int>(6));
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(A3<int>::copy_called == true);
+        assert(A3<int>::move_called == false);
+        assert(a.outer_allocator() == A1<int>(4));
+        assert((a.inner_allocator() ==
+            std::scoped_allocator_adaptor<A2<int>, A3<int>>(A2<int>(5), A3<int>(6))));
+    }
+    A1<int>::copy_called = false;
+    A1<int>::move_called = false;
+    A2<int>::copy_called = false;
+    A2<int>::move_called = false;
+    A3<int>::copy_called = false;
+    A3<int>::move_called = false;
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a(A1<int>(4), A2<int>(5), A3<int>(6));
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(A3<int>::copy_called == true);
+        assert(A3<int>::move_called == false);
+        assert(a.outer_allocator() == A1<int>(4));
+        assert((a.inner_allocator() ==
+            std::scoped_allocator_adaptor<A2<int>, A3<int>>(A2<int>(5), A3<int>(6))));
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp
new file mode 100644
index 0000000..de8e3ff
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/converting_copy.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// template <class OuterA2>
+//   scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2,
+//                                                           InnerAllocs...>& other);
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<double>> B;
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        B a1(A1<int>(3));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A a2 = a1;
+        assert(A1<int>::copy_called == true);
+        assert(a2 == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<double>, A2<int>> B;
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        B a1(A1<int>(4), A2<int>(5));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A a2 = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A2<int>::copy_called == true);
+        assert(a2 == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<double>, A2<int>, A3<int>> B;
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        B a1(A1<int>(4), A2<int>(5), A3<int>(6));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A3<int>::copy_called = false;
+        A3<int>::move_called = false;
+        A a2 = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A2<int>::copy_called == true);
+        assert(A3<int>::copy_called == true);
+        assert(a2 == a1);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp
new file mode 100644
index 0000000..533c01c
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/converting_move.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// template <class OuterA2>
+//   scoped_allocator_adaptor(scoped_allocator_adaptor<OuterA2,
+//                                                     InnerAllocs...>&& other);
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<double>> B;
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        B a1(A1<int>(3));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A a2 = std::move(a1);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(a2 == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<double>, A2<int>> B;
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        B a1(A1<int>(4), A2<int>(5));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A a2 = std::move(a1);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(A2<int>::copy_called == false);
+        assert(A2<int>::move_called == true);
+        assert(a2 == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<double>, A2<int>, A3<int>> B;
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        B a1(A1<int>(4), A2<int>(5), A3<int>(6));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A3<int>::copy_called = false;
+        A3<int>::move_called = false;
+        A a2 = std::move(a1);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == true);
+        assert(A2<int>::copy_called == false);
+        assert(A2<int>::move_called == true);
+        assert(A3<int>::copy_called == false);
+        assert(A3<int>::move_called == true);
+        assert(a2 == a1);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp
new file mode 100644
index 0000000..02397ce
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/copy.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// scoped_allocator_adaptor(const scoped_allocator_adaptor& other);
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a1(A1<int>(3));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A a2 = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(a2 == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a1(A1<int>(4), A2<int>(5));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A a2 = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(a2 == a1);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a1(A1<int>(4), A2<int>(5), A3<int>(6));
+        A1<int>::copy_called = false;
+        A1<int>::move_called = false;
+        A2<int>::copy_called = false;
+        A2<int>::move_called = false;
+        A3<int>::copy_called = false;
+        A3<int>::move_called = false;
+        A a2 = a1;
+        assert(A1<int>::copy_called == true);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == true);
+        assert(A2<int>::move_called == false);
+        assert(A3<int>::copy_called == true);
+        assert(A3<int>::move_called == false);
+        assert(a2 == a1);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp
new file mode 100644
index 0000000..770f68a
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.cnstr/default.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// scoped_allocator_adaptor();
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a;
+        assert(a.outer_allocator() == A1<int>());
+        assert(a.inner_allocator() == a);
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == false);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a;
+        assert(a.outer_allocator() == A1<int>());
+        assert(a.inner_allocator() == std::scoped_allocator_adaptor<A2<int>>());
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == false);
+        assert(A2<int>::move_called == false);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a;
+        assert(a.outer_allocator() == A1<int>());
+        assert((a.inner_allocator() == std::scoped_allocator_adaptor<A2<int>, A3<int>>()));
+        assert(A1<int>::copy_called == false);
+        assert(A1<int>::move_called == false);
+        assert(A2<int>::copy_called == false);
+        assert(A2<int>::move_called == false);
+        assert(A3<int>::copy_called == false);
+        assert(A3<int>::move_called == false);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp
new file mode 100644
index 0000000..c413df6
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/allocate_size.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// pointer allocate(size_type n);
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a;
+        A1<int>::allocate_called = false;
+        assert(a.allocate(10) == (int*)10);
+        assert(A1<int>::allocate_called == true);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a;
+        A1<int>::allocate_called = false;
+        assert(a.allocate(10) == (int*)10);
+        assert(A1<int>::allocate_called == true);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a;
+        A1<int>::allocate_called = false;
+        assert(a.allocate(10) == (int*)10);
+        assert(A1<int>::allocate_called == true);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp
new file mode 100644
index 0000000..711d6df
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/allocate_size_hint.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// pointer allocate(size_type n, const_void_pointer hint);
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a;
+        A1<int>::allocate_called = false;
+        assert(a.allocate(10, (const void*)0) == (int*)10);
+        assert(A1<int>::allocate_called == true);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a;
+        A1<int>::allocate_called = false;
+        assert(a.allocate(10, (const void*)10) == (int*)10);
+        assert(A1<int>::allocate_called == true);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a;
+        A1<int>::allocate_called = false;
+        assert(a.allocate(10, (const void*)20) == (int*)10);
+        assert(A1<int>::allocate_called == true);
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A2<int>> A;
+        A a;
+        A2<int>::allocate_called = false;
+        assert(a.allocate(10, (const void*)0) == (int*)0);
+        assert(A2<int>::allocate_called == true);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A2<int>, A2<int>> A;
+        A a;
+        A2<int>::allocate_called = false;
+        assert(a.allocate(10, (const void*)10) == (int*)10);
+        assert(A2<int>::allocate_called == true);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A2<int>, A2<int>, A3<int>> A;
+        A a;
+        A2<int>::allocate_called = false;
+        assert(a.allocate(10, (const void*)20) == (int*)20);
+        assert(A2<int>::allocate_called == true);
+    }
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp
new file mode 100644
index 0000000..f66da6b
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp
@@ -0,0 +1,193 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// template <class T, class... Args> void construct(T* p, Args&&... args);
+
+#include <memory>
+#include <cassert>
+#include <string>
+
+#include "../allocators.h"
+
+#ifdef _LIBCPP_MOVE
+
+struct B
+{
+    static bool constructed;
+
+    typedef A1<B> allocator_type;
+
+    explicit B(std::allocator_arg_t, const allocator_type& a, int i)
+    {
+        assert(a.id() == 5);
+        assert(i == 6);
+        constructed = true;
+    }
+};
+
+bool B::constructed = false;
+
+struct C
+{
+    static bool constructed;
+
+    typedef std::scoped_allocator_adaptor<A2<C>> allocator_type;
+
+    explicit C(std::allocator_arg_t, const allocator_type& a, int i)
+    {
+        assert(a.id() == 7);
+        assert(i == 8);
+        constructed = true;
+    }
+};
+
+bool C::constructed = false;
+
+struct D
+{
+    static bool constructed;
+
+    typedef std::scoped_allocator_adaptor<A2<D>> allocator_type;
+
+    explicit D(int i, int j, const allocator_type& a)
+    {
+        assert(i == 1);
+        assert(j == 2);
+        assert(a.id() == 3);
+        constructed = true;
+    }
+};
+
+bool D::constructed = false;
+
+struct E
+{
+    static bool constructed;
+
+    typedef std::scoped_allocator_adaptor<A1<E>> allocator_type;
+
+    explicit E(int i, int j, const allocator_type& a)
+    {
+        assert(i == 1);
+        assert(j == 2);
+        assert(a.id() == 50);
+        constructed = true;
+    }
+};
+
+bool E::constructed = false;
+
+struct F
+{
+    static bool constructed;
+
+    typedef std::scoped_allocator_adaptor<A2<F>> allocator_type;
+
+    explicit F(int i, int j)
+    {
+        assert(i == 1);
+        assert(j == 2);
+    }
+
+    explicit F(int i, int j, const allocator_type& a)
+    {
+        assert(i == 1);
+        assert(j == 2);
+        assert(a.id() == 50);
+        constructed = true;
+    }
+};
+
+bool F::constructed = false;
+
+#endif
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<std::string>> A;
+        A a;
+        char buf[100];
+        typedef std::string S;
+        S* s = (S*)buf;
+        a.construct(s, 4, 'c');
+        assert(*s == "cccc");
+        s->~S();
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<B>> A;
+        A a(A1<B>(5));
+        char buf[100];
+        typedef B S;
+        S* s = (S*)buf;
+        a.construct(s, 6);
+        assert(S::constructed);
+        s->~S();
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<C>> A;
+        A a(A1<int>(5), A2<C>(7));
+        char buf[100];
+        typedef C S;
+        S* s = (S*)buf;
+        a.construct(s, 8);
+        assert(S::constructed);
+        s->~S();
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<D>> A;
+        A a(A1<int>(5), A2<D>(3));
+        char buf[100];
+        typedef D S;
+        S* s = (S*)buf;
+        a.construct(s, 1, 2);
+        assert(S::constructed);
+        s->~S();
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A3<E>, A2<E>> K;
+        typedef std::scoped_allocator_adaptor<K, A1<E>> A;
+        A a(K(), A1<E>(50));
+        char buf[100];
+        typedef E S;
+        S* s = (S*)buf;
+        A3<E>::constructed = false;
+        a.construct(s, 1, 2);
+        assert(S::constructed);
+        assert(A3<E>::constructed);
+        s->~S();
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A3<F>, A2<F>> K;
+        typedef std::scoped_allocator_adaptor<K, A1<F>> A;
+        A a(K(), A1<F>(50));
+        char buf[100];
+        typedef F S;
+        S* s = (S*)buf;
+        A3<F>::constructed = false;
+        a.construct(s, 1, 2);
+        assert(!S::constructed);
+        assert(A3<F>::constructed);
+        s->~S();
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp
new file mode 100644
index 0000000..6a8b2da
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/deallocate.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// void deallocate(pointer p, size_type n);
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a;
+        a.deallocate((int*)10, 20);
+        assert((A1<int>::deallocate_called == std::pair<int*, std::size_t>((int*)10, 20)));
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a;
+        a.deallocate((int*)10, 20);
+        assert((A1<int>::deallocate_called == std::pair<int*, std::size_t>((int*)10, 20)));
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a;
+        a.deallocate((int*)10, 20);
+        assert((A1<int>::deallocate_called == std::pair<int*, std::size_t>((int*)10, 20)));
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp
new file mode 100644
index 0000000..d3af8b6
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/destroy.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// template <class T> void destroy(T* p);
+
+#include <memory>
+#include <cassert>
+#include <string>
+
+#include "../allocators.h"
+
+struct B
+{
+    static bool constructed;
+
+    B() {constructed = true;}
+    ~B() {constructed = false;}
+};
+
+bool B::constructed = false;
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<B>> A;
+        A a;
+        char buf[100];
+        typedef B S;
+        S* s = (S*)buf;
+        assert(!S::constructed);
+        a.construct(s);
+        assert(S::constructed);
+        a.destroy(s);
+        assert(!S::constructed);
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A3<B>, A1<B>> A;
+        A a;
+        char buf[100];
+        typedef B S;
+        S* s = (S*)buf;
+        assert(!S::constructed);
+        assert(!A3<S>::constructed);
+        assert(!A3<S>::destroy_called);
+        a.construct(s);
+        assert(S::constructed);
+        assert(A3<S>::constructed);
+        assert(!A3<S>::destroy_called);
+        a.destroy(s);
+        assert(!S::constructed);
+        assert(A3<S>::constructed);
+        assert(A3<S>::destroy_called);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp
new file mode 100644
index 0000000..5c66dde
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/inner_allocator.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// inner_allocator_type& inner_allocator();
+// const inner_allocator_type& inner_allocator() const;
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a(A1<int>(5));
+        assert(a.inner_allocator() == a);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a(A1<int>(5), A2<int>(6));
+        assert(a.inner_allocator() == std::scoped_allocator_adaptor<A2<int>>(A2<int>(6)));
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a(A1<int>(5), A2<int>(6), A3<int>(8));
+        assert((a.inner_allocator() ==
+            std::scoped_allocator_adaptor<A2<int>, A3<int>>(A2<int>(6), A3<int>(8))));
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp
new file mode 100644
index 0000000..033c6cd
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/max_size.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// size_type max_size() const;
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        const A a(A1<int>(100));
+        assert(a.max_size() == 100);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        const A a(A1<int>(20), A2<int>());
+        assert(a.max_size() == 20);
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        const A a(A1<int>(200), A2<int>(), A3<int>());
+        assert(a.max_size() == 200);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp
new file mode 100644
index 0000000..94ffd87
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/outer_allocator.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// outer_allocator_type& outer_allocator();
+// const outer_allocator_type& outer_allocator() const;
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a(A1<int>(5));
+        assert(a.outer_allocator() == A1<int>(5));
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>> A;
+        A a(A1<int>(5), A2<int>(6));
+        assert(a.outer_allocator() == A1<int>(5));
+    }
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a(A1<int>(5), A2<int>(6), A3<int>(8));
+        assert(a.outer_allocator() == A1<int>(5));
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp
new file mode 100644
index 0000000..aa731f9
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.members/select_on_container_copy_construction.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// scoped_allocator_adaptor select_on_container_copy_construction() const;
+
+#include <memory>
+#include <cassert>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>> A;
+        A a1(A1<int>(3));
+        assert(a1.outer_allocator().id() == 3);
+        A a2 = std::allocator_traits<A>::select_on_container_copy_construction(a1);
+        assert(a2.outer_allocator().id() == 3);
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A3<int>> A;
+        A a1(A3<int>(3));
+        assert(a1.outer_allocator().id() == 3);
+        A a2 = std::allocator_traits<A>::select_on_container_copy_construction(a1);
+        assert(a2.outer_allocator().id() == -1);
+    }
+
+    {
+        typedef std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>> A;
+        A a1(A1<int>(1), A2<int>(2), A3<int>(3));
+        assert(a1.outer_allocator().id() == 1);
+        assert(a1.inner_allocator().outer_allocator().id() == 2);
+        assert(a1.inner_allocator().inner_allocator().outer_allocator().id() == 3);
+        A a2 = std::allocator_traits<A>::select_on_container_copy_construction(a1);
+        assert(a2.outer_allocator().id() == 1);
+        assert(a2.inner_allocator().outer_allocator().id() == 2);
+        assert(a2.inner_allocator().inner_allocator().outer_allocator().id() == -1);
+    }
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp
new file mode 100644
index 0000000..fd5c7cf
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/inner_allocator_type.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// typedef see below inner_allocator_type;
+
+#include <memory>
+#include <type_traits>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::inner_allocator_type,
+        std::scoped_allocator_adaptor<A1<int>>>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>>::inner_allocator_type,
+        std::scoped_allocator_adaptor<A2<int>>>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::inner_allocator_type,
+        std::scoped_allocator_adaptor<A2<int>, A3<int>>>::value), "");
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp
new file mode 100644
index 0000000..2fb1ee1
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_copy_assignment.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// typedef see below propagate_on_container_copy_assignment;
+
+#include <memory>
+#include <type_traits>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::propagate_on_container_copy_assignment,
+        std::false_type>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>>::propagate_on_container_copy_assignment,
+        std::false_type>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::propagate_on_container_copy_assignment,
+        std::true_type>::value), "");
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp
new file mode 100644
index 0000000..b52e281
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_move_assignment.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// typedef see below propagate_on_container_move_assignment;
+
+#include <memory>
+#include <type_traits>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::propagate_on_container_move_assignment,
+        std::false_type>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>>::propagate_on_container_move_assignment,
+        std::true_type>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::propagate_on_container_move_assignment,
+        std::true_type>::value), "");
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp
new file mode 100644
index 0000000..98773a4
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocator.adaptor.types/propagate_on_container_swap.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+//   class scoped_allocator_adaptor
+
+// typedef see below propagate_on_container_swap;
+
+#include <memory>
+#include <type_traits>
+
+#include "../allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::propagate_on_container_swap,
+        std::false_type>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>>::propagate_on_container_swap,
+        std::false_type>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::propagate_on_container_swap,
+        std::true_type>::value), "");
+
+#endif
+}
diff --git a/test/utilities/memory/allocator.adaptor/allocators.h b/test/utilities/memory/allocator.adaptor/allocators.h
new file mode 100644
index 0000000..7075f85
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/allocators.h
@@ -0,0 +1,176 @@
+#ifndef ALLOCATORS_H
+#define ALLOCATORS_H
+
+#include <type_traits>
+#include <utility>
+
+#ifdef _LIBCPP_MOVE
+
+template <class T>
+class A1
+{
+    int id_;
+public:
+    explicit A1(int id = 0) : id_(id) {}
+
+    typedef T value_type;
+
+    int id() const {return id_;}
+
+    static bool copy_called;
+    static bool move_called;
+    static bool allocate_called;
+    static std::pair<T*, std::size_t> deallocate_called;
+
+    A1(const A1& a) : id_(a.id()) {copy_called = true;}
+    A1(A1&& a) : id_(a.id())      {move_called = true;}
+
+    template <class U>
+        A1(const A1<U>& a) : id_(a.id()) {copy_called = true;}
+    template <class U>
+        A1(A1<U>&& a) : id_(a.id()) {move_called = true;}
+
+    T* allocate(std::size_t n)
+    {
+        allocate_called = true;
+        return (T*)n;
+    }
+
+    void deallocate(T* p, std::size_t n)
+    {
+        deallocate_called = std::pair<T*, std::size_t>(p, n);
+    }
+
+    std::size_t max_size() const {return id_;}
+};
+
+template <class T> bool A1<T>::copy_called = false;
+template <class T> bool A1<T>::move_called = false;
+template <class T> bool A1<T>::allocate_called = false;
+template <class T> std::pair<T*, std::size_t> A1<T>::deallocate_called;
+
+template <class T, class U>
+inline
+bool operator==(const A1<T>& x, const A1<U>& y)
+{
+    return x.id() == y.id();
+}
+
+template <class T, class U>
+inline
+bool operator!=(const A1<T>& x, const A1<U>& y)
+{
+    return !(x == y);
+}
+
+template <class T>
+class A2
+{
+    int id_;
+public:
+    explicit A2(int id = 0) : id_(id) {}
+
+    typedef T value_type;
+
+    typedef unsigned size_type;
+    typedef int difference_type;
+
+    typedef std::true_type propagate_on_container_move_assignment;
+
+    int id() const {return id_;}
+
+    static bool copy_called;
+    static bool move_called;
+    static bool allocate_called;
+
+    A2(const A2& a) : id_(a.id()) {copy_called = true;}
+    A2(A2&& a) : id_(a.id())      {move_called = true;}
+
+    T* allocate(std::size_t n, const void* hint)
+    {
+        allocate_called = true;
+        return (T*)hint;
+    }
+};
+
+template <class T> bool A2<T>::copy_called = false;
+template <class T> bool A2<T>::move_called = false;
+template <class T> bool A2<T>::allocate_called = false;
+
+template <class T, class U>
+inline
+bool operator==(const A2<T>& x, const A2<U>& y)
+{
+    return x.id() == y.id();
+}
+
+template <class T, class U>
+inline
+bool operator!=(const A2<T>& x, const A2<U>& y)
+{
+    return !(x == y);
+}
+
+template <class T>
+class A3
+{
+    int id_;
+public:
+    explicit A3(int id = 0) : id_(id) {}
+
+    typedef T value_type;
+
+    typedef std::true_type propagate_on_container_copy_assignment;
+    typedef std::true_type propagate_on_container_swap;
+
+    int id() const {return id_;}
+
+    static bool copy_called;
+    static bool move_called;
+    static bool constructed;
+    static bool destroy_called;
+
+    A3(const A3& a) : id_(a.id()) {copy_called = true;}
+    A3(A3&& a) : id_(a.id())      {move_called = true;}
+
+    template <class U, class ...Args>
+    void construct(U* p, Args&& ...args)
+    {
+        ::new (p) U(std::forward<Args>(args)...);
+        constructed = true;
+    }
+
+    template <class U>
+    void destroy(U* p)
+    {
+        p->~U();
+        destroy_called = true;
+    }
+
+    A3 select_on_container_copy_construction() const {return A3(-1);}
+};
+
+
+
+template <class T> bool A3<T>::copy_called = false;
+template <class T> bool A3<T>::move_called = false;
+template <class T> bool A3<T>::constructed = false;
+template <class T> bool A3<T>::destroy_called = false;
+
+template <class T, class U>
+inline
+bool operator==(const A3<T>& x, const A3<U>& y)
+{
+    return x.id() == y.id();
+}
+
+template <class T, class U>
+inline
+bool operator!=(const A3<T>& x, const A3<U>& y)
+{
+    return !(x == y);
+}
+
+#endif
+
+#endif
diff --git a/test/utilities/memory/allocator.adaptor/types.pass.cpp b/test/utilities/memory/allocator.adaptor/types.pass.cpp
new file mode 100644
index 0000000..ebac49a
--- /dev/null
+++ b/test/utilities/memory/allocator.adaptor/types.pass.cpp
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊThe LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+// class scoped_allocator_adaptor
+//     : public OuterAlloc
+// {
+// public:
+//     typedef OuterAlloc outer_allocator_type;
+//     typedef typename OuterTraits::size_type size_type;
+//     typedef typename OuterTraits::difference_type difference_type;
+//     typedef typename OuterTraits::pointer pointer;
+//     typedef typename OuterTraits::const_pointer const_pointer;
+//     typedef typename OuterTraits::void_pointer void_pointer;
+//     typedef typename OuterTraits::const_void_pointer const_void_pointer;
+// };
+
+#include <memory>
+#include <type_traits>
+
+#include "allocators.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+
+    static_assert((std::is_base_of<
+        A1<int>,
+        std::scoped_allocator_adaptor<A1<int>>
+        >::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::outer_allocator_type,
+        A1<int>>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::size_type,
+        std::size_t>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::difference_type,
+        std::ptrdiff_t>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::pointer,
+        int*>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::const_pointer,
+        const int*>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::void_pointer,
+        void*>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A1<int>>::const_void_pointer,
+        const void*>::value), "");
+
+
+    static_assert((std::is_base_of<
+        A2<int>,
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>
+        >::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>::outer_allocator_type,
+        A2<int>>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>::size_type,
+        unsigned>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>::difference_type,
+        int>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>::pointer,
+        int*>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>::const_pointer,
+        const int*>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>::void_pointer,
+        void*>::value), "");
+
+    static_assert((std::is_same<
+        std::scoped_allocator_adaptor<A2<int>, A1<int>>::const_void_pointer,
+        const void*>::value), "");
+
+#endif
+}