diff --git a/include/vector b/include/vector index 4ec6b60..559b7fd 100644 --- a/include/vector +++ b/include/vector @@ -343,6 +343,7 @@ template requires is-vector-bool-reference // Since C++ #include <__type_traits/is_allocator.h> #include <__type_traits/is_constructible.h> #include <__type_traits/is_nothrow_move_assignable.h> +#include <__type_traits/is_trivially_destructible.h> #include <__type_traits/noexcept_move_assign_container.h> #include <__type_traits/type_identity.h> #include <__utility/exception_guard.h> @@ -716,7 +717,7 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI + _LIBCPP_REINITIALIZES_OBJECT _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { size_type __old_size = size(); @@ -724,6 +725,15 @@ public: __annotate_shrink(__old_size); } +#if _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED + // This function works only for POD types, otherwise memory leak may occur. +#if _LIBCPP_STD_VER >= 20 + void resize_uninitialized(size_type __sz) requires is_trivially_destructible_v<_Tp>; +#else + void resize_uninitialized(size_type __sz); +#endif +#endif + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz, const_reference __x); @@ -809,7 +819,7 @@ private: template _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); - + void __append_uninitialized(size_type __n); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI @@ -1145,6 +1155,23 @@ vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __ __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_); } +template +void +vector<_Tp, _Allocator>::__append_uninitialized(size_type __n) +{ + if (static_cast(this->__end_cap() - this->__end_) >= __n) { + __annotate_increase(__n); + this->__end_ += __n; + } + else + { + allocator_type& __a = this->__alloc(); + __split_buffer __v(__recommend(size() + __n), size(), __a); + __v.__uninitialized_at_end(__n); + __swap_out_circular_buffer(__v); + } +} + // Default constructs __n objects starting at __end_ // throws if construction throws // Postcondition: size() == size() + __n @@ -2003,6 +2030,26 @@ vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) this->__destruct_at_end(this->__begin_ + __sz); } +#if _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED + +template +void +vector<_Tp, _Allocator>::resize_uninitialized(size_type __sz) +#if _LIBCPP_STD_VER >= 20 + requires is_trivially_destructible_v<_Tp> +#endif +{ + size_type __cs = size(); + if (__cs < __sz) + this->__append_uninitialized(__sz - __cs); + else if (__cs > __sz) { + this->__end_ = this->__begin_ + __sz; + __annotate_shrink(__cs); + } +} + +#endif + template _LIBCPP_CONSTEXPR_SINCE_CXX20 void @@ -2047,6 +2094,7 @@ vector<_Tp, _Allocator>::__invariants() const return true; } +#if _YNDX_LIBCXX_ENABLE_VECTOR_BOOL_COMPRESSION == 1 // vector template class vector; @@ -2360,7 +2408,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __position); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __first, const_iterator __last); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + _LIBCPP_REINITIALIZES_OBJECT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void clear() _NOEXCEPT {__size_ = 0;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&) @@ -3294,6 +3342,32 @@ struct _LIBCPP_TEMPLATE_VIS hash > size_t operator()(const vector& __vec) const _NOEXCEPT {return __vec.__hash_code();} }; +#else // _YNDX_LIBCXX_ENABLE_VECTOR_BOOL_COMPRESSION +// Hash function implementation for uncompressed std::vector which returns the same result. +template +struct _LIBCPP_TEMPLATE_VIS hash > + : public unary_function, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const vector& __vec) const _NOEXCEPT + { + size_t __h = 0; + size_t __idx = 0; + size_t __n = __vec.size(); + constexpr size_t __bits_per_word = sizeof(typename allocator_traits<_Allocator>::size_type) * CHAR_BIT; + static_assert(sizeof(typename allocator_traits<_Allocator>::size_type) <= sizeof(size_t), "size_type constraint violated"); + for (;__idx + __bits_per_word <= __n;) { + for (size_t __bit = 0; __bit < __bits_per_word; __bit++, __idx++) { + __h ^= static_cast(__vec[__idx]) << __bit; + } + } + for (size_t __bit = 0; __idx < __n; __bit++, __idx++) { + __h ^= static_cast(__vec[__idx]) << __bit; + } + return __h; + } +}; +#endif // _YNDX_LIBCXX_ENABLE_VECTOR_BOOL_COMPRESSION template _LIBCPP_CONSTEXPR_SINCE_CXX20