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

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 6 09:56:34 PST 2022


Author: Nikolas Klauser
Date: 2022-01-06T18:55:11+01:00
New Revision: f3aed3698185dd4a03b210a9d73be4dc1efc580f

URL: https://github.com/llvm/llvm-project/commit/f3aed3698185dd4a03b210a9d73be4dc1efc580f
DIFF: https://github.com/llvm/llvm-project/commit/f3aed3698185dd4a03b210a9d73be4dc1efc580f.diff

LOG: [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

Added: 
    libcxx/test/std/containers/container.adaptors/queue/queue.cons.alloc/ctor_iterators.pass.cpp
    libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_iterators.pass.cpp
    libcxx/test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp
    libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/queue.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/stack.version.pass.cpp

Modified: 
    libcxx/docs/FeatureTestMacroTable.rst
    libcxx/docs/Status/Cxx2bPapers.csv
    libcxx/include/queue
    libcxx/include/stack
    libcxx/include/version
    libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.pass.cpp
    libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 714ed803ba696..40e755864c19b 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -296,6 +296,8 @@ Status
     ------------------------------------------------- -----------------
     **C++ 2b**
     -------------------------------------------------------------------
+    ``__cpp_lib_adaptor_iterator_pair_constructor``   ``202106L``
+    ------------------------------------------------- -----------------
     ``__cpp_lib_allocate_at_least``                   *unimplemented*
     ------------------------------------------------- -----------------
     ``__cpp_lib_associative_heterogeneous_erasure``   *unimplemented*

diff  --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index 7a76e1f576451..50b11c4347d88 100644
--- a/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/libcxx/docs/Status/Cxx2bPapers.csv
@@ -15,7 +15,7 @@
 "`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
 "`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","",""
 "`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","",""
-"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","",""
+"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0"
 "`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
 "`P1659R3 <https://wg21.link/P1659R3>`__","LWG","starts_with and ends_with","June 2021","",""
 "`P1951R1 <https://wg21.link/P1951R1>`__","LWG","Default Arguments for pair Forwarding Constructor","June 2021","|Complete|","14.0"

diff  --git a/libcxx/include/queue b/libcxx/include/queue
index 9fad80253c502..9e1257b25e0e9 100644
--- a/libcxx/include/queue
+++ b/libcxx/include/queue
@@ -41,6 +41,8 @@ public:
 
     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 @@ public:
         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 @@ public:
 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 @@ template <class T, class Container, class Compare>
 */
 
 #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 @@ public:
     _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 @@ public:
     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(_Container, _Alloc)
     -> 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

diff  --git a/libcxx/include/stack b/libcxx/include/stack
index 3cf6cd2332823..ad65d7b29b4ff 100644
--- a/libcxx/include/stack
+++ b/libcxx/include/stack
@@ -41,11 +41,14 @@ public:
 
     explicit stack(const container_type& c);
     explicit stack(container_type&& c);
+    template <class InputIterator> stack(InputIterator first, InputIterator last); // since C++23
     template <class Alloc> explicit stack(const Alloc& a);
     template <class Alloc> stack(const container_type& c, const Alloc& a);
     template <class Alloc> stack(container_type&& c, const Alloc& a);
     template <class Alloc> stack(const stack& c, const Alloc& a);
     template <class Alloc> stack(stack&& c, const Alloc& a);
+    template<class InputIterator, class Alloc>
+    stack(InputIterator first, InputIterator last, const Alloc&); // since C++23
 
     bool empty() const;
     size_type size() const;
@@ -63,9 +66,17 @@ public:
 template<class Container>
   stack(Container) -> stack<typename Container::value_type, Container>;  // C++17
 
+template<class InputIterator>
+  stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>; // since C++23
+
 template<class Container, class Allocator>
   stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17
 
+template<class InputIterator, class Allocator>
+  stack(InputIterator, InputIterator, Allocator)
+    -> stack<iter-value-type<InputIterator>,
+             deque<iter-value-type<InputIterator>, Allocator>>; // since C++23
+
 template <class T, class Container>
   bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
 template <class T, class Container>
@@ -88,9 +99,11 @@ template <class T, class Container>
 */
 
 #include <__config>
+#include <__iterator/iterator_traits.h>
 #include <__memory/uses_allocator.h>
 #include <__utility/forward.h>
 #include <deque>
+#include <type_traits>
 #include <version>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -184,6 +197,20 @@ public:
             : c(_VSTD::move(__s.c), __a) {}
 #endif // _LIBCPP_CXX03_LANG
 
+#if _LIBCPP_STD_VER > 20
+    template <class _InputIterator,
+              class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+    _LIBCPP_HIDE_FROM_ABI
+    stack(_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
+    stack(_InputIterator __first, _InputIterator __last, const _Alloc& __alloc) : c(__first, __last, __alloc) {}
+#endif
+
     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
     bool empty()     const      {return c.empty();}
     _LIBCPP_INLINE_VISIBILITY
@@ -232,7 +259,7 @@ public:
     operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
 };
 
-#if _LIBCPP_STD_VER >= 17
+#if _LIBCPP_STD_VER > 14
 template<class _Container,
          class = enable_if_t<!__is_allocator<_Container>::value>
 >
@@ -248,6 +275,20 @@ stack(_Container, _Alloc)
     -> stack<typename _Container::value_type, _Container>;
 #endif
 
+#if _LIBCPP_STD_VER > 20
+template<class _InputIterator,
+         class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>>
+stack(_InputIterator, _InputIterator)
+    -> stack<__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>>
+stack(_InputIterator, _InputIterator, _Alloc)
+    -> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>;
+#endif
+
 template <class _Tp, class _Container>
 inline _LIBCPP_INLINE_VISIBILITY
 bool

diff  --git a/libcxx/include/version b/libcxx/include/version
index db67b2e65167e..6774e3151a6c2 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -14,6 +14,7 @@
   version synopsis
 
 Macro name                                              Value   Headers
+__cpp_lib_adaptor_iterator_pair_constructor             202106L <queue> <stack>
 __cpp_lib_addressof_constexpr                           201603L <memory>
 __cpp_lib_allocate_at_least                             202106L <memory>
 __cpp_lib_allocator_traits_is_always_equal              201411L <deque> <forward_list> <list>
@@ -358,6 +359,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 #endif
 
 #if _LIBCPP_STD_VER > 20
+# define __cpp_lib_adaptor_iterator_pair_constructor    202106L
 // # define __cpp_lib_allocate_at_least                    202106L
 // # define __cpp_lib_associative_heterogeneous_erasure    202110L
 # define __cpp_lib_byteswap                             202110L

diff  --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons.alloc/ctor_iterators.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons.alloc/ctor_iterators.pass.cpp
new file mode 100644
index 0000000000000..90606643b9332
--- /dev/null
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons.alloc/ctor_iterators.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <queue>
+
+// template <class InputIterator, class Allocator>
+// queue(InputIterator, InputIterator, const Allocator&);
+
+#include <cassert>
+#include <queue>
+
+#include "test_allocator.h"
+
+using base_type = std::queue<int, std::deque<int, test_allocator<int>>>;
+
+class GetAlloc : public base_type {
+  test_allocator_statistics* stats;
+
+public:
+  explicit GetAlloc(test_allocator_statistics& stats_, const int* begin, const int* end)
+      : base_type(begin, end, test_allocator<int>(&stats_)), stats(&stats_) {}
+  void check() {
+    assert(size() == 4);
+    assert(stats->alloc_count > 0);
+  }
+};
+
+int main(int, char**) {
+  const int a[] = {4, 3, 2, 1};
+  test_allocator_statistics stats{};
+  GetAlloc queue(stats, a, a + 4);
+  assert(queue.front() == 4);
+  queue.pop();
+  assert(queue.front() == 3);
+  queue.pop();
+  assert(queue.front() == 2);
+  queue.pop();
+  assert(queue.front() == 1);
+  queue.pop();
+  assert(queue.empty());
+}

diff  --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_iterators.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_iterators.pass.cpp
new file mode 100644
index 0000000000000..192587ca3f5ad
--- /dev/null
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_iterators.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <queue>
+
+// template <class InputIterator>
+// queue(InputIterator, InputIterator);
+
+#include <cassert>
+#include <queue>
+#include <type_traits>
+
+#include "test_allocator.h"
+
+static_assert(!std::is_constructible_v<std::queue<int>, int, int, std::allocator<int>>);
+static_assert(!std::is_constructible_v<std::queue<int>, int*, int*, int>);
+static_assert( std::is_constructible_v<std::queue<int, std::deque<int, test_allocator<int>>>, int*, int*, test_allocator<int>>);
+static_assert(!std::is_constructible_v<std::queue<int, std::deque<int, test_allocator<int>>>, int*, int*, std::allocator<int>>);
+
+struct alloc : test_allocator<int> {
+  alloc(test_allocator_statistics* a);
+};
+static_assert( std::is_constructible_v<std::queue<int, std::deque<int, alloc>>, int*, int*, test_allocator_statistics*>);
+
+int main(int, char**) {
+  const int a[] = {4, 3, 2, 1};
+  std::queue<int> queue(a, a + 4);
+  assert(queue.front() == 4);
+  queue.pop();
+  assert(queue.front() == 3);
+  queue.pop();
+  assert(queue.front() == 2);
+  queue.pop();
+  assert(queue.front() == 1);
+  queue.pop();
+  assert(queue.empty());
+}

diff  --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.pass.cpp
index a30d11fd493f1..e17c39e5faff7 100644
--- a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.pass.cpp
@@ -16,6 +16,7 @@
 //   queue(Container, Allocator) -> queue<typename Container::value_type, Container>;
 
 
+#include <array>
 #include <queue>
 #include <list>
 #include <iterator>
@@ -141,19 +142,34 @@ int main(int, char**)
         using Cont = std::list<int>;
         using Alloc = std::allocator<int>;
         using DiffAlloc = test_allocator<int>;
+        using Iter = int*;
 
-        struct BadAlloc {};
-        using AllocAsCont = Alloc;
+        struct NotIter{};
+        struct NotAlloc {};
 
-        // (cont, alloc)
-        //
-        // Cannot deduce from (ALLOC_as_cont, alloc)
-        static_assert(SFINAEs_away<std::queue, AllocAsCont, BadAlloc>);
-        // Cannot deduce from (cont, BAD_alloc)
-        static_assert(SFINAEs_away<std::queue, Cont, BadAlloc>);
-        // Cannot deduce from (cont, DIFFERENT_alloc)
+        static_assert(SFINAEs_away<std::queue, Alloc, NotAlloc>);
+        static_assert(SFINAEs_away<std::queue, Cont, NotAlloc>);
         static_assert(SFINAEs_away<std::queue, Cont, DiffAlloc>);
+        static_assert(SFINAEs_away<std::queue, Iter, NotIter>);
+#if TEST_STD_VER > 20
+        static_assert(SFINAEs_away<std::queue, Iter, NotIter, Alloc>);
+        static_assert(SFINAEs_away<std::queue, Iter, Iter, NotAlloc>);
+#endif
     }
