mirror of git://gcc.gnu.org/git/gcc.git
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 <debug/inplace_vector>. * 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.
This commit is contained in:
parent
6cae8aac08
commit
8a2e6590cc
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -53,15 +53,19 @@ namespace __gnu_debug
|
|||
* assertion statement because, e.g., we are in a constructor.
|
||||
*/
|
||||
template<typename _InputIterator>
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ namespace __gnu_debug
|
|||
}
|
||||
|
||||
template<typename _Iterator, typename _Sequence, typename _Category>
|
||||
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<typename _Iterator, typename _Sequence, typename _Category>
|
||||
bool
|
||||
_GLIBCXX20_CONSTEXPR bool
|
||||
__valid_range(const _Safe_iterator<_Iterator, _Sequence, _Category>&,
|
||||
const _Safe_iterator<_Iterator, _Sequence, _Category>&);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @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 <debug/debug.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default) { namespace __debug {
|
||||
template<typename _Tp, size_t _Nm> class inplace_vector;
|
||||
} } // namespace std::__debug
|
||||
|
||||
#include <inplace_vector>
|
||||
|
||||
#ifdef __glibcxx_inplace_vector // C++ >= 26
|
||||
|
||||
#include <debug/safe_sequence.h>
|
||||
#include <debug/safe_iterator.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
namespace __debug
|
||||
{
|
||||
/// Class std::inplace_vector with safety/checking/debug instrumentation.
|
||||
template<typename _Tp, size_t _Nm>
|
||||
class inplace_vector
|
||||
: public __gnu_debug::_Safe_sequence<inplace_vector<_Tp, _Nm>>
|
||||
, 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<typename _ItT, typename _SeqT, typename _CatT>
|
||||
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<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_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<typename... _Args>
|
||||
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<typename... _Args>
|
||||
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<typename... _Args>
|
||||
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<typename... _Args>
|
||||
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<typename _Tp>
|
||||
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<typename _Tp, size_t _Nm, typename _Predicate>
|
||||
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<typename _Tp, size_t _Nm, typename _Up = _Tp>
|
||||
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
|
||||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1114,21 +1114,31 @@ namespace __gnu_debug
|
|||
|
||||
/** Safe iterators know how to check if they form a valid range. */
|
||||
template<typename _Iterator, typename _Sequence, typename _Category>
|
||||
_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<typename _Iterator, typename _Sequence, typename _Category>
|
||||
_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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<typename _Predicate>
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -33,10 +33,13 @@ namespace __gnu_debug
|
|||
{
|
||||
template<typename _Sequence>
|
||||
template<typename _Predicate>
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#define __glibcxx_want_inplace_vector
|
||||
#include <bits/version.h>
|
||||
|
||||
#ifdef __glibcxx_inplace_vector // C++ >= 26
|
||||
#ifdef __glibcxx_inplace_vector // C++ >= 26
|
||||
#include <compare>
|
||||
#include <initializer_list>
|
||||
#include <bits/range_access.h>
|
||||
|
|
@ -49,6 +49,7 @@
|
|||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
|
||||
// [indirect], class template indirect
|
||||
template<typename _Tp, size_t _Nm>
|
||||
|
|
@ -1329,32 +1330,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
{ }
|
||||
};
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_CONTAINER
|
||||
|
||||
template<typename _Tp, size_t _Nm, typename _Predicate>
|
||||
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<typename _Tp, size_t _Nm, typename _Up = _Tp>
|
||||
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 <debug/inplace_vector>
|
||||
#endif
|
||||
|
||||
#endif // __glibcxx_inplace_vector
|
||||
#endif // _GLIBCXX_INPLACE_VECTOR
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ struct U
|
|||
};
|
||||
|
||||
// n5008 inplace.vector.overview says for inplace_vector<T, 0>
|
||||
// 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<std::inplace_vector<N,
|
|||
static_assert(!std::is_trivially_default_constructible_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(!std::is_trivially_default_constructible_v<std::inplace_vector<U, 2>>);
|
||||
|
||||
#if !_GLIBCXX_DEBUG
|
||||
static_assert(std::is_trivially_destructible_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(std::is_trivially_destructible_v<std::inplace_vector<X, 2>>);
|
||||
static_assert(std::is_trivially_destructible_v<std::inplace_vector<N, 2>>);
|
||||
static_assert(!std::is_trivially_destructible_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(std::is_trivially_destructible_v<std::inplace_vector<U, 2>>);
|
||||
#endif
|
||||
|
||||
static_assert(std::is_nothrow_default_constructible_v<std::inplace_vector<int, 0>>);
|
||||
static_assert(std::is_nothrow_default_constructible_v<std::inplace_vector<X, 0>>);
|
||||
|
|
|
|||
|
|
@ -72,12 +72,14 @@ static_assert(!std::is_nothrow_copy_constructible_v<std::inplace_vector<N<false,
|
|||
static_assert(std::is_nothrow_copy_constructible_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(!std::is_nothrow_copy_constructible_v<std::inplace_vector<U, 2>>);
|
||||
|
||||
#if !_GLIBCXX_DEBUG
|
||||
static_assert(std::is_trivially_copy_constructible_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(!std::is_trivially_copy_constructible_v<std::inplace_vector<X, 2>>);
|
||||
static_assert(!std::is_trivially_copy_constructible_v<std::inplace_vector<N<true, true>, 2>>);
|
||||
// is_trivially_copy_constructible_v checks destructor
|
||||
static_assert(!std::is_trivially_copy_constructible_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(std::is_trivially_copy_constructible_v<std::inplace_vector<U, 2>>);
|
||||
#endif
|
||||
|
||||
static_assert(std::is_copy_assignable_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(std::is_copy_assignable_v<std::inplace_vector<X, 2>>);
|
||||
|
|
@ -96,6 +98,7 @@ static_assert(!std::is_nothrow_copy_assignable_v<std::inplace_vector<N<false, fa
|
|||
static_assert(std::is_nothrow_copy_assignable_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(!std::is_nothrow_copy_assignable_v<std::inplace_vector<U, 2>>);
|
||||
|
||||
#if !_GLIBCXX_DEBUG
|
||||
// conditional noexcept here is libstdc++ extension,
|
||||
static_assert(std::is_trivially_copy_assignable_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(!std::is_trivially_copy_assignable_v<std::inplace_vector<X, 2>>);
|
||||
|
|
@ -103,6 +106,7 @@ static_assert(!std::is_trivially_copy_assignable_v<std::inplace_vector<N<true, t
|
|||
// destructor is not trivial
|
||||
static_assert(!std::is_trivially_copy_assignable_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(std::is_trivially_copy_assignable_v<std::inplace_vector<U, 2>>);
|
||||
#endif
|
||||
|
||||
static_assert(std::is_nothrow_copy_constructible_v<std::inplace_vector<int, 0>>);
|
||||
static_assert(std::is_nothrow_copy_constructible_v<std::inplace_vector<X, 0>>);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_assign1<std::inplace_vector<int, 10> >();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_assign2<std::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_assign3<std::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -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 <debug/inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_assign1<__gnu_debug::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_assign1<__gnu_debug::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_construct1<std::inplace_vector<int, 10> >();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_construct2<std::inplace_vector<int, 10> >();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_construct3<std::inplace_vector<int, 10> >();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_construct1<__gnu_debug::inplace_vector<int, 10> >();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test02()
|
||||
{
|
||||
using namespace __gnu_debug;
|
||||
|
||||
std::inplace_vector<int, 10> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
std::inplace_vector<int, 10> 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<int, 0> v;
|
||||
|
||||
VERIFY( std::erase(v, 6) == 0 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_insert1<std::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_insert2<std::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_insert3<std::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_insert1<__gnu_debug::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
// { dg-require-debug-mode "" }
|
||||
|
||||
#include <inplace_vector>
|
||||
#include <debug/checks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
__gnu_test::check_insert4<std::inplace_vector<int, 10>>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// { dg-do run { target c++26 xfail *-*-* } }
|
||||
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <debug/inplace_vector>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
__gnu_debug::inplace_vector<std::unique_ptr<int>, 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();
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
// Assignment
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 30> v1;
|
||||
inplace_vector<int, 30> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
// Resize
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 50> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
// Insert
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
// Erase
|
||||
void test04()
|
||||
{
|
||||
inplace_vector<int, 30> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> v(10, 17);
|
||||
inplace_vector<int, 10> 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<int, 100> v(10, 17);
|
||||
inplace_vector<int, 0> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 10> 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<int, 0> v;
|
||||
|
||||
VERIFY( std::erase(v, 6) == 0 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> 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<int, 10> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 10> v1;
|
||||
inplace_vector<int, 10> 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<int, 10> v1;
|
||||
inplace_vector<int, 10> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> v(10, 17);
|
||||
inplace_vector<int, 10> 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<int, 100> v(10, 17);
|
||||
inplace_vector<int, 0> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> 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<int> vv { 0, 1, 2, 3, 4, 5 };
|
||||
inplace_vector<std::vector<int>, 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// { dg-do run { target c++26 } }
|
||||
|
||||
#include <debug/inplace_vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using __gnu_debug::inplace_vector;
|
||||
|
||||
void test01()
|
||||
{
|
||||
inplace_vector<int, 100> 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;
|
||||
}
|
||||
|
|
@ -91,12 +91,14 @@ static_assert(!std::is_nothrow_move_constructible_v<std::inplace_vector<N<false,
|
|||
static_assert(std::is_nothrow_move_constructible_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(!std::is_nothrow_move_constructible_v<std::inplace_vector<U, 2>>);
|
||||
|
||||
#if !_GLIBCXX_DEBUG
|
||||
static_assert(std::is_trivially_move_constructible_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(!std::is_trivially_move_constructible_v<std::inplace_vector<X, 2>>);
|
||||
static_assert(!std::is_trivially_move_constructible_v<std::inplace_vector<N<true, true>, 2>>);
|
||||
// is_trivially_move_constructible_v checks destructor
|
||||
static_assert(!std::is_trivially_move_constructible_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(std::is_trivially_move_constructible_v<std::inplace_vector<U, 2>>);
|
||||
#endif
|
||||
|
||||
static_assert(std::is_move_assignable_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(std::is_move_assignable_v<std::inplace_vector<X, 2>>);
|
||||
|
|
@ -115,12 +117,14 @@ static_assert(!std::is_nothrow_move_assignable_v<std::inplace_vector<N<false, fa
|
|||
static_assert(std::is_nothrow_move_assignable_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(!std::is_nothrow_move_assignable_v<std::inplace_vector<U, 2>>);
|
||||
|
||||
#if !_GLIBCXX_DEBUG
|
||||
static_assert(std::is_trivially_move_assignable_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(!std::is_trivially_move_assignable_v<std::inplace_vector<X, 2>>);
|
||||
static_assert(!std::is_trivially_move_assignable_v<std::inplace_vector<N<true, true>, 2>>);
|
||||
// destructor is not trivial
|
||||
static_assert(!std::is_trivially_move_assignable_v<std::inplace_vector<D, 2>>);
|
||||
static_assert(std::is_trivially_move_assignable_v<std::inplace_vector<U, 2>>);
|
||||
#endif
|
||||
|
||||
static_assert(std::is_nothrow_swappable_v<std::inplace_vector<int, 2>>);
|
||||
static_assert(!std::is_nothrow_swappable_v<std::inplace_vector<X, 2>>);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
#include <vector>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <inplace_vector>
|
||||
#ifndef _GLIBCXX_DEBUG
|
||||
# include <debug/vector>
|
||||
# include <debug/deque>
|
||||
# include <debug/list>
|
||||
# include <debug/inplace_vector>
|
||||
#endif
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
|
|
@ -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<cont_val_type>::value_type val_type;
|
||||
typedef std::vector<val_type> vector_type;
|
||||
typedef _GLIBCXX_STD_C::vector<val_type> vector_type;
|
||||
|
||||
generate_unique<val_type> 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<cont_val_type>::value_type val_type;
|
||||
typedef std::vector<val_type> vector_type;
|
||||
typedef _GLIBCXX_STD_C::vector<val_type> vector_type;
|
||||
|
||||
generate_unique<val_type> 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<cont_val_type>::value_type val_type;
|
||||
typedef std::vector<val_type> vector_type;
|
||||
typedef _GLIBCXX_STD_C::vector<val_type> vector_type;
|
||||
|
||||
generate_unique<val_type> 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<cont_val_type>::value_type val_type;
|
||||
typedef std::vector<val_type> vector_type;
|
||||
typedef _GLIBCXX_STD_C::vector<val_type> vector_type;
|
||||
|
||||
generate_unique<val_type> gu;
|
||||
|
||||
|
|
@ -267,6 +273,13 @@ namespace __gnu_test
|
|||
: InsertRangeHelperAux<std::list<_Tp1, _Tp2> >
|
||||
{ };
|
||||
|
||||
#ifdef __glibcxx_inplace_vector // C++ >= 26
|
||||
template<typename _Tp, size_t _Nm>
|
||||
struct InsertRangeHelper<std::inplace_vector<_Tp, _Nm> >
|
||||
: InsertRangeHelperAux<std::inplace_vector<_Tp, _Nm> >
|
||||
{ };
|
||||
#endif
|
||||
|
||||
#ifndef _GLIBCXX_DEBUG
|
||||
template <typename _Tp1, typename _Tp2>
|
||||
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<typename _Tp, size_t _Nm>
|
||||
struct InsertRangeHelper<__gnu_debug::inplace_vector<_Tp, _Nm> >
|
||||
: InsertRangeHelperAux<__gnu_debug::inplace_vector<_Tp, _Nm> >
|
||||
{ };
|
||||
# endif
|
||||
#endif
|
||||
|
||||
template<typename _Tp>
|
||||
void
|
||||
check_insert1()
|
||||
{
|
||||
using namespace std;
|
||||
typedef _Tp cont_type;
|
||||
typedef typename cont_type::value_type cont_val_type;
|
||||
typedef typename CopyableValueType<cont_val_type>::value_type val_type;
|
||||
typedef std::vector<val_type> vector_type;
|
||||
typedef _GLIBCXX_STD_C::vector<val_type> vector_type;
|
||||
|
||||
generate_unique<val_type> 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<cont_val_type>::value_type val_type;
|
||||
typedef std::vector<val_type> vector_type;
|
||||
typedef _GLIBCXX_STD_C::vector<val_type> vector_type;
|
||||
|
||||
generate_unique<val_type> 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<cont_val_type>::value_type val_type;
|
||||
typedef std::list<val_type> list_type;
|
||||
typedef _GLIBCXX_STD_C::list<val_type> list_type;
|
||||
|
||||
generate_unique<val_type> gu;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue