[libcxx-commits] [libcxx] [String] Allow fancy pointer as pointer type of basic_string allocator (PR #191023)

Nikita Belenkiy via libcxx-commits libcxx-commits at lists.llvm.org
Wed Apr 8 11:53:00 PDT 2026


https://github.com/kitsnet updated https://github.com/llvm/llvm-project/pull/191023

>From 632383ea07235d8730a15e21d64e1683dcdecfc7 Mon Sep 17 00:00:00 2001
From: Nikita Belenkiy <nikita.nb.belenkiy at partner.bmw.de>
Date: Wed, 8 Apr 2026 19:28:57 +0200
Subject: [PATCH] [String] Allow fancy pointer as pointer type of basic_string
 allocator

Currently, basic_string does not support custom allocators which use fancy pointers
that are not trivially constructible and destructible as the pointer type. This happens
because in its internal representation, fancy pointers are stored in a union, which
deletes the default constructor of such a union.

In order to allow fancy pointers, this PR does:
* add an explicit default constructor to the underlying union;
* add explicit __construct_at() to start lifetime of the fancy pointer in constant expressions.

Addresses bug report: https://bugs.llvm.org/show_bug.cgi?id=20508
Takes over: https://github.com/llvm/llvm-project/pull/71182
Originally https://reviews.llvm.org/D132149
---
 libcxx/include/string                         |  20 +-
 .../basic.string/alignof.compile.pass.cpp     |  15 ++
 .../basic.string/sizeof.compile.pass.cpp      |  35 +++
 .../string.access/assert.back.pass.cpp        |   2 +
 .../string.access/assert.cback.pass.cpp       |   2 +
 .../string.access/assert.cfront.pass.cpp      |   2 +
 .../string.access/assert.cindex.pass.cpp      |   2 +
 .../string.access/assert.front.pass.cpp       |   2 +
 .../string.access/assert.index.pass.cpp       |   2 +
 .../string.cons/copy_shrunk_long.pass.cpp     |   2 +
 .../assert.iterator.add.pass.cpp              |   2 +
 .../assert.iterator.decrement.pass.cpp        |   2 +
 .../assert.iterator.dereference.pass.cpp      |   2 +
 .../assert.iterator.increment.pass.cpp        |   2 +
 .../assert.iterator.index.pass.cpp            |   2 +
 .../debug.iterator.compare.pass.cpp           |   2 +
 .../debug.iterator.subtract.pass.cpp          |   2 +
 .../assert.erase_iter.null.pass.cpp           |   2 +
 .../string.modifiers/assert.pop_back.pass.cpp |   2 +
 .../debug.erase.iter.pass.cpp                 |   2 +
 .../debug.erase.iter_iter.pass.cpp            |   2 +
 .../debug.insert.iter_char.pass.cpp           |   2 +
 .../debug.insert.iter_iter_iter.pass.cpp      |   2 +
 .../debug.insert.iter_size_char.pass.cpp      |   2 +
 .../test/std/containers/from_range_helpers.h  |   2 +
 .../std/containers/insert_range_helpers.h     |   4 +
 .../basic.string.hash/enabled_hashes.pass.cpp |   1 +
 .../basic.string/string.access/at.pass.cpp    |   2 +
 .../basic.string/string.access/back.pass.cpp  |   2 +
 .../basic.string/string.access/front.pass.cpp |   2 +
 .../basic.string/string.access/index.pass.cpp |   3 +
 .../string.capacity/capacity.pass.cpp         |   1 +
 .../string.capacity/clear.pass.cpp            |   2 +
 .../string.capacity/empty.pass.cpp            |   2 +
 .../string.capacity/length.pass.cpp           |   2 +
 .../string.capacity/max_size.pass.cpp         |   2 +
 .../string.capacity/over_max_size.pass.cpp    |   2 +
 .../string.capacity/reserve.pass.cpp          |   2 +
 .../string.capacity/reserve_size.pass.cpp     |   2 +
 .../string.capacity/resize_size.pass.cpp      |   2 +
 .../string.capacity/resize_size_char.pass.cpp |   2 +
 .../string.capacity/shrink_to_fit.pass.cpp    |   2 +
 .../string.capacity/size.pass.cpp             |   2 +
 .../string.cons/T_size_size.pass.cpp          |   1 +
 .../basic.string/string.cons/alloc.pass.cpp   |   1 +
 .../string.cons/char_assignment.pass.cpp      |   2 +
 .../basic.string/string.cons/copy.pass.cpp    |   1 +
 .../string.cons/copy_alloc.pass.cpp           |   1 +
 .../string.cons/copy_assignment.pass.cpp      |   2 +
 .../basic.string/string.cons/default.pass.cpp |   3 +
 .../basic.string/string.cons/dtor.pass.cpp    |   3 +
 .../string.cons/initializer_list.pass.cpp     |   1 +
 .../initializer_list_assignment.pass.cpp      |   2 +
 .../string.cons/iter_alloc.pass.cpp           |   1 +
 .../string.cons/iter_alloc_deduction.pass.cpp |  11 +
 .../basic.string/string.cons/move.pass.cpp    |   1 +
 .../string.cons/move_alloc.pass.cpp           |  12 +
 .../string.cons/move_assign_noexcept.pass.cpp |   4 +
 .../string.cons/move_assignment.pass.cpp      |   1 +
 .../string.cons/move_noexcept.pass.cpp        |   4 +
 .../string.cons/pointer_alloc.pass.cpp        |   1 +
 .../string.cons/pointer_assignment.pass.cpp   |   2 +
 .../string.cons/pointer_size_alloc.pass.cpp   |   1 +
 .../string.cons/size_char_alloc.pass.cpp      |   1 +
 .../string.cons/string_view.pass.cpp          |   1 +
 .../string_view_assignment.pass.cpp           |   2 +
 .../string_view_deduction.pass.cpp            |  10 +
 .../string_view_size_size_deduction.pass.cpp  |  10 +
 .../basic.string/string.cons/substr.pass.cpp  |   1 +
 .../string.cons/substr_rvalue.pass.cpp        |   1 +
 .../string.iterators/begin.pass.cpp           |   2 +
 .../string.iterators/cbegin.pass.cpp          |   2 +
 .../string.iterators/cend.pass.cpp            |   2 +
 .../string.iterators/crbegin.pass.cpp         |   2 +
 .../string.iterators/crend.pass.cpp           |   2 +
 .../string.iterators/end.pass.cpp             |   2 +
 .../string.iterators/rbegin.pass.cpp          |   2 +
 .../string.iterators/rend.pass.cpp            |   2 +
 .../string_append/T_size_size.pass.cpp        |   2 +
 .../string_append/initializer_list.pass.cpp   |   2 +
 .../string_append/iterator.pass.cpp           |   2 +
 .../string_append/pointer.pass.cpp            |   2 +
 .../string_append/pointer_size.pass.cpp       |   2 +
 .../string_append/push_back.pass.cpp          |   2 +
 .../string_append/size_char.pass.cpp          |   2 +
 .../string_append/string.pass.cpp             |   2 +
 .../string_append/string_size_size.pass.cpp   |   2 +
 .../string_append/string_view.pass.cpp        |   2 +
 .../string_assign/T_size_size.pass.cpp        |   2 +
 .../string_assign/initializer_list.pass.cpp   |   4 +-
 .../string_assign/iterator.pass.cpp           |   2 +
 .../string_assign/pointer.pass.cpp            |   2 +
 .../string_assign/pointer_size.pass.cpp       |   2 +
 .../string_assign/rv_string.pass.cpp          |   2 +
 .../string_assign/size_char.pass.cpp          |   2 +
 .../string_assign/string.pass.cpp             |   8 +
 .../string_assign/string_size_size.pass.cpp   |   2 +
 .../string_assign/string_view.pass.cpp        |   1 +
 .../string_copy/copy.pass.cpp                 |   2 +
 .../string_erase/iter.pass.cpp                |   2 +
 .../string_erase/iter_iter.pass.cpp           |   2 +
 .../string_erase/pop_back.pass.cpp            |   2 +
 .../string_erase/size_size.pass.cpp           |   2 +
 .../string_insert/iter_char.pass.cpp          |   2 +
 .../iter_initializer_list.pass.cpp            |   2 +
 .../string_insert/iter_iter_iter.pass.cpp     |   4 +-
 .../string_insert/iter_size_char.pass.cpp     |   2 +
 .../string_insert/size_T_size_size.pass.cpp   |   3 +
 .../string_insert/size_pointer.pass.cpp       |   2 +
 .../string_insert/size_pointer_size.pass.cpp  |   3 +
 .../string_insert/size_size_char.pass.cpp     |   2 +
 .../string_insert/size_string.pass.cpp        |   2 +
 .../size_string_size_size.pass.cpp            |   2 +
 .../string_insert/string_view.pass.cpp        |   2 +
 .../string_op_plus_equal/char.pass.cpp        |   2 +
 .../initializer_list.pass.cpp                 |   2 +
 .../string_op_plus_equal/pointer.pass.cpp     |   2 +
 .../string_op_plus_equal/string.pass.cpp      |   2 +
 .../iter_iter_initializer_list.pass.cpp       |   2 +
 .../iter_iter_iter_iter.pass.cpp              |   2 +
 .../string_replace/iter_iter_pointer.pass.cpp |   2 +
 .../iter_iter_pointer_size.pass.cpp           |   2 +
 .../iter_iter_size_char.pass.cpp              |   4 +-
 .../string_replace/iter_iter_string.pass.cpp  |   2 +
 .../iter_iter_string_view.pass.cpp            |   2 +
 .../size_size_T_size_size.pass.cpp            |   2 +
 .../string_replace/size_size_pointer.pass.cpp |   2 +
 .../size_size_pointer_size.pass.cpp           |   2 +
 .../size_size_size_char.pass.cpp              |   2 +
 .../string_replace/size_size_string.pass.cpp  |   2 +
 .../size_size_string_size_size.pass.cpp       |   2 +
 .../size_size_string_view.pass.cpp            |   2 +
 .../string_swap/swap.pass.cpp                 |   2 +
 .../string.io/get_line.pass.cpp               |   2 +
 .../string.io/get_line_delim.pass.cpp         |   2 +
 .../string.io/get_line_delim_rv.pass.cpp      |   2 +
 .../string.io/get_line_rv.pass.cpp            |   4 +
 .../string.io/stream_extract.pass.cpp         |   2 +
 .../string.io/stream_insert.pass.cpp          |   2 +
 .../string.special/swap.pass.cpp              |   2 +
 .../string_op!=/pointer_string.pass.cpp       |   2 +
 .../string_op!=/string_pointer.pass.cpp       |   2 +
 .../string_op!=/string_string.pass.cpp        |   2 +
 .../string_op!=/string_string_view.pass.cpp   |   2 +
 .../string_op!=/string_view_string.pass.cpp   |   2 +
 .../string_op+/char_string.pass.cpp           |   2 +
 .../string_op+/pointer_string.pass.cpp        |   2 +
 .../string_op+/string_char.pass.cpp           |   2 +
 .../string_op+/string_pointer.pass.cpp        |   2 +
 .../string_op+/string_string.pass.cpp         |   2 +
 .../string_operator==/pointer_string.pass.cpp |   2 +
 .../string_operator==/string_pointer.pass.cpp |   2 +
 .../string_operator==/string_string.pass.cpp  |   2 +
 .../string_string_view.pass.cpp               |   2 +
 .../string_view_string.pass.cpp               |   2 +
 .../string_opgt/pointer_string.pass.cpp       |   2 +
 .../string_opgt/string_pointer.pass.cpp       |   2 +
 .../string_opgt/string_string.pass.cpp        |   2 +
 .../string_opgt/string_string_view.pass.cpp   |   2 +
 .../string_opgt/string_view_string.pass.cpp   |   2 +
 .../string_opgt=/pointer_string.pass.cpp      |   2 +
 .../string_opgt=/string_pointer.pass.cpp      |   2 +
 .../string_opgt=/string_string.pass.cpp       |   2 +
 .../string_opgt=/string_string_view.pass.cpp  |   2 +
 .../string_opgt=/string_view_string.pass.cpp  |   2 +
 .../string_oplt/pointer_string.pass.cpp       |   2 +
 .../string_oplt/string_pointer.pass.cpp       |   2 +
 .../string_oplt/string_string.pass.cpp        |   2 +
 .../string_oplt/string_string_view.pass.cpp   |   2 +
 .../string_oplt/string_view_string.pass.cpp   |   2 +
 .../string_oplt=/pointer_string.pass.cpp      |   2 +
 .../string_oplt=/string_pointer.pass.cpp      |   2 +
 .../string_oplt=/string_string.pass.cpp       |   2 +
 .../string_oplt=/string_string_view.pass.cpp  |   2 +
 .../string_oplt=/string_view_string.pass.cpp  |   2 +
 .../string.accessors/c_str.pass.cpp           |   2 +
 .../string.ops/string.accessors/data.pass.cpp |   2 +
 .../string.accessors/get_allocator.pass.cpp   |   1 +
 .../string_compare/pointer.pass.cpp           |   2 +
 .../size_size_T_size_size.pass.cpp            |   2 +
 .../string_compare/size_size_pointer.pass.cpp |   2 +
 .../size_size_pointer_size.pass.cpp           |   2 +
 .../string_compare/size_size_string.pass.cpp  |   2 +
 .../size_size_string_size_size.pass.cpp       |   2 +
 .../size_size_string_view.pass.cpp            |   2 +
 .../string.ops/string_compare/string.pass.cpp |   2 +
 .../string_compare/string_view.pass.cpp       |   2 +
 .../char_size.pass.cpp                        |   2 +
 .../pointer_size.pass.cpp                     |   2 +
 .../pointer_size_size.pass.cpp                |   2 +
 .../string_size.pass.cpp                      |   2 +
 .../string_view_size.pass.cpp                 |   2 +
 .../string_find.first.of/char_size.pass.cpp   |   2 +
 .../pointer_size.pass.cpp                     |   2 +
 .../pointer_size_size.pass.cpp                |   2 +
 .../string_find.first.of/string_size.pass.cpp |   2 +
 .../string_view_size.pass.cpp                 |   2 +
 .../char_size.pass.cpp                        |   2 +
 .../pointer_size.pass.cpp                     |   2 +
 .../pointer_size_size.pass.cpp                |   2 +
 .../string_size.pass.cpp                      |   2 +
 .../string_view_size.pass.cpp                 |   2 +
 .../string_find.last.of/char_size.pass.cpp    |   2 +
 .../string_find.last.of/pointer_size.pass.cpp |   2 +
 .../pointer_size_size.pass.cpp                |   2 +
 .../string_find.last.of/string_size.pass.cpp  |   2 +
 .../string_view_size.pass.cpp                 |   2 +
 .../string.ops/string_find/char_size.pass.cpp |   2 +
 .../string_find/pointer_size.pass.cpp         |   2 +
 .../string_find/pointer_size_size.pass.cpp    |   2 +
 .../string_find/string_size.pass.cpp          |   2 +
 .../string_find/string_view_size.pass.cpp     |   2 +
 .../string_rfind/char_size.pass.cpp           |   2 +
 .../string_rfind/pointer_size.pass.cpp        |   2 +
 .../string_rfind/pointer_size_size.pass.cpp   |   2 +
 .../string_rfind/string_size.pass.cpp         |   2 +
 .../string_rfind/string_view_size.pass.cpp    |   2 +
 .../string.ops/string_substr/substr.pass.cpp  |   1 +
 .../string_substr/substr_rvalue.pass.cpp      |   1 +
 .../string.require/contiguous.pass.cpp        |   1 +
 .../std/strings/basic.string/types.pass.cpp   |   1 +
 .../strings/strings.erasure/erase.pass.cpp    |   1 +
 .../strings/strings.erasure/erase_if.pass.cpp |   1 +
 libcxx/test/support/test_allocator.h          | 228 ++++++++++++++++++
 224 files changed, 768 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index 0c8767df2cdd2..afa57af704ce5 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -751,7 +751,7 @@ public:
   using const_pointer                  = typename __alloc_traits::const_pointer;
 
   // A basic_string contains the following members which may be trivially relocatable:
-  // - pointer: is currently assumed to be trivially relocatable, but is still checked in case that changes
+  // - pointer: may or may not be trivially relocatable, so it's checked
   // - size_type: is always trivially relocatable, since it has to be an integral type
   // - value_type: is always trivially relocatable, since it has to be trivial
   // - unsigned char: is a fundamental type, so it's trivially relocatable
@@ -894,7 +894,8 @@ private:
     __short __s;
     __long __l;
 
-    __rep() = default;
+    // not using =default, as it would be deleted if __long is not trivially constructible
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep() : __s() {}
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__short __r) : __s(__r) {}
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__long __r) : __l(__r) {}
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __rep(__uninitialized_tag) {}
@@ -2116,6 +2117,20 @@ private:
 
   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI static bool __fits_in_sso(size_type __sz) { return __sz < __min_cap; }
 
