[libc++] Implement P1425R4 (Iterator pair constructors for std::stack and std::queue)

Implement P1425R4

Reviewed By: Quuxplusone, #libc, Mordante

Spies: Mordante, jloser, libcxx-commits, arichardson

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

NOKEYCHECK=True
GitOrigin-RevId: f3aed3698185dd4a03b210a9d73be4dc1efc580f
diff --git a/include/queue b/include/queue
index 9fad802..9e1257b 100644
--- a/include/queue
+++ b/include/queue
@@ -41,6 +41,8 @@
 
     explicit queue(const container_type& c);
     explicit queue(container_type&& c)
+    template<class InputIterator>
+        queue(InputIterator first, InputIterator last); // since C++23
     template <class Alloc>
         explicit queue(const Alloc& a);
     template <class Alloc>
@@ -51,6 +53,8 @@
         queue(const queue& q, const Alloc& a);
     template <class Alloc>
         queue(queue&& q, const Alloc& a);
+    template <class InputIterator, class Alloc>
+        queue(InputIterator first, InputIterator last, const Alloc&); // since C++23
 
     bool      empty() const;
     size_type size() const;
@@ -71,9 +75,17 @@
 template<class Container>
   queue(Container) -> queue<typename Container::value_type, Container>; // C++17
 
+template<class InputIterator>
+  queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23
+
 template<class Container, class Allocator>
   queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17
 
+template<class InputIterator, class Allocator>
+  queue(InputIterator, InputIterator, Allocator)
+  -> queue<iter-value-type<InputIterator>,
+           deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
+
 template <class T, class Container>
   bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
 
@@ -206,12 +218,14 @@
 */
 
 #include <__config>
+#include <__iterator/iterator_traits.h>
 #include <__memory/uses_allocator.h>
 #include <__utility/forward.h>
 #include <algorithm>
 #include <compare>
 #include <deque>
 #include <functional>
+#include <type_traits>
 #include <vector>
 #include <version>
 
@@ -256,6 +270,20 @@
     _LIBCPP_INLINE_VISIBILITY
     queue(const queue& __q) : c(__q.c) {}
 
+#if _LIBCPP_STD_VER > 20
+    template <class _InputIterator,
+              class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+    _LIBCPP_HIDE_FROM_ABI
+    queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {}
+
+    template <class _InputIterator,
+              class _Alloc,
+              class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+              class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>>
+    _LIBCPP_HIDE_FROM_ABI
+    queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     queue& operator=(const queue& __q) {c = __q.c; return *this;}
 
@@ -359,7 +387,7 @@
     operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
 };
 
-#if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER > 14
 template<class _Container,
          class = enable_if_t<!__is_allocator<_Container>::value>
 >
@@ -375,6 +403,20 @@
     -> queue<typename _Container::value_type, _Container>;
 #endif
 
+#if _LIBCPP_STD_VER > 20
+template <class _InputIterator,
+          class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+queue(_InputIterator, _InputIterator)
+    -> queue<__iter_value_type<_InputIterator>>;
+
+template <class _InputIterator,
+          class _Alloc,
+          class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>,
+          class = __enable_if_t<__is_allocator<_Alloc>::value>>
+queue(_InputIterator, _InputIterator, _Alloc)
+    -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
+#endif
+
 template <class _Tp, class _Container>
 inline _LIBCPP_INLINE_VISIBILITY
 bool