[libc++][format] Adds container adaptor formatters.

Implements parts of
- P2286R8 Formatting Ranges

Depends on D140653

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D141290

NOKEYCHECK=True
GitOrigin-RevId: 04d4f4b3d4e4fd608a3bc3fe387006435f04b61d
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 81d488f..2d20244 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -302,6 +302,7 @@
   __filesystem/u8path.h
   __format/buffer.h
   __format/concepts.h
+  __format/container_adaptor.h
   __format/enable_insertable.h
   __format/escaped_output_table.h
   __format/extended_grapheme_cluster_table.h
diff --git a/include/__format/container_adaptor.h b/include/__format/container_adaptor.h
new file mode 100644
index 0000000..62b6981
--- /dev/null
+++ b/include/__format/container_adaptor.h
@@ -0,0 +1,70 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
+#define _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#include <__availability>
+#include <__config>
+#include <__format/concepts.h>
+#include <__format/formatter.h>
+#include <__format/range_default_formatter.h>
+#include <queue>
+#include <stack>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+// [container.adaptors.format] only specifies the library should provide the
+// formatter specializations, not which header should provide them.
+// Since <format> includes a lot of headers, add these headers here instead of
+// adding more dependencies like, locale, optinal, string, tuple, etc. to the
+// adaptor headers. To use the format functions users already include <format>.
+
+template <class _Adaptor, class _CharT>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor {
+private:
+  using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>;
+  formatter<typename _Adaptor::container_type, _CharT> __underlying_;
+
+public:
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return __underlying_.parse(__ctx);
+  }
+
+  template <class _FormatContext>
+  _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+  format(__maybe_const_adaptor& __adaptor, _FormatContext& __ctx) const {
+    return __underlying_.format(__adaptor.__get_container(), __ctx);
+  }
+};
+
+template <class _CharT, class _Tp, formattable<_CharT> _Container>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<queue<_Tp, _Container>, _CharT>
+    : public __formatter_container_adaptor<queue<_Tp, _Container>, _CharT> {};
+
+template <class _CharT, class _Tp, class _Container, class _Compare>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
+    : public __formatter_container_adaptor<priority_queue<_Tp, _Container, _Compare>, _CharT> {};
+
+template <class _CharT, class _Tp, formattable<_CharT> _Container>
+struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<stack<_Tp, _Container>, _CharT>
+    : public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {};
+
+#endif //_LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H
diff --git a/include/__format/range_default_formatter.h b/include/__format/range_default_formatter.h
index ee1dc52..652c021 100644
--- a/include/__format/range_default_formatter.h
+++ b/include/__format/range_default_formatter.h
@@ -146,8 +146,6 @@
   __range_default_formatter() = delete; // TODO FMT Implement
 };
 
-// Dispatcher to select the specialization based on the type of the range.
-
 template <ranges::input_range _Rp, class _CharT>
   requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>)
 struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT>
diff --git a/include/format b/include/format
index aaac95b..2c583c1 100644
--- a/include/format
+++ b/include/format
@@ -178,6 +178,7 @@
 #include <__config>
 #include <__format/buffer.h>
 #include <__format/concepts.h>
+#include <__format/container_adaptor.h>
 #include <__format/enable_insertable.h>
 #include <__format/format_arg.h>
 #include <__format/format_arg_store.h>
diff --git a/include/module.modulemap.in b/include/module.modulemap.in
index 81f503e..aa4da4d 100644
--- a/include/module.modulemap.in
+++ b/include/module.modulemap.in
@@ -839,6 +839,7 @@
     module __format {
       module buffer                          { private header "__format/buffer.h" }
       module concepts                        { private header "__format/concepts.h" }
+      module container_adaptor               { private header "__format/container_adaptor.h" }
       module enable_insertable               { private header "__format/enable_insertable.h" }
       module escaped_output_table            { private header "__format/escaped_output_table.h" }
       module extended_grapheme_cluster_table { private header "__format/extended_grapheme_cluster_table.h" }
diff --git a/include/queue b/include/queue
index c58da5e..6c1b892 100644
--- a/include/queue
+++ b/include/queue
@@ -382,6 +382,8 @@
         swap(c, __q.c);
     }
 
+    _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
+
     template <class _T1, class _C1>
     friend
     _LIBCPP_INLINE_VISIBILITY
@@ -633,6 +635,8 @@
     void swap(priority_queue& __q)
         _NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&
                    __is_nothrow_swappable<value_compare>::value);
+
+    _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
 };
 
 #if _LIBCPP_STD_VER >= 17
diff --git a/include/stack b/include/stack
index 2abbcd0..d653d1b 100644
--- a/include/stack
+++ b/include/stack
@@ -255,6 +255,8 @@
         swap(c, __s.c);
     }
 
+    _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; }
+
     template <class T1, class _C1>
     friend
     bool