-
+#if TEST_STD_VER > 20
+    {
+        typedef short T;
+        typedef test_allocator<T> Alloc;
+        std::list<T> a;
+        {
+        std::queue q(a.begin(), a.end());
+        static_assert(std::is_same_v<decltype(q), std::queue<T>>);
+        }
+        {
+        std::queue q(a.begin(), a.end(), Alloc());
+        static_assert(std::is_same_v<decltype(q), std::queue<T, std::deque<T, Alloc>>>);
+        }
+    }
+#endif
     return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp
new file mode 100644
index 0000000000000..74a59d70a513b
--- /dev/null
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons.alloc/ctor_iterators.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <queue>
+
+// template <class InputIterator, class Allocator>
+// stack(InputIterator, InputIterator, Allocator);
+
+#include <cassert>
+#include <stack>
+
+#include "test_allocator.h"
+
+using base_type = std::stack<int, std::deque<int, test_allocator<int>>>;
+
+class GetAlloc : public base_type {
+  test_allocator_statistics* stats;
+
+public:
+  GetAlloc(test_allocator_statistics& stats_, const int* begin, const int* end)
+      : base_type(begin, end, test_allocator<int>(&stats_)), stats(&stats_) {}
+  void check() {
+    assert(size() == 4);
+    assert(stats->alloc_count > 0);
+  }
+};
+
+int main(int, char**) {
+  const int a[] = {4, 3, 2, 1};
+  test_allocator_statistics stats{};
+  GetAlloc stack(stats, a, a + 4);
+  assert(stack.top() == 1);
+  stack.pop();
+  assert(stack.top() == 2);
+  stack.pop();
+  assert(stack.top() == 3);
+  stack.pop();
+  assert(stack.top() == 4);
+  stack.pop();
+  assert(stack.empty());
+}