+  // If __long is not trivially constructible (this occurs if the pointer type inside __long is not trivially constructible)
+  // then the lifetime of __l must be explicitly started with std::__construct_at before it can be assigned to. If __long is
+  // trivially constructible, then the lifetime of __l can be implicitly started with a simple assignment and therefore does
+  // not need to be explicitly initialised here.
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_long_lifetime() {
+#if _LIBCPP_STD_VER >= 17
+    if constexpr(!__is_trivially_constructible(__long)) {
+#else
+    if (!__is_trivially_constructible(__long)) {
+#endif // _LIBCPP_STD_VER >= 17
+      std::__construct_at(std::addressof(__rep_.__l));
+    }
+  }
+
   template <class _Iterator, class _Sentinel>
   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
   __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n);
@@ -2293,6 +2308,7 @@ private:
       __annotate_new(__size);
       return __get_short_pointer();
     } else {
+      __begin_long_lifetime();
       __rep_.__l = __allocate_long_buffer(__alloc_, __size);
       __annotate_new(__size);
       return __get_long_pointer();
diff --git a/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp b/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp
index 49cbde14c568b..f78a7ab35326b 100644
--- a/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/alignof.compile.pass.cpp
@@ -54,6 +54,9 @@ class small_iter_allocator {
 template <class CharT>
 using min_string = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT>>;
 
+template <class CharT>
+using fancy_string = std::basic_string<CharT, std::char_traits<CharT>, fancy_pointer_allocator<CharT>>;
+
 template <class CharT>
 using test_string = std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT>>;
 
@@ -64,6 +67,7 @@ using small_string = std::basic_string<CharT, std::char_traits<CharT>, small_ite
 
 static_assert(alignof(std::string) == 8, "");
 static_assert(alignof(min_string<char>) == 8, "");
+static_assert(alignof(fancy_string<char>) == 8, "");
 static_assert(alignof(test_string<char>) == 8, "");
 static_assert(alignof(small_string<char>) == 2, "");
 
@@ -71,11 +75,13 @@ static_assert(alignof(small_string<char>) == 2, "");
 #    if __WCHAR_WIDTH__ == 32
 static_assert(alignof(std::wstring) == 8, "");
 static_assert(alignof(min_string<wchar_t>) == 8, "");
+static_assert(alignof(fancy_string<wchar_t>) == 8, "");
 static_assert(alignof(test_string<wchar_t>) == 8, "");
 static_assert(alignof(small_string<wchar_t>) == 4, "");
 #    elif __WCHAR_WIDTH__ == 16
 static_assert(alignof(std::wstring) == 8, "");
 static_assert(alignof(min_string<wchar_t>) == 8, "");
+static_assert(alignof(fancy_string<wchar_t>) == 8, "");
 static_assert(alignof(test_string<wchar_t>) == 8, "");
 static_assert(alignof(small_string<wchar_t>) == 2, "");
 #    else
@@ -86,6 +92,7 @@ static_assert(alignof(small_string<wchar_t>) == 2, "");
 #  ifndef TEST_HAS_NO_CHAR8_T
 static_assert(alignof(std::u8string) == 8, "");
 static_assert(alignof(min_string<char8_t>) == 8, "");
+static_assert(alignof(fancy_string<char8_t>) == 8, "");
 static_assert(alignof(test_string<char8_t>) == 8, "");
 static_assert(alignof(small_string<char8_t>) == 2, "");
 #  endif
@@ -95,6 +102,8 @@ static_assert(alignof(std::u16string) == 8, "");
 static_assert(alignof(std::u32string) == 8, "");
 static_assert(alignof(min_string<char16_t>) == 8, "");
 static_assert(alignof(min_string<char32_t>) == 8, "");
+static_assert(alignof(fancy_string<char16_t>) == 8, "");
+static_assert(alignof(fancy_string<char32_t>) == 8, "");
 static_assert(alignof(test_string<char16_t>) == 8, "");
 static_assert(alignof(test_string<char32_t>) == 8, "");
 static_assert(alignof(small_string<char16_t>) == 2, "");
@@ -105,6 +114,7 @@ static_assert(alignof(small_string<char32_t>) == 4, "");
 
 static_assert(alignof(std::string) == 4, "");
 static_assert(alignof(min_string<char>) == 4, "");
+static_assert(alignof(fancy_string<char>) == 4, "");
 static_assert(alignof(test_string<char>) == 4, "");
 static_assert(alignof(small_string<char>) == 2, "");
 
@@ -112,11 +122,13 @@ static_assert(alignof(small_string<char>) == 2, "");
 #    if __WCHAR_WIDTH__ == 32
 static_assert(alignof(std::wstring) == 4, "");
 static_assert(alignof(min_string<wchar_t>) == 4, "");
+static_assert(alignof(fancy_string<wchar_t>) == 4, "");
 static_assert(alignof(test_string<wchar_t>) == 4, "");
 static_assert(alignof(small_string<wchar_t>) == 4, "");
 #    elif __WCHAR_WIDTH__ == 16
 static_assert(alignof(std::wstring) == 4, "");
 static_assert(alignof(min_string<wchar_t>) == 4, "");
+static_assert(alignof(fancy_string<wchar_t>) == 4, "");
 static_assert(alignof(test_string<wchar_t>) == 4, "");
 static_assert(alignof(small_string<wchar_t>) == 2, "");
 #    else
@@ -127,6 +139,7 @@ static_assert(alignof(small_string<wchar_t>) == 2, "");
 #  ifndef TEST_HAS_NO_CHAR8_T
 static_assert(alignof(std::u8string) == 4, "");
 static_assert(alignof(min_string<char8_t>) == 4, "");
+static_assert(alignof(fancy_string<char8_t>) == 4, "");
 static_assert(alignof(test_string<char8_t>) == 4, "");
 static_assert(alignof(small_string<char8_t>) == 2, "");
 #  endif
@@ -136,6 +149,8 @@ static_assert(alignof(std::u16string) == 4, "");
 static_assert(alignof(std::u32string) == 4, "");
 static_assert(alignof(min_string<char16_t>) == 4, "");
 static_assert(alignof(min_string<char32_t>) == 4, "");
+static_assert(alignof(fancy_string<char16_t>) == 4, "");
+static_assert(alignof(fancy_string<char32_t>) == 4, "");
 static_assert(alignof(test_string<char16_t>) == 4, "");
 static_assert(alignof(test_string<char32_t>) == 4, "");
 static_assert(alignof(small_string<char32_t>) == 4, "");
diff --git a/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp b/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp
index 31f1a94c73216..73d0702d9f803 100644
--- a/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp
@@ -52,6 +52,9 @@ class small_iter_allocator {
 template <class CharT>
 using min_string = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT> >;
 
+template <class CharT>
+using fancy_string = std::basic_string<CharT, std::char_traits<CharT>, fancy_pointer_allocator<CharT> >;
+
 template <class CharT>
 using test_string = std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT> >;
 
@@ -62,6 +65,9 @@ using small_string = std::basic_string<CharT, std::char_traits<CharT>, small_ite
 
 static_assert(sizeof(std::string) == 24, "");
 static_assert(sizeof(min_string<char>) == 24, "");
+#  if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char>) == 24, "");
+#  endif
 static_assert(sizeof(test_string<char>) == 32, "");
 static_assert(sizeof(small_string<char>) == 6, "");
 
@@ -69,11 +75,17 @@ static_assert(sizeof(small_string<char>) == 6, "");
 #    if __WCHAR_WIDTH__ == 32
 static_assert(sizeof(std::wstring) == 24, "");
 static_assert(sizeof(min_string<wchar_t>) == 24, "");
+#      if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 24, "");
+#      endif
 static_assert(sizeof(test_string<wchar_t>) == 32, "");
 static_assert(sizeof(small_string<wchar_t>) == 12, "");
 #    elif __WCHAR_WIDTH__ == 16
 static_assert(sizeof(std::wstring) == 24, "");
 static_assert(sizeof(min_string<wchar_t>) == 24, "");
+#      if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 24, "");
+#      endif
 static_assert(sizeof(test_string<wchar_t>) == 32, "");
 static_assert(sizeof(small_string<wchar_t>) == 6, "");
 #    else
@@ -84,6 +96,9 @@ static_assert(sizeof(small_string<wchar_t>) == 6, "");
 #  ifndef TEST_HAS_NO_CHAR8_T
 static_assert(sizeof(std::u8string) == 24, "");
 static_assert(sizeof(min_string<char8_t>) == 24, "");
+#    if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char8_t>) == 24, "");
+#    endif
 static_assert(sizeof(test_string<char8_t>) == 32, "");
 static_assert(sizeof(small_string<char8_t>) == 6, "");
 #  endif
@@ -93,6 +108,10 @@ static_assert(sizeof(std::u16string) == 24, "");
 static_assert(sizeof(std::u32string) == 24, "");
 static_assert(sizeof(min_string<char16_t>) == 24, "");
 static_assert(sizeof(min_string<char32_t>) == 24, "");
+#    if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char16_t>) == 24, "");
+static_assert(sizeof(fancy_string<char32_t>) == 24, "");
+#    endif
 static_assert(sizeof(test_string<char16_t>) == 32, "");
 static_assert(sizeof(test_string<char32_t>) == 32, "");
 static_assert(sizeof(small_string<char16_t>) == 6, "");
@@ -103,6 +122,9 @@ static_assert(sizeof(small_string<char32_t>) == 12, "");
 
 static_assert(sizeof(std::string) == 12, "");
 static_assert(sizeof(min_string<char>) == 12, "");
+#  if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char>) == 12, "");
+#  endif
 static_assert(sizeof(test_string<char>) == 24, "");
 static_assert(sizeof(small_string<char>) == 6, "");
 
@@ -110,11 +132,17 @@ static_assert(sizeof(small_string<char>) == 6, "");
 #    if __WCHAR_WIDTH__ == 32
 static_assert(sizeof(std::wstring) == 12, "");
 static_assert(sizeof(min_string<wchar_t>) == 12, "");
+#      if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 12, "");
+#      endif
 static_assert(sizeof(test_string<wchar_t>) == 24, "");
 static_assert(sizeof(small_string<wchar_t>) == 12, "");
 #    elif __WCHAR_WIDTH__ == 16
 static_assert(sizeof(std::wstring) == 12, "");
 static_assert(sizeof(min_string<wchar_t>) == 12, "");
+#      if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<wchar_t>) == 12, "");
+#      endif
 static_assert(sizeof(test_string<wchar_t>) == 24, "");
 static_assert(sizeof(small_string<wchar_t>) == 6, "");
 #    else
@@ -125,6 +153,9 @@ static_assert(sizeof(small_string<wchar_t>) == 6, "");
 #  ifndef TEST_HAS_NO_CHAR8_T
 static_assert(sizeof(std::u8string) == 12, "");
 static_assert(sizeof(min_string<char8_t>) == 12, "");
+#    if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char8_t>) == 12, "");
+#    endif
 static_assert(sizeof(test_string<char8_t>) == 24, "");
 static_assert(sizeof(small_string<char>) == 6, "");
 #  endif
@@ -134,6 +165,10 @@ static_assert(sizeof(std::u16string) == 12, "");
 static_assert(sizeof(std::u32string) == 12, "");
 static_assert(sizeof(min_string<char16_t>) == 12, "");
 static_assert(sizeof(min_string<char32_t>) == 12, "");
+#    if TEST_STD_VER >= 11
+static_assert(sizeof(fancy_string<char16_t>) == 12, "");
+static_assert(sizeof(fancy_string<char32_t>) == 12, "");
+#    endif
 static_assert(sizeof(test_string<char16_t>) == 24, "");
 static_assert(sizeof(test_string<char32_t>) == 24, "");
 static_assert(sizeof(small_string<char16_t>) == 6, "");
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp
index 36a485a1e4d00..975414643b73b 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -29,6 +30,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp
index d810acd67e7e7..40496f3b7c57d 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -29,6 +30,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp
index 12e7ef3328b04..0fa0d2ffe29f5 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -29,6 +30,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp
index 3983352712963..a34ef54ac4804 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp
@@ -20,6 +20,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -31,6 +32,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp
index 24df3fcad0c5c..bdb239d56145c 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp
@@ -20,6 +20,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -30,6 +31,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp
index d26997d8d24c2..1227225bcae3b 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp
@@ -20,6 +20,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -31,6 +32,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
index d4a0b318f36d7..f346a2cd2b38a 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.cons/copy_shrunk_long.pass.cpp
@@ -35,10 +35,12 @@ int main(int, char**) {
   test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 #if TEST_STD_VER > 17
   static_assert(test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>());
   static_assert(test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>());
+  static_assert(test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >());
 #endif
 
   return 0;
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
index 56c9d63d0dbaf..313681dce1622 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.add.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class C>
 void test() {
@@ -32,6 +33,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
index 43a9739bf936f..43d80c554e2f2 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.decrement.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class C>
 void test() {
@@ -31,6 +32,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
index e2326be021033..7969d766be1a7 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.dereference.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class C>
 void test() {
@@ -28,6 +29,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp
index a7453f3115197..e234050672564 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.increment.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class C>
 void test() {
@@ -31,6 +32,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp
index e7d384413b589..d3bce9f32e8c9 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/assert.iterator.index.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class C>
 void test() {
@@ -32,6 +33,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp
index c55410edf4eba..aa99d18a0c201 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.compare.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -28,6 +29,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp
index d3274cbd90cc5..2f60065dc324b 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.iterators/debug.iterator.subtract.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -28,6 +29,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp
index 036e75965c488..9bab6a14e6a00 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -30,6 +31,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp
index 54c011c4d54a0..9061569bdf55c 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp
@@ -18,6 +18,7 @@
 #include <string>
 
 #include "check_assertion.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -27,6 +28,7 @@ void test() {
 
 int main(int, char**) {
   test<std::string>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp
index 93fd6caf0ba23..4fc4be6bfaf67 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -30,6 +31,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp
index ed97e21d9411e..29954095f3b22 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.erase.iter_iter.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "check_assertion.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -56,6 +57,7 @@ void test() {
 int main(int, char**) {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp
index 561f79e0e18fb..946839aea6612 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_char.pass.cpp
@@ -22,6 +22,7 @@
 #include <string>
 
 #include "check_assertion.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -34,6 +35,7 @@ void test() {
 
 int main(int, char**) {
   test<std::string>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp
index eef525349972b..baff22ee85a44 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_iter_iter.pass.cpp
@@ -17,6 +17,7 @@
 #include <string>
 
 #include "check_assertion.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -30,6 +31,7 @@ void test() {
 
 int main(int, char**) {
   test<std::string>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp
index 4b7532678f2e5..4b1ed1b82ebad 100644
--- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp
+++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/debug.insert.iter_size_char.pass.cpp
@@ -16,6 +16,7 @@
 #include <string>
 
 #include "check_assertion.h"
+#include "test_allocator.h"
 
 template <class S>
 void test() {
@@ -27,6 +28,7 @@ void test() {
 
 int main(int, char**) {
   test<std::string>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return 0;
 }
diff --git a/libcxx/test/std/containers/from_range_helpers.h b/libcxx/test/std/containers/from_range_helpers.h
index edf1d6ce528d7..05a3edfac02a7 100644
--- a/libcxx/test/std/containers/from_range_helpers.h
+++ b/libcxx/test/std/containers/from_range_helpers.h
@@ -100,12 +100,14 @@ constexpr void for_all_iterators_and_allocators(Func f) {
     f.template operator()<Iter, sentinel_wrapper<Iter>, std::allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, test_allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, min_allocator<T>>();
+    f.template operator()<Iter, sentinel_wrapper<Iter>, fancy_pointer_allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, safe_allocator<T>>();
 
     if constexpr (std::sentinel_for<Iter, Iter>) {
       f.template operator()<Iter, Iter, std::allocator<T>>();
       f.template operator()<Iter, Iter, test_allocator<T>>();
       f.template operator()<Iter, Iter, min_allocator<T>>();
+      f.template operator()<Iter, Iter, fancy_pointer_allocator<T>>();
       f.template operator()<Iter, Iter, safe_allocator<T>>();
     }
   });
diff --git a/libcxx/test/std/containers/insert_range_helpers.h b/libcxx/test/std/containers/insert_range_helpers.h
index 4fbb128d91dc8..6c90f623e7326 100644
--- a/libcxx/test/std/containers/insert_range_helpers.h
+++ b/libcxx/test/std/containers/insert_range_helpers.h
@@ -85,12 +85,14 @@ constexpr void for_all_iterators_and_allocators(Func f) {
     f.template operator()<Iter, sentinel_wrapper<Iter>, std::allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, test_allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, min_allocator<T>>();
+    f.template operator()<Iter, sentinel_wrapper<Iter>, fancy_pointer_allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, safe_allocator<T>>();
 
     if constexpr (std::sentinel_for<Iter, Iter>) {
       f.template operator()<Iter, Iter, std::allocator<T>>();
       f.template operator()<Iter, Iter, test_allocator<T>>();
       f.template operator()<Iter, Iter, min_allocator<T>>();
+      f.template operator()<Iter, Iter, fancy_pointer_allocator<T>>();
       f.template operator()<Iter, Iter, safe_allocator<T>>();
     }
   });
@@ -109,12 +111,14 @@ constexpr void for_all_iterators_and_allocators_constexpr(Func f) {
     f.template operator()<Iter, sentinel_wrapper<Iter>, std::allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, test_allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, min_allocator<T>>();
+    f.template operator()<Iter, sentinel_wrapper<Iter>, fancy_pointer_allocator<T>>();
     f.template operator()<Iter, sentinel_wrapper<Iter>, safe_allocator<T>>();
 
     if constexpr (std::sentinel_for<Iter, Iter>) {
       f.template operator()<Iter, Iter, std::allocator<T>>();
       f.template operator()<Iter, Iter, test_allocator<T>>();
       f.template operator()<Iter, Iter, min_allocator<T>>();
+      f.template operator()<Iter, Iter, fancy_pointer_allocator<T>>();
       f.template operator()<Iter, Iter, safe_allocator<T>>();
     }
   });
diff --git a/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp b/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
index 643c6bec637ae..fff07d97b1b59 100644
--- a/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
+++ b/libcxx/test/std/strings/basic.string.hash/enabled_hashes.pass.cpp
@@ -63,6 +63,7 @@ int main(int, char**) {
     test_hash_enabled<std::u16string>();
     test_hash_enabled<std::u32string>();
     test_hash_enabled<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>();
+    test_hash_enabled<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
     test_hash_disabled<std::basic_string<MyChar, std::char_traits<MyChar>, std::allocator<MyChar>>>();
     test_hash_disabled<std::basic_string<char, constexpr_char_traits<char>, std::allocator<char>>>();
   }
diff --git a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp
index 52c0646c7d7c5..f1ffeffb11eae 100644
--- a/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/at.pass.cpp
@@ -16,6 +16,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 #include "make_string.h"
 #include "test_macros.h"
@@ -61,6 +62,7 @@ struct TestCaller {
     test_string<std::basic_string<T> >();
 #if TEST_STD_VER >= 11
     test_string<std::basic_string<T, std::char_traits<T>, min_allocator<T> > >();
+    test_string<std::basic_string<T, std::char_traits<T>, fancy_pointer_allocator<T> > >();
 #endif
   }
 };
diff --git a/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp
index 2f0c282c8e436..e0d31336c0eed 100644
--- a/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/back.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s) {
@@ -40,6 +41,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp
index 809b0399dc70f..d229a4a2f757e 100644
--- a/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/front.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s) {
@@ -40,6 +41,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp b/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp
index 8ba8bf0c8b096..d294e052cfb8e 100644
--- a/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.access/index.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_string() {
@@ -58,7 +59,9 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string_long<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string_long<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
index 61867cfb087b9..1bf547e00a2de 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/capacity.pass.cpp
@@ -68,6 +68,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>());
   test_string(test_allocator<char>(3));
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
   test_string(safe_allocator<char>());
 
   {
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp
index 643ea4a3bdad4..1f1fba676c2f7 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/clear.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp
index b4700d68a59af..c8a4914ec3dbb 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/empty.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s) {
@@ -33,6 +34,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp
index e873f82c4830b..0f0ff13a67d1c 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/length.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s) {
@@ -32,6 +33,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
index 45a52acab464e..f0d07b01c785c 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -25,6 +25,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_resize_max_size_minus_1(const S& s) {
@@ -85,6 +86,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, tiny_size_allocator<64, char> > >();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
index 8e5919539d94e..cdb99dacc38e7 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/over_max_size.pass.cpp
@@ -26,6 +26,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 void test(const S& s) {
@@ -51,6 +52,7 @@ bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/reserve.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
index 43414da3794a5..6667d9202a3b2 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/reserve.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -49,6 +50,7 @@ bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
index cb1e6b18ed450..70c989125d525 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/reserve_size.pass.cpp
@@ -20,6 +20,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -90,6 +91,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp
index e23b6cf40691f..2b9b821447a58 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_size.pass.cpp
@@ -17,6 +17,7 @@
 #include "asan_testing.h"
 #include "make_string.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 
 template <class S>
@@ -76,6 +77,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator<char> >();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator<char>>();
+  test_string<char, fancy_pointer_allocator<char>>();
   test_string<char, safe_allocator<char>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp
index e3b925ca8bcdb..fd43e28bd247e 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/resize_size_char.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -75,6 +76,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
index 230852445e92b..b7fcee0c86b7e 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp
@@ -16,6 +16,7 @@
 #include "asan_testing.h"
 #include "increasing_allocator.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 
 template <class S>
@@ -58,6 +59,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp b/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp
index 9d53971779b64..e1be04a13427c 100644
--- a/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.capacity/size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s, typename S::size_type c) {
@@ -32,6 +33,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp
index dcf697bed752f..e4466449805e5 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/T_size_size.pass.cpp
@@ -115,6 +115,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(8));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
   test_string(safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp
index 91beac37764db..445d0802948cd 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/alloc.pass.cpp
@@ -94,6 +94,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
 #if TEST_STD_VER >= 11
   test2<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test2<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test2<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
   test2<std::basic_string<char, std::char_traits<char>, explicit_allocator<char> > >();
 #endif
diff --git a/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp
index 1019dc8bca5df..28fec5760619a 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/char_assignment.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -40,6 +41,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp
index f65f8e97c9824..2478046a40c09 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/copy.pass.cpp
@@ -43,6 +43,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(3));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
   test_string(safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp
index c4fd5afe83a44..00463aa020359 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/copy_alloc.pass.cpp
@@ -92,6 +92,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(3));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
   test_string(safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp
index 2e98fccb5394b..e34ea3bf1778e 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/copy_assignment.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -50,6 +51,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/default.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/default.pass.cpp
index fc263f9820cb5..5d72d5bf316f5 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/default.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/default.pass.cpp
@@ -23,6 +23,9 @@ LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<std::string>::value,
 LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<
                          std::basic_string<char, std::char_traits<char>, test_allocator<char>>>::value,
                      "");
+LIBCPP_STATIC_ASSERT(std::is_nothrow_default_constructible<
+                         std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>::value,
+                     "");
 LIBCPP_STATIC_ASSERT(!std::is_nothrow_default_constructible<
                          std::basic_string<char, std::char_traits<char>, limited_allocator<char, 10>>>::value,
                      "");
diff --git a/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp
index d5c1f4d9348b8..929e09e385647 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/dtor.pass.cpp
@@ -37,6 +37,9 @@ std::wstring unused_wide_string;
 static_assert(std::is_nothrow_destructible<std::string>::value, "");
 static_assert(
     std::is_nothrow_destructible< std::basic_string<char, std::char_traits<char>, test_allocator<char>>>::value, "");
+static_assert(std::is_nothrow_destructible<
+                  std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>::value,
+              "");
 LIBCPP_STATIC_ASSERT(
     !std::is_nothrow_destructible< std::basic_string<char, std::char_traits<char>, throwing_alloc<char>>>::value, "");
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp
index ebdcc523f055d..d598e1ae640e0 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/initializer_list.pass.cpp
@@ -51,6 +51,7 @@ TEST_CONSTEXPR_CXX20 void test_string() {
 TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::allocator>();
   test_string<min_allocator>();
+  test_string<fancy_pointer_allocator>();
   test_string<safe_allocator>();
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp
index a3491696a4fc8..d4c95aa8ce51b 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/initializer_list_assignment.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 // clang-format off
@@ -65,6 +66,7 @@ TEST_CONSTEXPR_CXX20 void test_string() {
 TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::allocator>();
   test_string<min_allocator>();
+  test_string<fancy_pointer_allocator>();
   test_string<safe_allocator>();
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp
index e14227d1a7717..4cac882d5d5e0 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc.pass.cpp
@@ -93,6 +93,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(2));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
 #endif
   {
     static_assert((!std::is_constructible<std::string, std::string, std::string>::value), "");
diff --git a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp
index d47c9dfded226..964603a979ab3 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.pass.cpp
@@ -105,6 +105,17 @@ TEST_CONSTEXPR_CXX20 bool test() {
     assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
     LIBCPP_ASSERT(is_string_asan_correct(s1));
   }
+  {
+    const char32_t* s = U"12345678901234";
+    std::basic_string s1{s, s + 10, fancy_pointer_allocator<char32_t>{}};
+    using S = decltype(s1); // what type did we get?
+    static_assert(std::is_same_v<S::value_type, char32_t>, "");
+    static_assert(std::is_same_v<S::traits_type, std::char_traits<char32_t>>, "");
+    static_assert(std::is_same_v<S::allocator_type, fancy_pointer_allocator<char32_t>>, "");
+    assert(s1.size() == 10);
+    assert(s1.compare(0, s1.size(), s, s1.size()) == 0);
+    LIBCPP_ASSERT(is_string_asan_correct(s1));
+  }
   {
     const char32_t* s = U"12345678901234";
     std::basic_string s1{s, s + 10, explicit_allocator<char32_t>{}};
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp
index 5d2d774b36063..6238322471be8 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move.pass.cpp
@@ -47,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>());
   test_string(test_allocator<char>(3));
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
 
   return true;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
index 93a8e59349634..dfc3aaae24e3f 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
@@ -70,6 +70,18 @@ TEST_CONSTEXPR_CXX20 bool test() {
     static_assert((noexcept(S{})), "");
 #elif TEST_STD_VER >= 11
     static_assert((noexcept(S()) == std::is_nothrow_move_constructible<A>::value), "");
+#endif
+    test(S(), A());
+    test(S("1"), A());
+    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
+  }
+  {
+    typedef fancy_pointer_allocator<char> A;
+    typedef std::basic_string<char, std::char_traits<char>, A> S;
+#if TEST_STD_VER > 14
+    static_assert((noexcept(S{})), "");
+#elif TEST_STD_VER >= 11
+    static_assert((noexcept(S()) == std::is_nothrow_move_constructible<A>::value), "");
 #endif
     test(S(), A());
     test(S("1"), A());
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp
index bba86b3acffee..551de2b3f4a66 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_assign_noexcept.pass.cpp
@@ -68,6 +68,10 @@ TEST_CONSTEXPR_CXX20 bool test() {
     typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C;
     static_assert(!std::is_nothrow_move_assignable<C>::value, "");
   }
+  {
+    typedef std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>> C;
+    static_assert(std::is_nothrow_move_assignable<C>::value, "");
+  }
   {
     typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
 #if TEST_STD_VER > 14
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp
index 9af9abdfc449c..67232030d373e 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_assignment.pass.cpp
@@ -56,6 +56,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
index d807cac2c72c8..c408508e8f21a 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
@@ -30,6 +30,10 @@ int main(int, char**) {
     typedef std::basic_string<char, std::char_traits<char>, test_allocator<char>> C;
     static_assert(std::is_nothrow_move_constructible<C>::value, "");
   }
+  {
+    typedef std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>> C;
+    static_assert(std::is_nothrow_move_constructible<C>::value, "");
+  }
   {
     typedef std::basic_string<char, std::char_traits<char>, limited_allocator<char, 10>> C;
 #if TEST_STD_VER <= 14
diff --git a/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp
index d5d5152e11e54..2b9780bb72db1 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_alloc.pass.cpp
@@ -70,6 +70,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test(test_allocator<char>(2));
 #if TEST_STD_VER >= 11
   test(min_allocator<char>());
+  test(fancy_pointer_allocator<char>());
   test(safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp
index 98430cdd6ab99..91e8899a23afe 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_assignment.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -51,6 +52,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp
index b6ba2be46d18b..e6c1cfff7ec8c 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/pointer_size_alloc.pass.cpp
@@ -67,6 +67,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test(test_allocator<char>(2));
 #if TEST_STD_VER >= 11
   test(min_allocator<char>());
+  test(fancy_pointer_allocator<char>());
   test(safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
index a87e01f0fc088..6cc7bbc039e04 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/size_char_alloc.pass.cpp
@@ -97,6 +97,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(2));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
   test_string(safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp
index ad37b50b83ba7..9625e5d1b6455 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view.pass.cpp
@@ -98,6 +98,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(2));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
   test_string(safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp
index 2e6c54a584b6e..7f75288f2925e 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_assignment.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(S s1, SV sv) {
@@ -51,6 +52,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
index a19564b98b283..33de5d6741c66 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_deduction.pass.cpp
@@ -101,6 +101,16 @@ TEST_CONSTEXPR_CXX20 bool test() {
     assert(s1.size() == sv.size());
     assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
   }
+  {
+    std::u32string_view sv = U"12345678901234";
+    std::basic_string s1{sv, fancy_pointer_allocator<char32_t>{}};
+    using S = decltype(s1); // what type did we get?
+    static_assert(std::is_same_v<S::value_type, char32_t>, "");
+    static_assert(std::is_same_v<S::traits_type, std::char_traits<char32_t>>, "");
+    static_assert(std::is_same_v<S::allocator_type, fancy_pointer_allocator<char32_t>>, "");
+    assert(s1.size() == sv.size());
+    assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
+  }
   {
     std::u32string_view sv = U"12345678901234";
     std::basic_string s1{sv, explicit_allocator<char32_t>{}};
diff --git a/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
index e36503d92be18..9fa536b89b72c 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/string_view_size_size_deduction.pass.cpp
@@ -108,6 +108,16 @@ TEST_CONSTEXPR_CXX20 bool test() {
     assert(s1.size() == 4);
     assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
   }
+  {
+    std::u32string_view sv = U"12345678901234";
+    std::basic_string s1{sv, 0, 4, fancy_pointer_allocator<char32_t>{}};
+    using S = decltype(s1); // what type did we get?
+    static_assert(std::is_same_v<S::value_type, char32_t>, "");
+    static_assert(std::is_same_v<S::traits_type, std::char_traits<char32_t>>, "");
+    static_assert(std::is_same_v<S::allocator_type, fancy_pointer_allocator<char32_t>>, "");
+    assert(s1.size() == 4);
+    assert(s1.compare(0, s1.size(), sv.data(), s1.size()) == 0);
+  }
   {
     std::u32string_view sv = U"12345678901234";
     std::basic_string s1{sv, 0, 4, explicit_allocator<char32_t>{}};
diff --git a/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp
index cafd9674f4898..948e54b54458d 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/substr.pass.cpp
@@ -168,6 +168,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(3), test_allocator<char>(5));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>(), min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>(), fancy_pointer_allocator<char>());
   test_string(safe_allocator<char>(), safe_allocator<char>());
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp b/libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp
index 9c7c341302df9..0004c03d15787 100644
--- a/libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.cons/substr_rvalue.pass.cpp
@@ -212,6 +212,7 @@ template <class CharT, class CharTraits>
 constexpr void test_allocators() {
   test_string<std::basic_string<CharT, CharTraits, std::allocator<CharT>>>(std::allocator<CharT>{});
   test_string<std::basic_string<CharT, CharTraits, min_allocator<CharT>>>(min_allocator<CharT>{});
+  test_string<std::basic_string<CharT, CharTraits, fancy_pointer_allocator<CharT>>>(fancy_pointer_allocator<CharT>{});
   test_string<std::basic_string<CharT, CharTraits, test_allocator<CharT>>>(test_allocator<CharT>{42});
   test_string<std::basic_string<CharT, CharTraits, operator_hijacker_allocator<CharT>>>(
       operator_hijacker_allocator<CharT>{});
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp
index 202a87dd777b3..0da516f14b65e 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/begin.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s) {
@@ -38,6 +39,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp
index df2c38476197e..cd3afb59789bd 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/cbegin.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s) {
@@ -35,6 +36,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp
index 31d06725e5107..b794408e5ebee 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/cend.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s) {
@@ -32,6 +33,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp
index 85b33afeb403e..84aae817b597e 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/crbegin.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s) {
@@ -35,6 +36,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp
index 5d1f90c409bc4..3e40a30f75038 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/crend.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s) {
@@ -32,6 +33,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp
index 2c3e3b1287215..2a72ed0326efd 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/end.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s) {
@@ -41,6 +42,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp
index feaea2f65790c..c07ccb1faf6c2 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/rbegin.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s) {
@@ -38,6 +39,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp
index d34ee26fd9d04..1e20f95cd9d98 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/rend.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s) {
@@ -41,6 +42,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp
index e43c36c31e483..6a70e0c17ae1a 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/T_size_size.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(S s, SV sv, typename S::size_type pos, typename S::size_type n, S expected) {
@@ -91,6 +92,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   {
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
index d494cd0435b96..aa819545a9a18 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "nasty_string.h"
 #include "asan_testing.h"
 
@@ -42,6 +43,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test<std::u32string>();
 
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #if TEST_STD_VER >= 20
   test<nasty_string>();
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
index 82f4f2de760c9..57b8e1ab114b3 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "test_iterators.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S, class It>
@@ -228,6 +229,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
index af334eb080c37..b454a6ba6730c 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -45,6 +46,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
index 8a13f11cf156f..81d57bf260e87 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/pointer_size.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -68,6 +69,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
index 8c2324c9d1759..249a762454d41 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/push_back.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 struct VeryLarge {
@@ -78,6 +79,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
 #endif
   {
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
index a898efcf21855..bc490352872f3 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/size_char.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -51,6 +52,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
index 66a2dc26341f8..266633e7955f6 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -61,6 +62,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
index d30f13d96b5b8..affba8ae96938 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_size_size.pass.cpp
@@ -18,6 +18,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -96,6 +97,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp
index 9de48ca2463e2..d4d6e62a93964 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/string_view.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(S s, SV sv, S expected) {
@@ -61,6 +62,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp
index b35f6b9497d03..7648302275418 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/T_size_size.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(S s, SV sv, typename S::size_type pos, typename S::size_type n, S expected) {
@@ -88,6 +89,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   {
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
index 47a59e8997e62..a4da91fc1f7cc 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/initializer_list.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_string() {
@@ -39,10 +40,9 @@ TEST_CONSTEXPR_CXX20 void test_string() {
 
 TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
-#if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
-#endif
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return true;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
index b2306807fcf7b..73b3f47d881b6 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "asan_testing.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 #include "test_iterators.h"
 
@@ -174,6 +175,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
index 0d5c269d30df4..8549f137a946e 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer.pass.cpp
@@ -17,6 +17,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, const typename S::value_type* str, S expected) {
@@ -51,6 +52,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   { // test assignment to self
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
index 1f40898b71bfe..810032708b19b 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/pointer_size.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, const typename S::value_type* str, typename S::size_type n, S expected) {
@@ -57,6 +58,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   { // test assign to self
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
index a33e8e97157c4..cf87524b0d9fd 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/rv_string.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, S str, S expected) {
@@ -52,6 +53,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
index 3c7651135f1aa..8b0dd89648baa 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/size_char.pass.cpp
@@ -17,6 +17,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type n, typename S::value_type c, S expected) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
index edd3913fa01f6..0543df642cd52 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp
@@ -107,6 +107,14 @@ TEST_CONSTEXPR_CXX20 bool test() {
     testAlloc(S(), S("1234567890"), min_allocator<char>());
     testAlloc(S(), S("12345678901234567890"), min_allocator<char>());
   }
+  {
+    typedef std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>> S;
+    test_assign<S>();
+    testAlloc(S(), S(), fancy_pointer_allocator<char>());
+    testAlloc(S(), S("12345"), fancy_pointer_allocator<char>());
+    testAlloc(S(), S("1234567890"), fancy_pointer_allocator<char>());
+    testAlloc(S(), S("12345678901234567890"), fancy_pointer_allocator<char>());
+  }
 #endif
 #if TEST_STD_VER > 14
   {
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
index 1cd2368b2a6b3..efd7909643e43 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_size_size.pass.cpp
@@ -19,6 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, S str, typename S::size_type pos, typename S::size_type n, S expected) {
@@ -88,6 +89,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   {
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp
index aeda9db36a840..3ff71a929ba6d 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/string_view.pass.cpp
@@ -69,6 +69,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp
index 0d7221ced8034..67729e30c492c 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_copy/copy.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S str, typename S::value_type* s, typename S::size_type n, typename S::size_type pos) {
@@ -115,6 +116,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
index b724973150296..68f90e5dfa569 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::difference_type pos, S expected) {
@@ -49,6 +50,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
index 5270335aa9ff3..8d46e61b77476 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/iter_iter.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::difference_type pos, typename S::difference_type n, S expected) {
@@ -92,6 +93,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
index f52512231e094..619aea72aa316 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, S expected) {
@@ -40,6 +41,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
index 97acffd484e64..c51c9497aaf32 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_erase/size_size.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos, typename S::size_type n, S expected) {
@@ -183,6 +184,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
index 1d8c7e06ed8c3..37911f54e4ecc 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
@@ -17,6 +17,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S& s, typename S::const_iterator p, typename S::value_type c, S expected) {
@@ -74,6 +75,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
index 769bd7c4274ff..1ec1c493a7e36 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_string() {
@@ -37,6 +38,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return true;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
index e228ccac20574..82716ff2d5296 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "asan_testing.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "test_iterators.h"
 #include "test_macros.h"
 
@@ -150,7 +151,8 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
-  test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
 #ifndef TEST_HAS_NO_EXCEPTIONS
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
index 6937ccc0d540a..3f24c630c886b 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -101,6 +102,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_T_size_size.pass.cpp
index f7e6ca71180e3..b0a19f977d4d5 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_T_size_size.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void
@@ -1858,6 +1859,8 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>,
        std::basic_string_view<char, std::char_traits<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>,
+       std::basic_string_view<char, std::char_traits<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
index 9e2d00279b96d..c42e26fb05139 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos, const typename S::value_type* str, S expected) {
@@ -131,6 +132,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   { // test inserting into self
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
index 3e581b56a6390..f04d365e28bda 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_pointer_size.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -391,11 +392,13 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
 #if TEST_STD_VER > 17
   static_assert(test<std::string>());
   static_assert(test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>());
+  static_assert(test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>());
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
index f18ef484b5a04..e13083a389fc4 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_size_char.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -132,6 +133,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
index 49870ba05e357..62724e038a81e 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos, S str, S expected) {
@@ -131,6 +132,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
 #if TEST_STD_VER >= 11
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
index 2c0579485d0fb..14cf20085a515 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/size_string_size_size.pass.cpp
@@ -20,6 +20,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -1819,6 +1820,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp
index 7c0f157bc3230..699b88bec5813 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/string_view.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos, SV sv, S expected) {
@@ -129,6 +130,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   { // test inserting into self
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp
index 753c38fa232b3..c049eb1eb6c29 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/char.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::value_type str, S expected) {
@@ -39,6 +40,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp
index 165fb2f96313b..14e9610ac2412 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/initializer_list.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_string() {
@@ -45,6 +46,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   return true;
 }
 
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp
index 4231b0c6cd8d6..c260e3da8274b 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/pointer.pass.cpp
@@ -16,6 +16,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, const typename S::value_type* str, S expected) {
@@ -63,6 +64,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp
index 0aee67f27fb05..dbbcda9dd3240 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_op_plus_equal/string.pass.cpp
@@ -17,6 +17,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, S str, S expected) {
@@ -64,6 +65,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s;
     s += {"abc", 1};
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
index efc21725ee24c..41210a319bd3b 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_initializer_list.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_string() {
@@ -28,6 +29,7 @@ TEST_CONSTEXPR_CXX20 void test_string() {
 TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 
   return true;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
index ba91e0bd56f00..fadfeb639a1f6 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
@@ -20,6 +20,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "test_iterators.h"
+#include "test_allocator.h"
 
 template <class S, class It>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos1, typename S::size_type n1, It f, It l, S expected) {
@@ -1065,6 +1066,7 @@ int main(int, char**) {
   test<std::string>();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp
index fa13ca8062b2a..a7793fae3763b 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -299,6 +300,7 @@ int main(int, char**) {
   test<std::string>();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
index 45d57c793a335..2ddf6ffe55be9 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -1004,6 +1005,7 @@ int main(int, char**) {
   test<std::string>();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp
index dd87da1e25354..4cd17627be91c 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -285,7 +286,8 @@ int main(int, char**) {
   test<std::string>();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return 0;
-}
+}
\ No newline at end of file
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp
index eb0c62a66504c..5c28589e7ca32 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos1, typename S::size_type n1, S str, S expected) {
@@ -295,6 +296,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp
index 767ed41ae2247..d741aa0c0062c 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_string_view.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos1, typename S::size_type n1, SV sv, S expected) {
@@ -283,6 +284,7 @@ int main(int, char**) {
   test<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test<char, min_allocator>();
+  test<char, fancy_pointer_allocator>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp
index df08ae675a11e..8c25ce94922a2 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_T_size_size.pass.cpp
@@ -24,6 +24,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void
@@ -6282,6 +6283,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<char, min_allocator>();
   test<char, safe_allocator>();
+  test<char, fancy_pointer_allocator>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp
index aefe3ced9765e..f60cab2e58811 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer.pass.cpp
@@ -19,6 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -380,6 +381,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp
index cb01c34e43d4a..9cf1696799356 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_pointer_size.pass.cpp
@@ -19,6 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -1344,6 +1345,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp
index 67e9316794225..f024da04cb95d 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_size_char.pass.cpp
@@ -19,6 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -384,6 +385,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp
index 47fe7030c83b3..9aba8dabcbde3 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string.pass.cpp
@@ -19,6 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos1, typename S::size_type n1, S str, S expected) {
@@ -388,6 +389,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp
index 48645f6280990..dc1c026c0de51 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_size_size.pass.cpp
@@ -23,6 +23,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -6102,6 +6103,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
   test<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp
index 7f17160419065..97987eae72afc 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/size_size_string_view.pass.cpp
@@ -19,6 +19,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(S s, typename S::size_type pos1, typename S::size_type n1, SV sv, S expected) {
@@ -379,6 +380,7 @@ int main(int, char**) {
 #if TEST_STD_VER >= 11
   test<char, min_allocator>();
   test<char, safe_allocator>();
+  test<char, fancy_pointer_allocator>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
index 9af110a8920d6..8a12dc042295e 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_swap/swap.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 #include "operator_hijacker.h"
 
@@ -62,6 +63,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, operator_hijacker_allocator<char>>>();
 #endif
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp
index 28b1f9b67f28d..527bbf5fbf331 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "make_string.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "stream_types.h"
 #include "test_macros.h"
 
@@ -119,6 +120,7 @@ int main(int, char**) {
   test_alloc<std::allocator>();
 #if TEST_STD_VER >= 11
   test_alloc<min_allocator>();
+  test_alloc<fancy_pointer_allocator>();
 #endif
   test_tiny_allocator();
 
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp
index 97a55fa09d14d..87962e85cdf1c 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "min_allocator.h"
 #include "test_macros.h"
+#include "test_allocator.h"
 
 template <template <class> class Alloc>
 void test_string() {
@@ -150,6 +151,7 @@ int main(int, char**) {
   test_string<std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<min_allocator>();
+  test_string<fancy_pointer_allocator>();
 #endif
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp
index 1cd50a4c8940c..275274606e60e 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim_rv.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <template <class> class Alloc>
 void test() {
@@ -42,6 +43,7 @@ int main(int, char**) {
   test<std::allocator>();
 #if TEST_STD_VER >= 11
   test<min_allocator>();
+  test<fancy_pointer_allocator>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp
index ff100f9234bef..dac37ff415388 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_rv.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <template <class> class Alloc>
 void test() {
@@ -41,6 +42,9 @@ void test() {
 int main(int, char**) {
   test<std::allocator>();
   test<min_allocator>();
+#if TEST_STD_VER >= 11
+  test<fancy_pointer_allocator>();
+#endif // TEST_STD_VER >= 11
 
   return 0;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp
index fde4990c9cafb..e04f11b115015 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "min_allocator.h"
 #include "test_macros.h"
+#include "test_allocator.h"
 
 template <template <class> class Alloc>
 void test_string() {
@@ -115,6 +116,7 @@ int main(int, char**) {
   test_string<std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<min_allocator>();
+  test_string<fancy_pointer_allocator>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp
index c66f15213ff2f..89b46d41a5e7a 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_insert.pass.cpp
@@ -19,6 +19,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <template <class> class Alloc>
 void test() {
@@ -65,6 +66,7 @@ int main(int, char**) {
 
 #if TEST_STD_VER >= 11
   test<min_allocator>();
+  test<fancy_pointer_allocator>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp
index c807007fea352..8995477d9955d 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.special/swap.pass.cpp
@@ -20,6 +20,7 @@
 #include "test_macros.h"
 #include "min_allocator.h"
 #include "asan_testing.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(S s1, S s2) {
@@ -63,6 +64,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp
index 11cfcfcf42995..bd77ce2e59ea7 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/pointer_string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const typename S::value_type* lhs, const S& rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp
index c04c06243cd25..c7429e8cc1c70 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_pointer.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const typename S::value_type* rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp
index 881770e421bb0..5081cc6958257 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp
index 1595ec501f4e9..da6a3c86fbb4e 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_string_view.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, SV rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp
index 246b98bc5e107..35bd322002cdc 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op!=/string_view_string.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(SV lhs, const S& rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp
index 333787a0a0766..96e8eb2a18628 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/char_string.pass.cpp
@@ -22,6 +22,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "asan_testing.h"
 
 template <class S>
@@ -48,6 +49,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp
index 400b5165036ed..7ee72575ba2db 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/pointer_string.pass.cpp
@@ -22,6 +22,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_string() {
@@ -59,6 +60,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   { // check that growing to max_size() works
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp
index 20ac1fb4cc723..3600e2a77fca7 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_char.pass.cpp
@@ -22,6 +22,7 @@
 
 #include "asan_testing.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 
 template <class S>
@@ -48,6 +49,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp
index 215a98223814b..2e98b5e7913fc 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_pointer.pass.cpp
@@ -22,6 +22,7 @@
 
 #include "asan_testing.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 
 template <class S>
@@ -73,6 +74,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char> > >();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp
index 082b0007498f5..a559eccdfc858 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_op+/string_string.pass.cpp
@@ -34,6 +34,7 @@
 
 #include "asan_testing.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 #include "test_macros.h"
 
 template <class S>
@@ -83,6 +84,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
 #endif
 
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp
index a8114af2600ca..e32beb04f45de 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/pointer_string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const typename S::value_type* lhs, const S& rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp
index 8e67e6e81a6e9..b5c4417fc7a82 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_pointer.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const typename S::value_type* rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp
index 31bace312f1df..6f08981e51f5f 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp
index c758c4adfe604..9cd603eaa6007 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_string_view.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, SV rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp
index 39dd627033c48..86615394ce32a 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_operator==/string_view_string.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(SV lhs, const S& rhs, bool x) {
@@ -48,6 +49,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
   return true;
 }
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp
index ce0fbf55b5c51..8fb70310cb3f1 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/pointer_string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const typename S::value_type* lhs, const S& rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp
index 2a77947bc7feb..79468cf9ac5a4 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_pointer.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const typename S::value_type* rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp
index 794f9e76b4e85..b799d1773a8ac 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp
index de06981bb4787..43926e53404f8 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_string_view.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, SV rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp
index 8026777a88db1..c5525240e63eb 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt/string_view_string.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(SV lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp
index 35d3c69785325..0774e120e4f94 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/pointer_string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const typename S::value_type* lhs, const S& rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp
index 3f8883e358da5..50279392b934d 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_pointer.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const typename S::value_type* rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp
index 1dc65bf0b6db0..af17ea82748d9 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp
index 19c96ffb77e79..54fb2f9b174d2 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_string_view.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, SV rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp
index d55b2f8fd34be..c70a90ac4de47 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_opgt=/string_view_string.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(SV lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp
index 0c4dbe2f9193b..abeebad52977b 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/pointer_string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const typename S::value_type* lhs, const S& rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp
index bcdb1091140df..b0a7c29cd8bda 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_pointer.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const typename S::value_type* rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp
index 6ca1dd27f31ab..4f835fdeef2a7 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp
index 56549d1767736..4d39b0baf1b2b 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_string_view.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, SV rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp
index 72e9d4bf96682..9c8503bd2b934 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt/string_view_string.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(SV lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp
index 85c6f04ecc2c1..03679cc700f9f 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/pointer_string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const typename S::value_type* lhs, const S& rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp
index 16db933782329..1689f13dc46d5 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_pointer.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const typename S::value_type* rhs, bool x) {
@@ -46,6 +47,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp
index a970014177915..33c6a1e2f3276 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string.pass.cpp
@@ -17,6 +17,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp
index 2ee253820c11e..24db2ba6c75d1 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_string_view.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& lhs, SV rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp
index 88951e4da9101..a9b74e72c222f 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string_oplt=/string_view_string.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(SV lhs, const S& rhs, bool x) {
@@ -47,6 +48,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp
index 837599ae9ef55..a7053de9512df 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/c_str.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s) {
@@ -39,6 +40,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp
index 27762fbd9390d..d03f03e05fbd5 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/data.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test_const(const S& s) {
@@ -63,6 +64,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp
index a6158aeb38dc2..1d552345f06ab 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string.accessors/get_allocator.pass.cpp
@@ -39,6 +39,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(3));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp
index e1d23924517ff..edf335538910a 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/pointer.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 TEST_CONSTEXPR_CXX20 int sign(int x) {
   if (x == 0)
@@ -54,6 +55,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp
index c6281d9e377f4..b073873baf277 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_T_size_size.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 #include "test_macros.h"
 
@@ -6044,6 +6045,7 @@ int main(int, char**) {
   test<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test<char, min_allocator>();
+  test<char, fancy_pointer_allocator>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp
index d4a5133ed3907..2f44efa443aed 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 #include "test_macros.h"
 
@@ -362,6 +363,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp
index aba230d92e182..c9979cf1dbb7f 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_pointer_size.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 #include "test_macros.h"
 
@@ -1339,6 +1340,7 @@ int main(int, char**) {
   test<std::string>();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp
index 018daaa2f262e..597528472b33e 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 TEST_CONSTEXPR_CXX20 int sign(int x) {
   if (x == 0)
@@ -369,6 +370,7 @@ int main(int, char**) {
   test<std::string>();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s = " !";
     assert(s.compare(0, 1, {"abc", 1}) < 0);
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp
index f5d70b93c979f..35e4be5e3d5ee 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_size_size.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 #include "test_macros.h"
 
@@ -6010,6 +6011,7 @@ int main(int, char**) {
   test<std::string>();
 #if TEST_STD_VER >= 11
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp
index 006f8495886b8..2ed2c7b11fb57 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/size_size_string_view.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 #include "test_macros.h"
 
@@ -364,6 +365,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp
index 7378b604c91c8..2f2fa2679b653 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 TEST_CONSTEXPR_CXX20 int sign(int x) {
   if (x == 0)
@@ -54,6 +55,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s = " !";
     assert(s.compare({"abc", 1}) < 0);
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp
index a03e34328f51a..6cfa314397e5f 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_compare/string_view.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 TEST_CONSTEXPR_CXX20 int sign(int x) {
   if (x == 0)
@@ -57,6 +58,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp
index fd97e5bd6e79c..967f337703bbf 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/char_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -68,6 +69,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp
index 927ec97ae0218..b7b3a627ddf12 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -146,6 +147,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp
index 2da628b8437d5..d66a031744d60 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/pointer_size_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -377,6 +378,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp
index 23e1906943401..de712424a77c6 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) {
@@ -146,6 +147,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s = " !";
     assert(s.find_first_not_of({"abc", 1}) == 0);
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_view_size.pass.cpp
index d63eb8c2f1673..d906496b73da4 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.not.of/string_view_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) {
@@ -149,6 +150,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp
index 100d3f4bf2510..aed0ff6feaea3 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/char_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -66,6 +67,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp
index 6d805393245e7..0977b40cb32fe 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -147,6 +148,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp
index 14d23b8ece135..50f280ac10b02 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/pointer_size_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -377,6 +378,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp
index ed872091dcffe..025b013843f6e 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) {
@@ -146,6 +147,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s = " !";
     assert(s.find_first_of({"abc", 1}) == std::string::npos);
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp
index 541d0f171a91e..fa75567950d19 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.first.of/string_view_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) {
@@ -149,6 +150,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp
index a23206d51430c..e40ebd048711c 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/char_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -66,6 +67,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp
index 1cb761ee31a64..f9332fe48c779 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -147,6 +148,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp
index 4fe72a5a9e5c1..aef6f1ed647e6 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/pointer_size_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -377,6 +378,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp
index ae088ba98b5ff..a200504d26eef 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) {
@@ -146,6 +147,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s = " !";
     assert(s.find_last_not_of({"abc", 1}) == s.size() - 1);
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp
index 478015095a7ac..1bd55b1c51e03 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.not.of/string_view_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) {
@@ -149,6 +150,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp
index fd278d9b917eb..f91f642a125ab 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/char_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -66,6 +67,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp
index f177671e8ebfe..8e6c3339b2a96 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -147,6 +148,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp
index 0dc4f92ba33b7..3d84112961ecb 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/pointer_size_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -377,6 +378,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp
index c4c7c251445fe..d5b86903532d6 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) {
@@ -146,6 +147,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s = " !";
     assert(s.find_last_of({"abc", 1}) == std::string::npos);
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp
index 3eae90abd78fb..b6362909a1e62 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find.last.of/string_view_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) {
@@ -148,6 +149,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp
index c0c89c90b3019..8c4917aa18ee6 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/char_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -66,6 +67,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp
index e07302f2624f4..b66472e2e9bf9 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -151,6 +152,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp
index 5fda0e2af64c7..b420d4d4ab1f6 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/pointer_size_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -377,6 +378,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp
index 4aa4a3f339142..a0a2d07fb8fd1 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) {
@@ -163,6 +164,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 #if TEST_STD_VER >= 11
   { // LWG 2946
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp
index 68c08e2d504bd..45080544c1a1e 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_find/string_view_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) {
@@ -148,6 +149,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp
index b8f2ad0112d4a..94685a493279b 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/char_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -66,6 +67,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp
index 1d396fb6b8efe..3c86a6288b859 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -146,6 +147,7 @@ TEST_CONSTEXPR_CXX20 bool tests() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp
index 8e981a5e1087d..30c5e735e3549 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/pointer_size_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void
@@ -377,6 +378,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp
index f9d09dcabcfd2..42333303177cd 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S>
 TEST_CONSTEXPR_CXX20 void test(const S& s, const S& str, typename S::size_type pos, typename S::size_type x) {
@@ -140,6 +141,7 @@ TEST_CONSTEXPR_CXX20 bool tests() {
   test_string<std::string>();
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char> > >();
   { // LWG 2946
     std::string s = " !";
     assert(s.rfind({"abc", 1}) == std::string::npos);
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp
index e42fd3a0ee2de..0e23762c978c2 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_rfind/string_view_size.pass.cpp
@@ -15,6 +15,7 @@
 
 #include "test_macros.h"
 #include "min_allocator.h"
+#include "test_allocator.h"
 
 template <class S, class SV>
 TEST_CONSTEXPR_CXX20 void test(const S& s, SV sv, typename S::size_type pos, typename S::size_type x) {
@@ -144,6 +145,7 @@ TEST_CONSTEXPR_CXX20 bool tests() {
   test_string<char, std::allocator>();
 #if TEST_STD_VER >= 11
   test_string<char, min_allocator>();
+  test_string<char, fancy_pointer_allocator>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp
index 6a66a0067b390..38088b26d6ddf 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr.pass.cpp
@@ -121,6 +121,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
 #if TEST_STD_VER >= 11
   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
+  test_string<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp b/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp
index 596eb923db310..615c5825c1241 100644
--- a/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.ops/string_substr/substr_rvalue.pass.cpp
@@ -77,6 +77,7 @@ constexpr void test_allocators() {
   test_string<std::basic_string<CharT, CharTraits, std::allocator<CharT>>>();
   test_string<std::basic_string<CharT, CharTraits, min_allocator<CharT>>>();
   test_string<std::basic_string<CharT, CharTraits, test_allocator<CharT>>>();
+  test_string<std::basic_string<CharT, CharTraits, fancy_pointer_allocator<CharT>>>();
 }
 
 template <class CharT>
diff --git a/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp b/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp
index 78908901686cf..51587e731d937 100644
--- a/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.require/contiguous.pass.cpp
@@ -50,6 +50,7 @@ TEST_CONSTEXPR_CXX20 bool test() {
   test_string(test_allocator<char>(3));
 #if TEST_STD_VER >= 11
   test_string(min_allocator<char>());
+  test_string(fancy_pointer_allocator<char>());
 #endif
 
   return true;
diff --git a/libcxx/test/std/strings/basic.string/types.pass.cpp b/libcxx/test/std/strings/basic.string/types.pass.cpp
index 45408fa620298..b11c6e0ffc7ee 100644
--- a/libcxx/test/std/strings/basic.string/types.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/types.pass.cpp
@@ -79,6 +79,7 @@ int main(int, char**) {
   static_assert((std::is_same<std::basic_string<char>::allocator_type, std::allocator<char> >::value), "");
 #if TEST_STD_VER >= 11
   test<std::char_traits<char>, min_allocator<char> >();
+  test<std::char_traits<char>, fancy_pointer_allocator<char> >();
 #endif
 
   return 0;
diff --git a/libcxx/test/std/strings/strings.erasure/erase.pass.cpp b/libcxx/test/std/strings/strings.erasure/erase.pass.cpp
index a5a542b40c52a..2bc0c9883f2ee 100644
--- a/libcxx/test/std/strings/strings.erasure/erase.pass.cpp
+++ b/libcxx/test/std/strings/strings.erasure/erase.pass.cpp
@@ -67,6 +67,7 @@ constexpr void test() {
 constexpr bool test() {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>();
 
   return true;
diff --git a/libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp b/libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp
index 0f1c3fcf675eb..183fcb9af124e 100644
--- a/libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp
+++ b/libcxx/test/std/strings/strings.erasure/erase_if.pass.cpp
@@ -69,6 +69,7 @@ constexpr void test() {
 constexpr bool test() {
   test<std::string>();
   test<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
+  test<std::basic_string<char, std::char_traits<char>, fancy_pointer_allocator<char>>>();
   test<std::basic_string<char, std::char_traits<char>, test_allocator<char>>>();
 
   return true;
diff --git a/libcxx/test/support/test_allocator.h b/libcxx/test/support/test_allocator.h
index f8b622d7f9520..8ad646ef74259 100644
--- a/libcxx/test/support/test_allocator.h
+++ b/libcxx/test/support/test_allocator.h
@@ -444,6 +444,234 @@ TEST_CONSTEXPR_CXX20 thread_unsafe_shared_ptr<T> make_thread_unsafe_shared(Args.
 }
 } // namespace detail
 
+template <class T>
+class fancy_pointer {
+public:
+  // For the std::pointer_traits interface.
+  using pointer         = T*;
+  using element_type    = T;
+  using difference_type = std::ptrdiff_t;
+
+  template <class U>
+  using rebind = fancy_pointer<U>;
+
+  // For the std::iterator_traits interface.
+  using value_type        = typename std::remove_cv<T>::type;
+  using reference         = typename std::add_lvalue_reference<T>::type;
+  using iterator_category = std::random_access_iterator_tag;
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer() TEST_NOEXCEPT : ptr_(nullptr) {}
+  TEST_CONSTEXPR_CXX14 fancy_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
+
+  template <typename T2>
+  TEST_CONSTEXPR_CXX14 fancy_pointer(const fancy_pointer<T2>& other) TEST_NOEXCEPT : ptr_(other.get()) {}
+
+  TEST_CONSTEXPR_CXX14 operator T*() const TEST_NOEXCEPT { return ptr_; }
+  TEST_CONSTEXPR_CXX14 fancy_pointer(fancy_pointer&&) TEST_NOEXCEPT                 = default;
+  TEST_CONSTEXPR_CXX14 fancy_pointer(const fancy_pointer&) TEST_NOEXCEPT            = default;
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(fancy_pointer&&) TEST_NOEXCEPT      = default;
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(const fancy_pointer&) TEST_NOEXCEPT = default;
+  TEST_CONSTEXPR_CXX20 ~fancy_pointer() TEST_NOEXCEPT                               = default;
+  TEST_CONSTEXPR_CXX14 operator fancy_pointer<const T>() const TEST_NOEXCEPT { return fancy_pointer<const T>(get()); }
+  TEST_CONSTEXPR_CXX14 T& operator*() const TEST_NOEXCEPT { return *ptr_; }
+  TEST_CONSTEXPR_CXX14 T* operator->() const TEST_NOEXCEPT { return ptr_; }
+  TEST_CONSTEXPR_CXX14 explicit operator bool() const TEST_NOEXCEPT { return ptr_; }
+  TEST_CONSTEXPR_CXX14 T* get() const TEST_NOEXCEPT { return ptr_; }
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator++() TEST_NOEXCEPT {
+    ++ptr_;
+    return *this;
+  }
+  TEST_CONSTEXPR_CXX14 fancy_pointer operator++(int) TEST_NOEXCEPT {
+    fancy_pointer tmp(*this);
+    ++ptr_;
+    return tmp;
+  }
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator--() TEST_NOEXCEPT {
+    --ptr_;
+    return *this;
+  }
+  TEST_CONSTEXPR_CXX14 fancy_pointer operator--(int) TEST_NOEXCEPT {
+    fancy_pointer tmp(*this);
+    --ptr_;
+    return tmp;
+  }
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator+=(difference_type n) TEST_NOEXCEPT {
+    ptr_ += n;
+    return *this;
+  }
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator-=(difference_type n) TEST_NOEXCEPT {
+    ptr_ -= n;
+    return *this;
+  }
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer operator+(difference_type n) const TEST_NOEXCEPT {
+    fancy_pointer tmp(*this);
+    tmp += n;
+    return tmp;
+  }
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer operator-(difference_type n) const TEST_NOEXCEPT {
+    fancy_pointer tmp(*this);
+    tmp -= n;
+    return tmp;
+  }
+
+  TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const TEST_NOEXCEPT { return ptr_[n]; }
+
+  friend TEST_CONSTEXPR_CXX14 fancy_pointer operator+(difference_type x, fancy_pointer y) TEST_NOEXCEPT {
+    return y + x;
+  }
+
+  friend TEST_CONSTEXPR_CXX14 bool operator<(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return x.ptr_ < y.ptr_; }
+  friend TEST_CONSTEXPR_CXX14 bool operator>(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return y < x; }
+  friend TEST_CONSTEXPR_CXX14 bool operator<=(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return !(y < x); }
+  friend TEST_CONSTEXPR_CXX14 bool operator>=(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return !(x < y); }
+
+  static TEST_CONSTEXPR_CXX14 fancy_pointer pointer_to(reference ref) TEST_NOEXCEPT { return fancy_pointer(&ref); }
+
+  T* ptr_;
+};
+
+template <>
+class fancy_pointer<void> {
+public:
+  using T = void;
+
+  // For the std::pointer_traits interface.
+  using pointer         = T*;
+  using element_type    = T;
+  using difference_type = std::ptrdiff_t;
+
+  template <class U>
+  using rebind = fancy_pointer<U>;
+
+  // For the std::iterator_traits interface.
+  using value_type        = typename std::remove_cv<T>::type;
+  using reference         = typename std::add_lvalue_reference<T>::type;
+  using iterator_category = std::random_access_iterator_tag;
+
+  TEST_CONSTEXPR_CXX14 fancy_pointer() TEST_NOEXCEPT : ptr_(nullptr) {}
+  TEST_CONSTEXPR_CXX14 fancy_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
+
+  template <typename T2>
+  TEST_CONSTEXPR_CXX14 fancy_pointer(const fancy_pointer<T2>& other) TEST_NOEXCEPT : ptr_(other.get()) {}
+
+  TEST_CONSTEXPR_CXX14 operator T*() const TEST_NOEXCEPT { return ptr_; }
+  TEST_CONSTEXPR_CXX14 fancy_pointer(fancy_pointer&&) TEST_NOEXCEPT                 = default;
+  TEST_CONSTEXPR_CXX14 fancy_pointer(const fancy_pointer&) TEST_NOEXCEPT            = default;
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(fancy_pointer&&) TEST_NOEXCEPT      = default;
+  TEST_CONSTEXPR_CXX14 fancy_pointer& operator=(const fancy_pointer&) TEST_NOEXCEPT = default;
+  TEST_CONSTEXPR_CXX20 ~fancy_pointer() TEST_NOEXCEPT                               = default;
+  TEST_CONSTEXPR_CXX14 explicit operator bool() const TEST_NOEXCEPT { return ptr_; }
+  TEST_CONSTEXPR_CXX14 T* get() const TEST_NOEXCEPT { return ptr_; }
+
+  friend TEST_CONSTEXPR_CXX14 bool operator<(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return x.ptr_ < y.ptr_; }
+  friend TEST_CONSTEXPR_CXX14 bool operator>(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return y < x; }
+  friend TEST_CONSTEXPR_CXX14 bool operator<=(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return !(y < x); }
+  friend TEST_CONSTEXPR_CXX14 bool operator>=(fancy_pointer x, fancy_pointer y) TEST_NOEXCEPT { return !(x < y); }
+
+  T* ptr_;
+};
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 typename fancy_pointer<T>::difference_type
+operator-(fancy_pointer<T> x, fancy_pointer<T> y) TEST_NOEXCEPT {
+  return x.ptr_ - y.ptr_;
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 typename fancy_pointer<T>::difference_type
+operator-(fancy_pointer<const T> x, fancy_pointer<T> y) TEST_NOEXCEPT {
+  return x.ptr_ - y.ptr_;
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 typename fancy_pointer<T>::difference_type
+operator-(fancy_pointer<T> x, fancy_pointer<const T> y) TEST_NOEXCEPT {
+  return x.ptr_ - y.ptr_;
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 typename fancy_pointer<T>::difference_type
+operator-(fancy_pointer<const T> x, fancy_pointer<const T> y) TEST_NOEXCEPT {
+  return x.ptr_ - y.ptr_;
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator==(fancy_pointer<T> x, fancy_pointer<T> y) TEST_NOEXCEPT {
+  return x.get() == y.get();
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator==(fancy_pointer<const T> x, fancy_pointer<T> y) TEST_NOEXCEPT {
+  return x.get() == y.get();
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator==(fancy_pointer<T> x, fancy_pointer<const T> y) TEST_NOEXCEPT {
+  return x.get() == y.get();
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator==(fancy_pointer<const T> x, fancy_pointer<const T> y) TEST_NOEXCEPT {
+  return x.get() == y.get();
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator!=(fancy_pointer<T> x, fancy_pointer<T> y) TEST_NOEXCEPT {
+  return !(x == y);
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator!=(fancy_pointer<const T> x, fancy_pointer<T> y) TEST_NOEXCEPT {
+  return !(x == y);
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator!=(fancy_pointer<T> x, fancy_pointer<const T> y) TEST_NOEXCEPT {
+  return !(x == y);
+}
+
+template <typename T>
+TEST_CONSTEXPR_CXX14 bool operator!=(fancy_pointer<const T> x, fancy_pointer<const T> y) TEST_NOEXCEPT {
+  return !(x == y);
+}
+
+template <class T>
+class fancy_pointer_allocator : public std::allocator<T> {
+  typedef std::allocator<T> base;
+
+public:
+  typedef T value_type;
+  typedef fancy_pointer<T> pointer;
+  typedef fancy_pointer<const T> const_pointer;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef std::size_t size_type;
+  typedef std::ptrdiff_t difference_type;
+
+  template <class U>
+  struct rebind {
+    typedef fancy_pointer_allocator<U> other;
+  };
+
+  TEST_CONSTEXPR_CXX20 fancy_pointer_allocator() TEST_NOEXCEPT {}
+
+  template <class U>
+  TEST_CONSTEXPR explicit fancy_pointer_allocator(fancy_pointer_allocator<U>) TEST_NOEXCEPT {}
+
+  TEST_CONSTEXPR_CXX20 pointer allocate(size_t n) { return base::allocate(n); }
+  TEST_CONSTEXPR_CXX20 void deallocate(pointer p, size_t n) { return base::deallocate(p, n); }
+
+#if TEST_STD_VER > 20
+  TEST_CONSTEXPR_CXX20 std::allocation_result<pointer> allocate_at_least(std::size_t n) { return {allocate(n), n}; }
+#endif
+};
+
 template <class T, std::size_t N>
 class limited_allocator {
   template <class U, std::size_t UN>



More information about the libcxx-commits mailing list