From 8a2e6590cc4a2fceb03ec9616d24173c0ea393f5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Mon, 22 Sep 2025 18:58:52 +0200 Subject: [PATCH] libstdc++: [_GLIBCXX_DEBUG] Implement std::__debug::inplace_vector Add _GLIBCXX_DEBUG std::inplace_vector implementation. libstdc++-v3/ChangeLog: * include/Makefile.am (debug_headers): Add inplace_vector. * include/Makefile.in: Regenerate. * include/debug/functions.h (__check_valid_range): Add C++20 constexpr. * include/debug/helper_functions.h (__valid_range): Likewise. * include/debug/inplace_vector: New. * include/debug/safe_base.h (~_Safe_sequence_base()): Add C++11 noexcept. (_Safe_sequence_base::operator=(const _Safe_sequence_base&)): New. (_Safe_sequence_base::operator=(_Safe_sequence_base&&)): New. (_Safe_sequence_base::_M_invalidate_all): Add C++20 constexpr. * include/debug/safe_container.h (_Safe_container<>::operator=(const _Safe_container<>&)): Implement using _Safe_sequence_base same operator. * include/debug/safe_iterator.h (__valid_range): Add C++20 constexpr. * include/debug/safe_sequence.h (_Not_equal_to(const _Type&)): Add C++20 constexpr. (_Equal_to(const _Type&)): Add C++20 constexpr. (_After_nth_from(const difference_type&, const _Iterator&)): Add C++20 constexpr. (_Safe_sequence<>::_M_invalidate_if): Add C++20 constexpr. (_Safe_node_sequence::operator=(const _Safe_node_sequence&)): New. (_Safe_node_sequence::operator=(_Safe_node_sequence&&)): New. (_Safe_node_sequence<>::_M_invalidate_all()): Add C++20 constexpr. * include/debug/safe_sequence.tcc (_Safe_sequence<>::_M_invalidate_if): Add C++20 constexpr. * include/std/inplace_vector [_GLIBCXX_DEBUG](std::inplace_vector<>): Move implementation into __cxx1998 namespace. (erase, erase_if): Limit to non-debug inplace_vector<>, cleanup code. [_GLIBCXX_DEBUG]: Add include . * testsuite/23_containers/inplace_vector/cons/1.cc: Adapt, skip several is_trivially_xxx checks when in _GLIBCXX_DEBUG mode. * testsuite/23_containers/inplace_vector/copy.cc: Likewise. * testsuite/23_containers/inplace_vector/move.cc: Likewise. * testsuite/23_containers/inplace_vector/debug/assign1_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/assign2_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/assign3_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/assign4_backtrace_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/assign4_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/construct1_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/construct2_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/construct3_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/construct4_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/debug_functions.cc: New test case. * testsuite/23_containers/inplace_vector/debug/erase.cc: New test case. * testsuite/23_containers/inplace_vector/debug/insert1_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/insert2_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/insert3_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/insert4_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/insert5_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/insert7_neg.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/1.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/2.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/3.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/4.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/append_range.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/erase.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/pop_back.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/push_back.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/swap.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc: New test case. * testsuite/23_containers/inplace_vector/debug/invalidation/unchecked_emplace_back.cc: New test case. * testsuite/util/debug/checks.h: Avoid using _GLIBCXX_DEBUG containers in test implementations. --- libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/debug/functions.h | 10 +- libstdc++-v3/include/debug/helper_functions.h | 4 +- libstdc++-v3/include/debug/inplace_vector | 691 ++++++++++++++++++ libstdc++-v3/include/debug/safe_base.h | 22 +- libstdc++-v3/include/debug/safe_container.h | 21 +- libstdc++-v3/include/debug/safe_iterator.h | 12 +- libstdc++-v3/include/debug/safe_sequence.h | 28 +- libstdc++-v3/include/debug/safe_sequence.tcc | 5 +- libstdc++-v3/include/std/inplace_vector | 35 +- .../23_containers/inplace_vector/cons/1.cc | 4 +- .../23_containers/inplace_vector/copy.cc | 4 + .../inplace_vector/debug/assign1_neg.cc | 16 + .../inplace_vector/debug/assign2_neg.cc | 16 + .../inplace_vector/debug/assign3_neg.cc | 16 + .../debug/assign4_backtrace_neg.cc | 17 + .../inplace_vector/debug/assign4_neg.cc | 15 + .../inplace_vector/debug/construct1_neg.cc | 16 + .../inplace_vector/debug/construct2_neg.cc | 16 + .../inplace_vector/debug/construct3_neg.cc | 16 + .../inplace_vector/debug/construct4_neg.cc | 15 + .../inplace_vector/debug/debug_functions.cc | 34 + .../inplace_vector/debug/erase.cc | 35 + .../inplace_vector/debug/insert1_neg.cc | 16 + .../inplace_vector/debug/insert2_neg.cc | 16 + .../inplace_vector/debug/insert3_neg.cc | 16 + .../inplace_vector/debug/insert4_neg.cc | 15 + .../inplace_vector/debug/insert5_neg.cc | 16 + .../inplace_vector/debug/insert7_neg.cc | 24 + .../inplace_vector/debug/invalidation/1.cc | 33 + .../inplace_vector/debug/invalidation/2.cc | 34 + .../inplace_vector/debug/invalidation/3.cc | 43 ++ .../inplace_vector/debug/invalidation/4.cc | 40 + .../debug/invalidation/append_range.cc | 45 ++ .../debug/invalidation/erase.cc | 36 + .../debug/invalidation/pop_back.cc | 27 + .../debug/invalidation/push_back.cc | 53 ++ .../inplace_vector/debug/invalidation/swap.cc | 53 ++ .../debug/invalidation/try_append_range.cc | 45 ++ .../debug/invalidation/try_emplace_back.cc | 27 + .../debug/invalidation/try_push_back.cc | 45 ++ .../invalidation/unchecked_emplace_back.cc | 27 + .../23_containers/inplace_vector/move.cc | 4 + libstdc++-v3/testsuite/util/debug/checks.h | 37 +- 45 files changed, 1660 insertions(+), 42 deletions(-) create mode 100644 libstdc++-v3/include/debug/inplace_vector create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign1_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign2_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign3_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_backtrace_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct1_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct2_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct3_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct4_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/debug_functions.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/erase.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert1_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert2_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert3_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert4_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert5_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert7_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/1.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/2.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/3.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/4.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/append_range.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/erase.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/pop_back.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/push_back.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/swap.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc create mode 100644 libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/unchecked_emplace_back.cc diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index ae7a7ca9073a..7d65c6f3ab31 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -971,6 +971,7 @@ debug_headers = \ ${debug_srcdir}/forward_list \ ${debug_srcdir}/functions.h \ ${debug_srcdir}/helper_functions.h \ + ${debug_srcdir}/inplace_vector \ ${debug_srcdir}/list \ ${debug_srcdir}/map \ ${debug_srcdir}/macros.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index f07e2326816b..acf8ae9be441 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -1308,6 +1308,7 @@ debug_freestanding = \ @GLIBCXX_HOSTED_TRUE@ ${debug_srcdir}/forward_list \ @GLIBCXX_HOSTED_TRUE@ ${debug_srcdir}/functions.h \ @GLIBCXX_HOSTED_TRUE@ ${debug_srcdir}/helper_functions.h \ +@GLIBCXX_HOSTED_TRUE@ ${debug_srcdir}/inplace_vector \ @GLIBCXX_HOSTED_TRUE@ ${debug_srcdir}/list \ @GLIBCXX_HOSTED_TRUE@ ${debug_srcdir}/map \ @GLIBCXX_HOSTED_TRUE@ ${debug_srcdir}/macros.h \ diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h index c5f5582b0050..4e6fdae71935 100644 --- a/libstdc++-v3/include/debug/functions.h +++ b/libstdc++-v3/include/debug/functions.h @@ -53,15 +53,19 @@ namespace __gnu_debug * assertion statement because, e.g., we are in a constructor. */ template - inline _InputIterator + _GLIBCXX20_CONSTEXPR inline _InputIterator __check_valid_range(const _InputIterator& __first, const _InputIterator& __last, const char* __file, unsigned int __line, const char* __function) { - __glibcxx_check_valid_range_at(__first, __last, - __file, __line, __function); + if (!std::__is_constant_evaluated()) + { + __glibcxx_check_valid_range_at(__first, __last, + __file, __line, __function); + } + return __first; } diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h index 9395892b537c..b9771034bf34 100644 --- a/libstdc++-v3/include/debug/helper_functions.h +++ b/libstdc++-v3/include/debug/helper_functions.h @@ -249,7 +249,7 @@ namespace __gnu_debug } template - bool + _GLIBCXX20_CONSTEXPR bool __valid_range(const _Safe_iterator<_Iterator, _Sequence, _Category>&, const _Safe_iterator<_Iterator, _Sequence, _Category>&, typename _Distance_traits<_Iterator>::__type&); @@ -272,7 +272,7 @@ namespace __gnu_debug } template - bool + _GLIBCXX20_CONSTEXPR bool __valid_range(const _Safe_iterator<_Iterator, _Sequence, _Category>&, const _Safe_iterator<_Iterator, _Sequence, _Category>&); diff --git a/libstdc++-v3/include/debug/inplace_vector b/libstdc++-v3/include/debug/inplace_vector new file mode 100644 index 000000000000..c7e301efc621 --- /dev/null +++ b/libstdc++-v3/include/debug/inplace_vector @@ -0,0 +1,691 @@ +// Debugging inplace_vector implementation -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file debug/inplace_vector + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_INPLACE_VECTOR +#define _GLIBCXX_DEBUG_INPLACE_VECTOR 1 + +#ifdef _GLIBCXX_SYSHDR +#pragma GCC system_header +#endif + +#include + +namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug { + template class inplace_vector; +} } // namespace std::__debug + +#include + +#ifdef __glibcxx_inplace_vector // C++ >= 26 + +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace __debug +{ + /// Class std::inplace_vector with safety/checking/debug instrumentation. + template + class inplace_vector + : public __gnu_debug::_Safe_sequence> + , public _GLIBCXX_STD_C::inplace_vector<_Tp, _Nm> + { + using _Base = _GLIBCXX_STD_C::inplace_vector<_Tp, _Nm>; + using _Base_iterator = typename _Base::iterator; + using _Base_const_iterator = typename _Base::const_iterator; + using _Equal = __gnu_debug::_Equal_to<_Base_const_iterator>; + + template + friend class ::__gnu_debug::_Safe_iterator; + + public: + // types: + using value_type = _Base::value_type; + using pointer = _Base::pointer; + using const_pointer = _Base::const_pointer; + using reference = _Base::reference; + using const_reference = _Base::const_reference; + using size_type = _Base::size_type; + using difference_type = _Base::difference_type; + using iterator + = __gnu_debug::_Safe_iterator<_Base_iterator, inplace_vector>; + using const_iterator + = __gnu_debug::_Safe_iterator<_Base_const_iterator, inplace_vector>; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + constexpr + inplace_vector() noexcept = default; + + constexpr explicit + inplace_vector(size_type __n) + : _Base(__n) { } + + constexpr + inplace_vector(size_type __n, const _Tp& __value) + : _Base(__n, __value) { } + + template<__any_input_iterator _InputIterator> + constexpr + inplace_vector(_InputIterator __first, _InputIterator __last) + : _Base(__gnu_debug::__base( + __glibcxx_check_valid_constructor_range(__first, __last)), + __gnu_debug::__base(__last)) { } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr + inplace_vector(from_range_t, _Rg&& __rg) + : _Base(from_range_t{}, std::forward<_Rg>(__rg)) { } + + constexpr + inplace_vector(initializer_list<_Tp> __il) + : _Base(__il) { } + + inplace_vector(const inplace_vector&) = default; + inplace_vector(inplace_vector&&) = default; + ~inplace_vector() = default; + + inplace_vector& + operator=(const inplace_vector&) = default; + + inplace_vector& + operator=(inplace_vector&&) = default; + + constexpr inplace_vector& + operator=(initializer_list<_Tp> __il) + { + _Base::operator=(__il); + this->_M_invalidate_all(); + return *this; + } + + template<__any_input_iterator _InputIterator> + constexpr void + assign(_InputIterator __first, _InputIterator __last) + { + typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + + const auto __size = size(); + const auto __end = _Base::end(); + if (__dist.second >= __gnu_debug::__dp_sign) + _Base::assign(__gnu_debug::__unsafe(__first), + __gnu_debug::__unsafe(__last)); + else + _Base::assign(__first, __last); + + if (size() < __size) + _M_invalidate_after_nth(size()); + else if (size() > __size) + this->_M_invalidate_if(_Equal(__end)); + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr void + assign_range(_Rg&& __rg) + { + _Base::assign_range(std::forward<_Rg>(__rg)); + this->_M_invalidate_all(); + } + + constexpr void + assign(size_type __n, const _Tp& __u) + { + _Base::assign(__n, __u); + this->_M_invalidate_all(); + } + + constexpr void + assign(initializer_list<_Tp> __il) + { + _Base::assign(__il); + this->_M_invalidate_all(); + } + + // iterators + [[nodiscard]] + constexpr iterator + begin() noexcept + { return { _Base::begin(), this }; } + + [[nodiscard]] + constexpr const_iterator + begin() const noexcept + { return { _Base::begin(), this }; } + + [[nodiscard]] + constexpr iterator + end() noexcept + { return { _Base::end(), this }; } + + [[nodiscard]] + constexpr const_iterator + end() const noexcept + { return { _Base::end(), this }; } + + [[nodiscard]] + constexpr reverse_iterator + rbegin() noexcept + { return reverse_iterator(end()); } + + [[nodiscard]] + constexpr const_reverse_iterator + rbegin() const noexcept + { return const_reverse_iterator(end()); } + + [[nodiscard]] + constexpr reverse_iterator + rend() noexcept { return reverse_iterator(begin()); } + + [[nodiscard]] + constexpr const_reverse_iterator + rend() const noexcept { return const_reverse_iterator(begin()); } + + [[nodiscard]] + constexpr const_iterator + cbegin() const noexcept + { return { _Base::cbegin(), this }; } + + [[nodiscard]] + constexpr const_iterator + cend() const noexcept + { return { _Base::cend(), this }; } + + [[nodiscard]] + constexpr const_reverse_iterator + crbegin() const noexcept { return rbegin(); } + + [[nodiscard]] + constexpr const_reverse_iterator + crend() const noexcept { return rend(); } + + using _Base::empty; + using _Base::size; + using _Base::max_size; + using _Base::capacity; + + constexpr void + resize(size_type __n) + { + _Base::resize(__n); + _M_invalidate_after_nth(__n); + } + + constexpr void + resize(size_type __n, const _Tp& __c) + { + _Base::resize(__n, __c); + _M_invalidate_after_nth(__n); + } + + using _Base::reserve; + using _Base::shrink_to_fit; + + // element access + [[nodiscard]] + constexpr reference + operator[](size_type __n) + { + __glibcxx_check_subscript(__n); + return _Base::operator[](__n); + } + + [[nodiscard]] + constexpr const_reference + operator[](size_type __n) const + { + __glibcxx_check_subscript(__n); + return _Base::operator[](__n); + } + + using _Base::at; + + [[nodiscard]] + constexpr reference + front() + { + __glibcxx_check_nonempty(); + return data()[0]; + } + + [[nodiscard]] + constexpr const_reference + front() const + { + __glibcxx_check_nonempty(); + return data()[0]; + } + + [[nodiscard]] + constexpr reference + back() + { + __glibcxx_check_nonempty(); + return data()[size() - 1]; + } + + [[nodiscard]] + constexpr const_reference + back() const + { + __glibcxx_check_nonempty(); + return data()[size() - 1]; + } + + using _Base::data; + + template + constexpr _Tp& + emplace_back(_Args&&... __args) + { + const auto __end = _Base::cend(); + _Tp& __res = _Base::emplace_back(std::forward<_Args>(__args)...); + this->_M_invalidate_if(_Equal(__end)); + return __res; + } + + constexpr _Tp& + push_back(const _Tp& __x) + { return emplace_back(__x); } + + constexpr _Tp& + push_back(_Tp&& __x) + { return emplace_back(std::move(__x)); } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr void + append_range(_Rg&& __rg) + { + const auto __size = size(); + const auto __end = _Base::cend(); + _Base::append_range(__rg); + if (size() != __size) + this->_M_invalidate_if(_Equal(__end)); + } + + constexpr void + pop_back() + { + __glibcxx_check_nonempty(); + _M_invalidate_after_nth(_Base::size() - 1); + _Base::pop_back(); + } + + template + constexpr _Tp* + try_emplace_back(_Args&&... __args) + { + auto __end = _Base::cend(); + _Tp* __res = _Base::try_emplace_back(std::forward<_Args>(__args)...); + + if (__res) + this->_M_invalidate_if(_Equal(__end)); + + return __res; + } + + constexpr _Tp* + try_push_back(const _Tp& __x) + { + const auto __end = _Base::cend(); + _Tp* __res = _Base::try_push_back(__x); + + if (__res) + this->_M_invalidate_if(_Equal(__end)); + + return __res; + } + + constexpr _Tp* + try_push_back(_Tp&& __x) + { + const auto __end = _Base::cend(); + _Tp* __res = _Base::try_push_back(std::move(__x)); + + if (__res) + this->_M_invalidate_if(_Equal(__end)); + + return __res; + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr ranges::borrowed_iterator_t<_Rg> + try_append_range(_Rg&& __rg) + { + const auto __size = size(); + const auto __end = _Base::cend(); + auto __res = _Base::try_append_range(__rg); + if (size() != __size) + this->_M_invalidate_if(_Equal(__end)); + + return __res; + } + + template + constexpr _Tp& + unchecked_emplace_back(_Args&&... __args) + { + const auto __end = _Base::cend(); + _Tp& __res = + _Base::unchecked_emplace_back(std::forward<_Args>(__args)...); + + this->_M_invalidate_if(_Equal(__end)); + + return __res; + } + + constexpr _Tp& + unchecked_push_back(const _Tp& __x) + { return unchecked_emplace_back(__x); } + + constexpr _Tp& + unchecked_push_back(_Tp&& __x) + { return unchecked_emplace_back(std::move(__x)); } + + template + constexpr iterator + emplace(const_iterator __position, _Args&&... __args) + { + if (std::is_constant_evaluated()) + return iterator(_Base::emplace(__position.base(), + std::forward<_Args>(__args)...), + this); + + __glibcxx_check_insert(__position); + const difference_type __offset = __position.base() - _Base::cbegin(); + _Base_iterator __res = _Base::emplace(__position.base(), + std::forward<_Args>(__args)...); + _M_invalidate_after_nth(__offset); + return { __res, this }; + } + + constexpr iterator + insert(const_iterator __position, const _Tp& __x) + { return emplace(__position, __x); } + + constexpr iterator + insert(const_iterator __position, _Tp&& __x) + { return emplace(__position, std::move(__x)); } + + constexpr iterator + insert(const_iterator __position, size_type __n, const _Tp& __x) + { + if (std::is_constant_evaluated()) + return iterator(_Base::insert(__position.base(), __n, __x), this); + + __glibcxx_check_insert(__position); + const difference_type __offset = __position.base() - _Base::cbegin(); + _Base_iterator __res = _Base::insert(__position.base(), __n, __x); + _M_invalidate_after_nth(__offset); + return { __res, this }; + } + + template<__any_input_iterator _InputIterator> + constexpr iterator + insert(const_iterator __position, _InputIterator __first, + _InputIterator __last) + { + if (std::is_constant_evaluated()) + return iterator(_Base::insert(__position.base(), + __gnu_debug::__unsafe(__first), + __gnu_debug::__unsafe(__last)), this); + + typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; + __glibcxx_check_insert_range(__position, __first, __last, __dist); + + const difference_type __offset = __position.base() - _Base::cbegin(); + _Base_iterator __res; + if (__dist.second >= __gnu_debug::__dp_sign) + __res = _Base::insert(__position.base(), + __gnu_debug::__unsafe(__first), + __gnu_debug::__unsafe(__last)); + else + __res = _Base::insert(__position.base(), __first, __last); + + _M_invalidate_after_nth(__offset); + return { __res, this }; + } + + template<__detail::__container_compatible_range<_Tp> _Rg> + constexpr iterator + insert_range(const_iterator __position, _Rg&& __rg) + { + const auto __size = size(); + const difference_type __offset = __position.base() - _Base::cbegin(); + auto __res = _Base::insert_range(__position.base(), __rg); + if (size() > __size) + this->_M_invalidate_after_nth(__offset); + + return iterator(__res, this); + } + + constexpr iterator + insert(const_iterator __position, initializer_list<_Tp> __il) + { + if (std::is_constant_evaluated()) + return iterator(_Base::insert(__position.base(), __il), this); + + __glibcxx_check_insert(__position); + const auto __size = size(); + difference_type __offset = __position.base() - _Base::begin(); + _Base_iterator __res = _Base::insert(__position.base(), __il); + if (size() > __size) + this->_M_invalidate_after_nth(__offset); + return iterator(__res, this); + } + + constexpr iterator + erase(const_iterator __position) + { + if (std::is_constant_evaluated()) + return iterator(_Base::erase(__position.base()), this); + + __glibcxx_check_erase(__position); + difference_type __offset = __position.base() - _Base::cbegin(); + _Base_iterator __res = _Base::erase(__position.base()); + this->_M_invalidate_after_nth(__offset); + return iterator(__res, this); + } + + constexpr iterator + erase(const_iterator __first, const_iterator __last) + { + if (std::is_constant_evaluated()) + return iterator(_Base::erase(__first.base(), __last.base()), + this); + + __glibcxx_check_erase_range(__first, __last); + + if (__first.base() != __last.base()) + { + difference_type __offset = __first.base() - _Base::cbegin(); + _Base_iterator __res = _Base::erase(__first.base(), + __last.base()); + this->_M_invalidate_after_nth(__offset); + return { __res, this }; + } + else + return { _Base::begin() + (__first.base() - _Base::cbegin()), this }; + } + + constexpr void + swap(inplace_vector& __x) + noexcept(is_nothrow_swappable_v<_Tp> && is_nothrow_move_constructible_v<_Tp>) + { + this->_M_invalidate_all(); + __x._M_invalidate_all(); + _Base::swap(__x); + } + + constexpr void + clear() noexcept + { + _Base::clear(); + this->_M_invalidate_all(); + } + + constexpr friend bool + operator==(const inplace_vector& __x, const inplace_vector& __y) + { return __x._M_base() == __y._M_base(); } + + constexpr friend auto + operator<=>(const inplace_vector& __x, const inplace_vector& __y) + requires requires (const _Tp __t) { + { __t < __t } -> __detail::__boolean_testable; + } + { return __x._M_base() <=> __y._M_base(); } + + constexpr friend void + swap(inplace_vector& __x, inplace_vector& __y) + noexcept( noexcept(__x.swap(__y)) ) + { __x.swap(__y); } + + private: + constexpr _Base& + _M_base() noexcept { return *this; } + + constexpr const _Base& + _M_base() const noexcept { return *this; } + + constexpr void + _M_invalidate_after_nth(difference_type __n) noexcept + { + using _After_nth + = __gnu_debug::_After_nth_from<_Base_const_iterator>; + this->_M_invalidate_if(_After_nth(__n, _Base::cbegin())); + } + }; + + // specialization for zero capacity, that is required to be trivally copyable + // and empty regardless of _Tp. + template + class inplace_vector<_Tp, 0> + : public _GLIBCXX_STD_C::inplace_vector<_Tp, 0> + { + using _Base = _GLIBCXX_STD_C::inplace_vector<_Tp, 0>; + + public: + // types: + using value_type = _Base::value_type; + using pointer = _Base::pointer; + using const_pointer = _Base::const_pointer; + using reference = _Base::reference; + using const_reference = _Base::const_reference; + using size_type = _Base::size_type; + using difference_type = _Base::difference_type; + using iterator = _Base::iterator; + using const_iterator = _Base::const_iterator; + using reverse_iterator = _Base::reverse_iterator; + using const_reverse_iterator = _Base::const_reverse_iterator; + + inplace_vector() = default; + + constexpr explicit + inplace_vector(size_type __n) : _Base(__n) { } + + constexpr + inplace_vector(size_type __n, const _Tp& __value) + : _Base(__n, __value) { } + + template<__any_input_iterator _InputIterator> + constexpr + inplace_vector(_InputIterator __first, _InputIterator __last) + : _Base(__gnu_debug::__base( + __glibcxx_check_valid_constructor_range(__first, __last)), + __gnu_debug::__base(__last)) { } + + template <__detail::__container_compatible_range<_Tp> _Rg> + constexpr + inplace_vector(from_range_t, _Rg&& __rg) + : _Base(from_range_t{}, std::forward<_Rg>(__rg)) { } + + constexpr + inplace_vector(initializer_list<_Tp> __il) + : _Base(__il) { } + + inplace_vector(const inplace_vector&) = default; + inplace_vector(inplace_vector&&) = default; + + constexpr + ~inplace_vector() = default; + + inplace_vector& + operator=(const inplace_vector&) = default; + + inplace_vector& + operator=(inplace_vector&&) = default; + + constexpr inplace_vector& + operator=(initializer_list<_Tp> __il) + { + _Base::operator=(__il); + return *this; + } + + constexpr void + swap(inplace_vector& __x) + noexcept + { } + }; +} // namespace __debug + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + constexpr size_t + erase_if(__debug::inplace_vector<_Tp, _Nm>& __cont, _Predicate __pred) + { + if constexpr (_Nm != 0) + { + _GLIBCXX_STD_C::inplace_vector<_Tp, _Nm>& __ucont = __cont; + const auto __osz = __cont.size(); + const auto __end = __ucont.end(); + auto __removed = std::__remove_if(__ucont.begin(), __end, + std::move(__pred)); + if (__removed != __end) + { + __cont.erase(__niter_wrap(__cont.cbegin(), __removed), + __cont.cend()); + return __osz - __cont.size(); + } + } + + return 0; + } + + template + constexpr size_t + erase(__debug::inplace_vector<_Tp, _Nm>& __cont, const _Up& __value) + { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // __glibcxx_inplace_vector +#endif // _GLIBCXX_DEBUG_INPLACE_VECTOR diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h index 44622970792b..7491cc0ebe2f 100644 --- a/libstdc++-v3/include/debug/safe_base.h +++ b/libstdc++-v3/include/debug/safe_base.h @@ -254,12 +254,30 @@ namespace __gnu_debug /** Notify all iterators that reference this sequence that the sequence is being destroyed. */ _GLIBCXX20_CONSTEXPR - ~_Safe_sequence_base() + ~_Safe_sequence_base() _GLIBCXX_NOEXCEPT { if (!std::__is_constant_evaluated()) this->_M_detach_all(); } + // Copy assignment invalidate all iterators. + _GLIBCXX20_CONSTEXPR _Safe_sequence_base& + operator=(const _Safe_sequence_base&) _GLIBCXX_NOEXCEPT + { + _M_invalidate_all(); + return *this; + } + +#if __cplusplus >= 201103L + _GLIBCXX20_CONSTEXPR _Safe_sequence_base& + operator=(_Safe_sequence_base&& __x) noexcept + { + _M_invalidate_all(); + __x._M_invalidate_all(); + return *this; + } +#endif + /** Detach all iterators, leaving them singular. */ void _M_detach_all() const; @@ -292,7 +310,7 @@ namespace __gnu_debug _M_get_mutex() const _GLIBCXX_USE_NOEXCEPT; /** Invalidates all iterators. */ - void + _GLIBCXX20_CONSTEXPR void _M_invalidate_all() const { if (++_M_version == 0) _M_version = 1; } diff --git a/libstdc++-v3/include/debug/safe_container.h b/libstdc++-v3/include/debug/safe_container.h index 3341806fd596..2d0fbb8110e0 100644 --- a/libstdc++-v3/include/debug/safe_container.h +++ b/libstdc++-v3/include/debug/safe_container.h @@ -86,17 +86,22 @@ namespace __gnu_debug { } #endif - // Copy assignment invalidate all iterators. - _GLIBCXX20_CONSTEXPR +#if __cplusplus < 201103L _Safe_container& - operator=(const _Safe_container&) _GLIBCXX_NOEXCEPT + operator=(const _Safe_container& __x) { - if (!std::__is_constant_evaluated()) - this->_M_invalidate_all(); + _Base::operator=(__x); return *this; } -#if __cplusplus >= 201103L + void + _M_swap(const _Safe_container& __x) const throw() + { _Base::_M_swap(__x); } +#else + _GLIBCXX20_CONSTEXPR + _Safe_container& + operator=(const _Safe_container&) noexcept = default; + _GLIBCXX20_CONSTEXPR _Safe_container& operator=(_Safe_container&& __x) noexcept @@ -146,10 +151,6 @@ namespace __gnu_debug _M_swap_base(__x); } -#else - void - _M_swap(const _Safe_container& __x) const throw() - { _Base::_M_swap(__x); } #endif }; diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index e0b1b46939c3..80ed9570ecb4 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -1114,21 +1114,31 @@ namespace __gnu_debug /** Safe iterators know how to check if they form a valid range. */ template + _GLIBCXX20_CONSTEXPR inline bool __valid_range(const _Safe_iterator<_Iterator, _Sequence, _Category>& __first, const _Safe_iterator<_Iterator, _Sequence, _Category>& __last, typename _Distance_traits<_Iterator>::__type& __dist) - { return __first._M_valid_range(__last, __dist); } + { + if (std::__is_constant_evaluated()) + return true; + + return __first._M_valid_range(__last, __dist); + } template + _GLIBCXX20_CONSTEXPR inline bool __valid_range(const _Safe_iterator<_Iterator, _Sequence, _Category>& __first, const _Safe_iterator<_Iterator, _Sequence, _Category>& __last) { + if (std::__is_constant_evaluated()) + return true; + typename _Distance_traits<_Iterator>::__type __dist; return __first._M_valid_range(__last, __dist); } diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h index e10474aae79c..c908d1e47a90 100644 --- a/libstdc++-v3/include/debug/safe_sequence.h +++ b/libstdc++-v3/include/debug/safe_sequence.h @@ -46,6 +46,7 @@ namespace __gnu_debug _Type __value; public: + _GLIBCXX20_CONSTEXPR explicit _Not_equal_to(const _Type& __v) : __value(__v) { } bool @@ -61,6 +62,7 @@ namespace __gnu_debug _Type __value; public: + _GLIBCXX20_CONSTEXPR explicit _Equal_to(const _Type& __v) : __value(__v) { } bool @@ -80,6 +82,7 @@ namespace __gnu_debug difference_type _M_n; public: + _GLIBCXX20_CONSTEXPR _After_nth_from(const difference_type& __n, const _Iterator& __base) : _M_base(__base), _M_n(__n) { } @@ -113,7 +116,7 @@ namespace __gnu_debug true. @c __pred will be invoked with the normal iterators nested in the safe ones. */ template - void + _GLIBCXX20_CONSTEXPR void _M_invalidate_if(_Predicate __pred) const; /** Transfers all iterators @c x that reference @c from sequence, @@ -132,10 +135,31 @@ namespace __gnu_debug class _Safe_node_sequence : public _Safe_sequence<_Sequence> { + public: + _GLIBCXX20_CONSTEXPR _Safe_node_sequence& + operator=(const _Safe_node_sequence&) _GLIBCXX_NOEXCEPT + { + _M_invalidate_all(); + return *this; + } + +#if __cplusplus >= 201103L + _GLIBCXX20_CONSTEXPR _Safe_node_sequence& + operator=(_Safe_node_sequence&& __x) noexcept + { + _M_invalidate_all(); + __x._M_invalidate_all(); + return *this; + } +#endif + protected: - void + _GLIBCXX20_CONSTEXPR void _M_invalidate_all() const { + if (std::__is_constant_evaluated()) + return; + typedef typename _Sequence::const_iterator _Const_iterator; typedef typename _Const_iterator::iterator_type _Base_const_iterator; typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal; diff --git a/libstdc++-v3/include/debug/safe_sequence.tcc b/libstdc++-v3/include/debug/safe_sequence.tcc index 053361dff3c0..720a18427525 100644 --- a/libstdc++-v3/include/debug/safe_sequence.tcc +++ b/libstdc++-v3/include/debug/safe_sequence.tcc @@ -33,10 +33,13 @@ namespace __gnu_debug { template template - void + _GLIBCXX20_CONSTEXPR void _Safe_sequence<_Sequence>:: _M_invalidate_if(_Predicate __pred) const { + if (std::__is_constant_evaluated()) + return; + typedef typename _Sequence::iterator iterator; typedef typename _Sequence::const_iterator const_iterator; diff --git a/libstdc++-v3/include/std/inplace_vector b/libstdc++-v3/include/std/inplace_vector index 7aa6f9d4ab28..0f7716cb64de 100644 --- a/libstdc++-v3/include/std/inplace_vector +++ b/libstdc++-v3/include/std/inplace_vector @@ -35,7 +35,7 @@ #define __glibcxx_want_inplace_vector #include -#ifdef __glibcxx_inplace_vector // C++ >= 26 +#ifdef __glibcxx_inplace_vector // C++ >= 26 #include #include #include @@ -49,6 +49,7 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CONTAINER // [indirect], class template indirect template @@ -1329,32 +1330,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } }; +_GLIBCXX_END_NAMESPACE_CONTAINER + template constexpr size_t - erase_if(inplace_vector<_Tp, _Nm>& __cont, _Predicate __pred) + erase_if(_GLIBCXX_STD_C::inplace_vector<_Tp, _Nm>& __cont, + _Predicate __pred) { - using namespace __gnu_cxx; - const auto __osz = __cont.size(); - const auto __end = __cont.end(); - auto __removed = std::__remove_if(__cont.begin(), __end, - std::move(__pred)); - if (__removed != __end) + if constexpr (_Nm != 0) { - __cont.erase(__niter_wrap(__cont.begin(), __removed), - __cont.end()); - return __osz - __cont.size(); + const auto __osz = __cont.size(); + const auto __end = __cont.end(); + auto __removed = std::__remove_if(__cont.begin(), __end, + std::move(__pred)); + if (__removed != __end) + { + __cont.erase(__removed, __end); + return __osz - __cont.size(); + } } + return 0; } - template constexpr size_t - erase(inplace_vector<_Tp, _Nm>& __cont, const _Up& __value) + erase(_GLIBCXX_STD_C::inplace_vector<_Tp, _Nm>& __cont, const _Up& __value) { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace +#ifdef _GLIBCXX_DEBUG +# include +#endif + #endif // __glibcxx_inplace_vector #endif // _GLIBCXX_INPLACE_VECTOR diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc index e9c2cdc8665a..45685c2beccf 100644 --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/1.cc @@ -24,7 +24,7 @@ struct U }; // n5008 inplace.vector.overview says for inplace_vector -// provides trivial copy/move/default cosntructpr regardless of T +// provides trivial copy/move/default constructor regardless of T struct Z { constexpr Z(int) {} @@ -52,11 +52,13 @@ static_assert(!std::is_trivially_default_constructible_v>); static_assert(!std::is_trivially_default_constructible_v>); +#if !_GLIBCXX_DEBUG static_assert(std::is_trivially_destructible_v>); static_assert(std::is_trivially_destructible_v>); static_assert(std::is_trivially_destructible_v>); static_assert(!std::is_trivially_destructible_v>); static_assert(std::is_trivially_destructible_v>); +#endif static_assert(std::is_nothrow_default_constructible_v>); static_assert(std::is_nothrow_default_constructible_v>); diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/copy.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/copy.cc index d149e63970c9..917eebd80f7c 100644 --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/copy.cc +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/copy.cc @@ -72,12 +72,14 @@ static_assert(!std::is_nothrow_copy_constructible_v>); static_assert(!std::is_nothrow_copy_constructible_v>); +#if !_GLIBCXX_DEBUG static_assert(std::is_trivially_copy_constructible_v>); static_assert(!std::is_trivially_copy_constructible_v>); static_assert(!std::is_trivially_copy_constructible_v, 2>>); // is_trivially_copy_constructible_v checks destructor static_assert(!std::is_trivially_copy_constructible_v>); static_assert(std::is_trivially_copy_constructible_v>); +#endif static_assert(std::is_copy_assignable_v>); static_assert(std::is_copy_assignable_v>); @@ -96,6 +98,7 @@ static_assert(!std::is_nothrow_copy_assignable_v>); static_assert(!std::is_nothrow_copy_assignable_v>); +#if !_GLIBCXX_DEBUG // conditional noexcept here is libstdc++ extension, static_assert(std::is_trivially_copy_assignable_v>); static_assert(!std::is_trivially_copy_assignable_v>); @@ -103,6 +106,7 @@ static_assert(!std::is_trivially_copy_assignable_v>); static_assert(std::is_trivially_copy_assignable_v>); +#endif static_assert(std::is_nothrow_copy_constructible_v>); static_assert(std::is_nothrow_copy_constructible_v>); diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign1_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign1_neg.cc new file mode 100644 index 000000000000..37c80c32bbde --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign1_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_assign1 >(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign2_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign2_neg.cc new file mode 100644 index 000000000000..ff6c9a73acc7 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign2_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_assign2>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign3_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign3_neg.cc new file mode 100644 index 000000000000..42f811d07e11 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign3_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_assign3>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_backtrace_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_backtrace_neg.cc new file mode 100644 index 000000000000..dec72289fbcb --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_backtrace_neg.cc @@ -0,0 +1,17 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++exp" } +// { dg-require-cpp-feature-test __cpp_lib_stacktrace } + +#include +#include + +void test01() +{ + __gnu_test::check_assign1<__gnu_debug::inplace_vector>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_neg.cc new file mode 100644 index 000000000000..4bed3456e78b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/assign4_neg.cc @@ -0,0 +1,15 @@ +// { dg-do run { target c++26 xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_assign1<__gnu_debug::inplace_vector>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct1_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct1_neg.cc new file mode 100644 index 000000000000..28ede4c47b92 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct1_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_construct1 >(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct2_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct2_neg.cc new file mode 100644 index 000000000000..be37ddeaaf2d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct2_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_construct2 >(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct3_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct3_neg.cc new file mode 100644 index 000000000000..80861831b480 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct3_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_construct3 >(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct4_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct4_neg.cc new file mode 100644 index 000000000000..099b35727aeb --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/construct4_neg.cc @@ -0,0 +1,15 @@ +// { dg-do run { target c++26 xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_construct1<__gnu_debug::inplace_vector >(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/debug_functions.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/debug_functions.cc new file mode 100644 index 000000000000..bc5ed50113f7 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/debug_functions.cc @@ -0,0 +1,34 @@ +// { dg-do run { target c++26 } } +// { dg-require-debug-mode "" } + +#include +#include + +void test02() +{ + using namespace __gnu_debug; + + std::inplace_vector v1(3, 1); + VERIFY( !__check_singular(v1.begin()) ); + auto it = v1.begin(); + VERIFY( !__check_singular(it) ); + + VERIFY( !__check_singular(v1.end()) ); + it = v1.end(); + VERIFY( !__check_singular(it) ); + + v1.clear(); + + VERIFY( it._M_singular() ); + VERIFY( __check_singular(it) ); + + it = v1.end(); + VERIFY( !it._M_singular() ); + VERIFY( !__check_singular(it) ); +} + +int main() +{ + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/erase.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/erase.cc new file mode 100644 index 000000000000..94da94627f37 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/erase.cc @@ -0,0 +1,35 @@ +// { dg-do run { target c++26 } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + std::inplace_vector v; + + for (int i = 0; i != 10; ++i) + v.push_back(i); + + auto before = v.begin() + 4; + auto last = v.end() - 1; + + VERIFY( std::erase(v, 6) == 1 ); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_singular()); +} + +void test02() +{ + std::inplace_vector v; + + VERIFY( std::erase(v, 6) == 0 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert1_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert1_neg.cc new file mode 100644 index 000000000000..f85cfaa90b42 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert1_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_insert1>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert2_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert2_neg.cc new file mode 100644 index 000000000000..6a203696ec98 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert2_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_insert2>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert3_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert3_neg.cc new file mode 100644 index 000000000000..63f6e05d6550 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert3_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_insert3>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert4_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert4_neg.cc new file mode 100644 index 000000000000..59e9f4b1722f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert4_neg.cc @@ -0,0 +1,15 @@ +// { dg-do run { target c++26 xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_insert1<__gnu_debug::inplace_vector>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert5_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert5_neg.cc new file mode 100644 index 000000000000..e1fbd65b7112 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert5_neg.cc @@ -0,0 +1,16 @@ +// { dg-do run { target c++26 xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + __gnu_test::check_insert4>(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert7_neg.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert7_neg.cc new file mode 100644 index 000000000000..c59453cc5183 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/insert7_neg.cc @@ -0,0 +1,24 @@ +// { dg-do run { target c++26 xfail *-*-* } } + +#include +#include +#include + +void +test01() +{ + __gnu_debug::inplace_vector, 10> v; + + v.emplace_back(new int(0)); + v.emplace_back(new int(1)); + + v.insert(begin(v) + 1, + make_move_iterator(begin(v)), + make_move_iterator(end(v))); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/1.cc new file mode 100644 index 000000000000..1a852739de00 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/1.cc @@ -0,0 +1,33 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +// Assignment +void test01() +{ + inplace_vector v1; + inplace_vector v2; + + auto i = v1.end(); + VERIFY(!i._M_dereferenceable() && !i._M_singular()); + + v1 = v2; + VERIFY(i._M_singular()); + + i = v1.end(); + v1.assign(v2.begin(), v2.end()); + VERIFY( !i._M_singular() ); + + i = v1.end(); + v1.assign(17, 42); + VERIFY(i._M_singular()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/2.cc new file mode 100644 index 000000000000..22d512ca107c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/2.cc @@ -0,0 +1,34 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +// Resize +void test01() +{ + inplace_vector v(10, 17); + v.reserve(20); + + auto before = v.begin() + 6; + auto at = before + 1; + auto after = at + 1; + + // Shrink. + v.resize(7); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + VERIFY(after._M_singular()); + + // Grow. + before = v.begin() + 6; + v.resize(17); + VERIFY(before._M_dereferenceable()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/3.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/3.cc new file mode 100644 index 000000000000..7b742131d485 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/3.cc @@ -0,0 +1,43 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +// Insert +void test01() +{ + inplace_vector v(10, 17); + v.reserve(30); + + // Insert a single element + auto before = v.begin() + 6; + auto at = before + 1; + auto after = at; + at = v.insert(at, 42); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_singular()); + + // Insert multiple copies + before = v.begin() + 6; + at = before + 1; + v.insert(at, 3, 42); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // Insert iterator range + static int data[] = { 2, 3, 5, 7 }; + before = v.begin() + 6; + at = before + 1; + v.insert(at, &data[0], &data[0] + 4); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/4.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/4.cc new file mode 100644 index 000000000000..7393f1ba4eee --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/4.cc @@ -0,0 +1,40 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +// Erase +void test04() +{ + inplace_vector v(20, 42); + + // Single element erase + auto before = v.begin(); + auto at = before + 3; + auto after = at; + at = v.erase(at); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_dereferenceable()); + VERIFY(after._M_singular()); + + // Multiple element erase + before = v.begin(); + at = before + 3; + v.erase(at, at + 3); + VERIFY(before._M_dereferenceable()); + VERIFY(at._M_singular()); + + // clear() + before = v.begin(); + VERIFY(before._M_dereferenceable()); + v.clear(); + VERIFY(before._M_singular()); +} + +int main() +{ + test04(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/append_range.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/append_range.cc new file mode 100644 index 000000000000..8a793ec92b62 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/append_range.cc @@ -0,0 +1,45 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v(10, 17); + inplace_vector v1(10, 19); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + v.append_range(v1); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(end._M_singular()); +} + +void test02() +{ + inplace_vector v(10, 17); + inplace_vector v1; + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + v.append_range(v1); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(!end._M_singular()); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/erase.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/erase.cc new file mode 100644 index 000000000000..6e899d72b792 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/erase.cc @@ -0,0 +1,36 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v; + + for (int i = 0; i != 10; ++i) + v.push_back(i); + + auto before = v.begin() + 4; + auto last = v.end() - 1; + + VERIFY( std::erase(v, 6) == 1 ); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_singular()); +} + +void test02() +{ + inplace_vector v; + + VERIFY( std::erase(v, 6) == 0 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/pop_back.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/pop_back.cc new file mode 100644 index 000000000000..4c1a04338878 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/pop_back.cc @@ -0,0 +1,27 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v(10, 17); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + v.pop_back(); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_singular()); + VERIFY(end._M_singular()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/push_back.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/push_back.cc new file mode 100644 index 000000000000..f269364cf5b2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/push_back.cc @@ -0,0 +1,53 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v(10, 17); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + v.push_back(42); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(end._M_singular()); +} + +#if __cpp_exceptions +void test02() +{ + inplace_vector v(10, 17); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + try + { + v.push_back(42); + VERIFY( false ); + } + catch (std::bad_alloc&) + { + } + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(!end._M_singular()); +} +#endif + +int main() +{ + test01(); +#if __cpp_exceptions + test02(); +#endif + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/swap.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/swap.cc new file mode 100644 index 000000000000..3e5ab7409b6c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/swap.cc @@ -0,0 +1,53 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v1; + inplace_vector v2; + + for (int i = 0; i != 10; ++i) + { + v1.push_back(i); + v2.push_back(i); + } + + auto it1 = v1.begin(); + auto it2 = v2.begin(); + + std::swap(v1, v2); + + VERIFY(it1._M_singular()); + VERIFY(it2._M_singular()); +} + +void test02() +{ + inplace_vector v1; + inplace_vector v2; + + for (int i = 0; i != 10; ++i) + { + v1.push_back(i); + v2.push_back(i); + } + + auto it1 = v1.begin(); + auto it2 = v2.begin(); + + swap(v1, v2); + + VERIFY(it1._M_singular()); + VERIFY(it2._M_singular()); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc new file mode 100644 index 000000000000..ae4ac418f501 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc @@ -0,0 +1,45 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v(10, 17); + inplace_vector v1(10, 19); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + v.try_append_range(v1); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(end._M_singular()); +} + +void test02() +{ + inplace_vector v(10, 17); + inplace_vector v1; + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + v.try_append_range(v1); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(!end._M_singular()); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc new file mode 100644 index 000000000000..f7c8c7a9ba20 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc @@ -0,0 +1,27 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v(10, 17); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + VERIFY( v.try_emplace_back(42) != nullptr ); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(end._M_singular()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc new file mode 100644 index 000000000000..04fc010e5003 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc @@ -0,0 +1,45 @@ +// { dg-do run { target c++26 } } + +#include +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v(10, 17); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + VERIFY( v.try_push_back(42) != nullptr ); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(end._M_singular()); +} + +void test02() +{ + std::vector vv { 0, 1, 2, 3, 4, 5 }; + inplace_vector, 100> v(10, vv); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + VERIFY( v.try_push_back(std::move(vv)) != nullptr ); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(end._M_singular()); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/unchecked_emplace_back.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/unchecked_emplace_back.cc new file mode 100644 index 000000000000..0d173d5885d5 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/unchecked_emplace_back.cc @@ -0,0 +1,27 @@ +// { dg-do run { target c++26 } } + +#include +#include + +using __gnu_debug::inplace_vector; + +void test01() +{ + inplace_vector v(10, 17); + + auto before = v.begin() + 6; + auto last = v.end(); + auto end = last--; + + v.unchecked_emplace_back(42); + + VERIFY(before._M_dereferenceable()); + VERIFY(last._M_dereferenceable()); + VERIFY(end._M_singular()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/move.cc b/libstdc++-v3/testsuite/23_containers/inplace_vector/move.cc index 5abcc8764bd5..e8703e027fe3 100644 --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/move.cc +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/move.cc @@ -91,12 +91,14 @@ static_assert(!std::is_nothrow_move_constructible_v>); static_assert(!std::is_nothrow_move_constructible_v>); +#if !_GLIBCXX_DEBUG static_assert(std::is_trivially_move_constructible_v>); static_assert(!std::is_trivially_move_constructible_v>); static_assert(!std::is_trivially_move_constructible_v, 2>>); // is_trivially_move_constructible_v checks destructor static_assert(!std::is_trivially_move_constructible_v>); static_assert(std::is_trivially_move_constructible_v>); +#endif static_assert(std::is_move_assignable_v>); static_assert(std::is_move_assignable_v>); @@ -115,12 +117,14 @@ static_assert(!std::is_nothrow_move_assignable_v>); static_assert(!std::is_nothrow_move_assignable_v>); +#if !_GLIBCXX_DEBUG static_assert(std::is_trivially_move_assignable_v>); static_assert(!std::is_trivially_move_assignable_v>); static_assert(!std::is_trivially_move_assignable_v, 2>>); // destructor is not trivial static_assert(!std::is_trivially_move_assignable_v>); static_assert(std::is_trivially_move_assignable_v>); +#endif static_assert(std::is_nothrow_swappable_v>); static_assert(!std::is_nothrow_swappable_v>); diff --git a/libstdc++-v3/testsuite/util/debug/checks.h b/libstdc++-v3/testsuite/util/debug/checks.h index 938cddabf6d3..528c021b1d75 100644 --- a/libstdc++-v3/testsuite/util/debug/checks.h +++ b/libstdc++-v3/testsuite/util/debug/checks.h @@ -19,10 +19,12 @@ #include #include #include +#include #ifndef _GLIBCXX_DEBUG # include # include # include +# include #endif #include @@ -88,10 +90,11 @@ namespace __gnu_test void check_assign1() { + using namespace std; typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; - typedef std::vector vector_type; + typedef _GLIBCXX_STD_C::vector vector_type; generate_unique gu; @@ -116,10 +119,11 @@ namespace __gnu_test void check_assign2() { + using namespace std; typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; - typedef std::vector vector_type; + typedef _GLIBCXX_STD_C::vector vector_type; generate_unique gu; @@ -170,10 +174,11 @@ namespace __gnu_test void check_construct1() { + using namespace std; typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; - typedef std::vector vector_type; + typedef _GLIBCXX_STD_C::vector vector_type; generate_unique gu; @@ -193,10 +198,11 @@ namespace __gnu_test void check_construct2() { + using namespace std; typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; - typedef std::vector vector_type; + typedef _GLIBCXX_STD_C::vector vector_type; generate_unique gu; @@ -267,6 +273,13 @@ namespace __gnu_test : InsertRangeHelperAux > { }; +#ifdef __glibcxx_inplace_vector // C++ >= 26 + template + struct InsertRangeHelper > + : InsertRangeHelperAux > + { }; +#endif + #ifndef _GLIBCXX_DEBUG template struct InsertRangeHelper<__gnu_debug::vector<_Tp1, _Tp2> > @@ -282,16 +295,24 @@ namespace __gnu_test struct InsertRangeHelper<__gnu_debug::list<_Tp1, _Tp2> > : InsertRangeHelperAux<__gnu_debug::list<_Tp1, _Tp2> > { }; + +# ifdef __glibcxx_inplace_vector // C++ >= 26 + template + struct InsertRangeHelper<__gnu_debug::inplace_vector<_Tp, _Nm> > + : InsertRangeHelperAux<__gnu_debug::inplace_vector<_Tp, _Nm> > + { }; +# endif #endif template void check_insert1() { + using namespace std; typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; - typedef std::vector vector_type; + typedef _GLIBCXX_STD_C::vector vector_type; generate_unique gu; @@ -315,10 +336,11 @@ namespace __gnu_test void check_insert2() { + using namespace std; typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; - typedef std::vector vector_type; + typedef _GLIBCXX_STD_C::vector vector_type; generate_unique gu; @@ -369,10 +391,11 @@ namespace __gnu_test void check_insert4() { + using namespace std; typedef _Tp cont_type; typedef typename cont_type::value_type cont_val_type; typedef typename CopyableValueType::value_type val_type; - typedef std::list list_type; + typedef _GLIBCXX_STD_C::list list_type; generate_unique gu; -- 2.47.3