diff  --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp
new file mode 100644
index 0000000000000..679e5836d5af7
--- /dev/null
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_iterators.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// <queue>
+
+// template <class InputIterator>
+// stack(InputIterator, InputIterator);
+
+#include <cassert>
+#include <stack>
+
+#include "test_allocator.h"
+
+static_assert(!std::is_constructible_v<std::stack<int>, int, int, std::allocator<int>>);
+static_assert(!std::is_constructible_v<std::stack<int>, int*, int*, int>);
+static_assert( std::is_constructible_v<std::stack<int, std::deque<int, test_allocator<int>>>, int*, int*, test_allocator<int>>);
+static_assert(!std::is_constructible_v<std::stack<int, std::deque<int, test_allocator<int>>>, int*, int*, std::allocator<int>>);
+
+struct alloc : test_allocator<int> {
+  alloc(test_allocator_statistics* a);
+};
+static_assert( std::is_constructible_v<std::stack<int, std::deque<int, alloc>>, int*, int*, test_allocator_statistics*>);
+
+int main(int, char**) {
+  const int a[] = {4, 3, 2, 1};
+  std::stack<int> stack(a, a + 4);
+  assert(stack.top() == 1);
+  stack.pop();
+  assert(stack.top() == 2);
+  stack.pop();
+  assert(stack.top() == 3);
+  stack.pop();
+  assert(stack.top() == 4);
+  stack.pop();
+  assert(stack.empty());
+}

