47-vector.patch 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. diff --git a/include/vector b/include/vector
  2. index 1defc43..8d5b846 100644
  3. --- a/include/vector
  4. +++ b/include/vector
  5. @@ -348,6 +348,7 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
  6. #include <__type_traits/is_allocator.h>
  7. #include <__type_traits/is_constructible.h>
  8. #include <__type_traits/is_nothrow_assignable.h>
  9. +#include <__type_traits/is_trivially_destructible.h>
  10. #include <__type_traits/noexcept_move_assign_container.h>
  11. #include <__type_traits/type_identity.h>
  12. #include <__utility/exception_guard.h>
  13. @@ -705,12 +706,22 @@ public:
  14. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position);
  15. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last);
  16. - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
  17. + _LIBCPP_REINITIALIZES_OBJECT _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT {
  18. size_type __old_size = size();
  19. __clear();
  20. __annotate_shrink(__old_size);
  21. }
  22. +#if _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED
  23. + // This function works only for POD types, otherwise memory leak may occur.
  24. +# if _LIBCPP_STD_VER >= 20
  25. + void resize_uninitialized(size_type __sz)
  26. + requires is_trivially_destructible_v<_Tp>;
  27. +# else
  28. + void resize_uninitialized(size_type __sz);
  29. +# endif
  30. +#endif
  31. +
  32. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz);
  33. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz, const_reference __x);
  34. @@ -793,7 +804,7 @@ private:
  35. template <class _InputIterator, class _Sentinel>
  36. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
  37. __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n);
  38. -
  39. + void __append_uninitialized(size_type __n);
  40. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n);
  41. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x);
  42. _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator __make_iter(pointer __p) _NOEXCEPT {
  43. @@ -1100,6 +1111,19 @@ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __
  44. __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_);
  45. }
  46. +template <class _Tp, class _Allocator>
  47. +void vector<_Tp, _Allocator>::__append_uninitialized(size_type __n) {
  48. + if (static_cast<size_type>(this->__end_cap() - this->__end_) >= __n) {
  49. + __annotate_increase(__n);
  50. + this->__end_ += __n;
  51. + } else {
  52. + allocator_type& __a = this->__alloc();
  53. + __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), __a);
  54. + __v.__uninitialized_at_end(__n);
  55. + __swap_out_circular_buffer(__v);
  56. + }
  57. +}
  58. +
  59. // Default constructs __n objects starting at __end_
  60. // throws if construction throws
  61. // Postcondition: size() == size() + __n
  62. @@ -1778,6 +1802,25 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::resize(size_type __s
  63. this->__destruct_at_end(this->__begin_ + __sz);
  64. }
  65. +#if _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED
  66. +
  67. +template <class _Tp, class _Allocator>
  68. +void vector<_Tp, _Allocator>::resize_uninitialized(size_type __sz)
  69. +# if _LIBCPP_STD_VER >= 20
  70. + requires is_trivially_destructible_v<_Tp>
  71. +# endif
  72. +{
  73. + size_type __cs = size();
  74. + if (__cs < __sz)
  75. + this->__append_uninitialized(__sz - __cs);
  76. + else if (__cs > __sz) {
  77. + this->__end_ = this->__begin_ + __sz;
  78. + __annotate_shrink(__cs);
  79. + }
  80. +}
  81. +
  82. +#endif
  83. +
  84. template <class _Tp, class _Allocator>
  85. _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::swap(vector& __x)
  86. #if _LIBCPP_STD_VER >= 14
  87. @@ -1813,6 +1856,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector<_Tp, _Allocator>::__invariants() const
  88. return true;
  89. }
  90. +#if _YNDX_LIBCXX_ENABLE_VECTOR_BOOL_COMPRESSION == 1
  91. // vector<bool>
  92. template <class _Allocator>
  93. @@ -2118,7 +2162,9 @@ public:
  94. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __position);
  95. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __first, const_iterator __last);
  96. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT { __size_ = 0; }
  97. + _LIBCPP_REINITIALIZES_OBJECT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT {
  98. + __size_ = 0;
  99. + }
  100. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&)
  101. #if _LIBCPP_STD_VER >= 14
  102. @@ -2872,6 +2918,30 @@ struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> >
  103. return __vec.__hash_code();
  104. }
  105. };
  106. +#else // _YNDX_LIBCXX_ENABLE_VECTOR_BOOL_COMPRESSION
  107. +// Hash function implementation for uncompressed std::vector<bool> which returns the same result.
  108. +template <class _Allocator>
  109. +struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> > : public unary_function<vector<bool, _Allocator>, size_t> {
  110. + _LIBCPP_HIDE_FROM_ABI
  111. + size_t operator()(const vector<bool, _Allocator>& __vec) const _NOEXCEPT {
  112. + size_t __h = 0;
  113. + size_t __idx = 0;
  114. + size_t __n = __vec.size();
  115. + constexpr size_t __bits_per_word = sizeof(typename allocator_traits<_Allocator>::size_type) * CHAR_BIT;
  116. + static_assert(
  117. + sizeof(typename allocator_traits<_Allocator>::size_type) <= sizeof(size_t), "size_type constraint violated");
  118. + for (; __idx + __bits_per_word <= __n;) {
  119. + for (size_t __bit = 0; __bit < __bits_per_word; __bit++, __idx++) {
  120. + __h ^= static_cast<size_t>(__vec[__idx]) << __bit;
  121. + }
  122. + }
  123. + for (size_t __bit = 0; __idx < __n; __bit++, __idx++) {
  124. + __h ^= static_cast<size_t>(__vec[__idx]) << __bit;
  125. + }
  126. + return __h;
  127. + }
  128. +};
  129. +#endif // _YNDX_LIBCXX_ENABLE_VECTOR_BOOL_COMPRESSION
  130. template <class _Tp, class _Allocator>
  131. _LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI bool