[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
This commit is contained in:
Nikolas Klauser 2022-01-06 12:36:07 +01:00
parent 3ef363ecec
commit f3aed36981
15 changed files with 474 additions and 22 deletions

View File

@ -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*

View File

@ -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"

1 Paper # Group Paper Name Meeting Status First released version
15 `P0448R4 <https://wg21.link/P0448R4>`__ LWG A strstream replacement using span<charT> as buffer June 2021
16 `P1132R8 <https://wg21.link/P1132R8>`__ LWG out_ptr - a scalable output pointer abstraction June 2021
17 `P1328R1 <https://wg21.link/P1328R1>`__ LWG Making std::type_info::operator== constexpr June 2021
18 `P1425R4 <https://wg21.link/P1425R4>`__ LWG Iterators pair constructors for stack and queue June 2021 |Complete| 14.0
19 `P1518R2 <https://wg21.link/P1518R2>`__ LWG Stop overconstraining allocators in container deduction guides June 2021 |Complete| 13.0
20 `P1659R3 <https://wg21.link/P1659R3>`__ LWG starts_with and ends_with June 2021
21 `P1951R1 <https://wg21.link/P1951R1>`__ LWG Default Arguments for pair Forwarding Constructor June 2021 |Complete| 14.0

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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;
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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;
}

View File

@ -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; }

View File

@ -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; }

View File

@ -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

View File

@ -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"],