diff  --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp
index 0e6bed76b520d..ad02a3ef5f55a 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.pass.cpp
@@ -16,6 +16,7 @@
 //   stack(Container, Allocator) -> stack<typename Container::value_type, Container>;
 
 
+#include <array>
 #include <stack>
 #include <deque>
 #include <vector>
@@ -145,19 +146,36 @@ int main(int, char**)
         using Cont = std::list<int>;
         using Alloc = std::allocator<int>;
         using DiffAlloc = test_allocator<int>;
+        using Iter = int;
 
-        struct BadAlloc {};
-        using AllocAsCont = Alloc;
+        struct NotIter {};
+        struct NotAlloc {};
 
-        // (cont, alloc)
-        //
-        // Cannot deduce from (ALLOC_as_cont, alloc)
-        static_assert(SFINAEs_away<std::stack, AllocAsCont, Alloc>);
-        // Cannot deduce from (cont, BAD_alloc)
-        static_assert(SFINAEs_away<std::stack, Cont, BadAlloc>);
-        // Cannot deduce from (cont, DIFFERENT_alloc)
+        static_assert(SFINAEs_away<std::stack, Alloc, Alloc>);
+        static_assert(SFINAEs_away<std::stack, Cont, NotAlloc>);
         static_assert(SFINAEs_away<std::stack, Cont, DiffAlloc>);
+        static_assert(SFINAEs_away<std::stack, Iter, NotIter>);
+#if TEST_STD_VER > 20
+        static_assert(SFINAEs_away<std::stack, Iter, NotIter, Alloc>);
+        static_assert(SFINAEs_away<std::stack, Iter, Iter, NotAlloc>);
+#endif
     }
 
+#if TEST_STD_VER > 20
+    {
+        typedef short T;
+        typedef test_allocator<T> Alloc;
+        std::list<T> a;
+        {
+        std::stack s(a.begin(), a.end());
+        static_assert(std::is_same_v<decltype(s), std::stack<T>>);
+        }
+        {
+        std::stack s(a.begin(), a.end(), Alloc());
+        static_assert(std::is_same_v<decltype(s), std::stack<T, std::deque<T, Alloc>>>);
+        }
+    }
+#endif
+
     return 0;
 }

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/queue.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/queue.version.pass.cpp
new file mode 100644
index 0000000000000..94a0a6b639ccd
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/queue.version.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <queue>
+
+// Test the feature test macros defined by <queue>
+
+/*  Constant                                       Value
+    __cpp_lib_adaptor_iterator_pair_constructor    202106L [C++2b]
+*/
+
+#include <queue>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER > 20
+
+# ifndef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++2b"
+# endif
+# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++2b"
+# endif
+
+#endif // TEST_STD_VER > 20
+
+int main(int, char**) { return 0; }

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/stack.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/stack.version.pass.cpp
new file mode 100644
index 0000000000000..d1b1103bc52e4
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/stack.version.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <stack>
+
+// Test the feature test macros defined by <stack>
+
+/*  Constant                                       Value
+    __cpp_lib_adaptor_iterator_pair_constructor    202106L [C++2b]
+*/
+
+#include <stack>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER > 20
+
+# ifndef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++2b"
+# endif
+# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++2b"
+# endif
+
+#endif // TEST_STD_VER > 20
+
+int main(int, char**) { return 0; }

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
index c22dda85a2470..e0f225009e41b 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
@@ -16,6 +16,7 @@
 // Test the feature test macros defined by <version>
 
 /*  Constant                                       Value
+    __cpp_lib_adaptor_iterator_pair_constructor    202106L [C++2b]
     __cpp_lib_addressof_constexpr                  201603L [C++17]
     __cpp_lib_allocate_at_least                    202106L [C++2b]
     __cpp_lib_allocator_traits_is_always_equal     201411L [C++17]
@@ -171,6 +172,10 @@
 
 #if TEST_STD_VER < 14
 
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_addressof_constexpr
 #   error "__cpp_lib_addressof_constexpr should not be defined before c++17"
 # endif
@@ -749,6 +754,10 @@
 
 #elif TEST_STD_VER == 14
 
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_addressof_constexpr
 #   error "__cpp_lib_addressof_constexpr should not be defined before c++17"
 # endif
@@ -1393,6 +1402,10 @@
 
 #elif TEST_STD_VER == 17
 
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
 # ifndef __cpp_lib_addressof_constexpr
 #   error "__cpp_lib_addressof_constexpr should be defined in c++17"
 # endif
@@ -2235,6 +2248,10 @@
 
 #elif TEST_STD_VER == 20
 
+# ifdef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++2b"
+# endif
+
 # ifndef __cpp_lib_addressof_constexpr
 #   error "__cpp_lib_addressof_constexpr should be defined in c++20"
 # endif
@@ -3407,6 +3424,13 @@
 
 #elif TEST_STD_VER > 20
 
+# ifndef __cpp_lib_adaptor_iterator_pair_constructor
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++2b"
+# endif
+# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L
+#   error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++2b"
+# endif
+
 # ifndef __cpp_lib_addressof_constexpr
 #   error "__cpp_lib_addressof_constexpr should be defined in c++2b"
 # endif

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 92de7b3b1284c..0d43c74a69790 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -63,6 +63,10 @@ def add_version_header(tc):
 # ================  ============================================================
 feature_test_macros = [ add_version_header(x) for x in [
   {
+    "name": "__cpp_lib_adaptor_iterator_pair_constructor",
+    "values": { "c++2b": 202106 },
+    "headers": ["queue", "stack"],
+  }, {
     "name": "__cpp_lib_addressof_constexpr",
     "values": { "c++17": 201603 },
     "headers": ["memory"],


        


More information about the libcxx-commits mailing list