From ccc9efcd74969ff99fb97bd48ae6b37fe136b019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 9 Dec 2025 17:11:57 +0100 Subject: [PATCH] Make static_vector's destructor trivial if T is trivial. --- doc/container.qbk | 3 +- include/boost/container/detail/workaround.hpp | 4 +++ include/boost/container/vector.hpp | 10 ++++++ test/static_vector_test.cpp | 31 +++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/doc/container.qbk b/doc/container.qbk index e931440..ff4b86b 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1437,6 +1437,7 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes_boost_1_91_00 Boost 1.91 Release] * Implemented heterogeneous overloads from C++23 ([@http://wg21.link/p2077r3 P2077]) and C++26 ([@http://wg21.link/P2363 P2363]). +* In C++20 compilers, `static_vector`'s destructor is now trivial if `T` is trivial. * Fixed bugs/issues: * [@https://github.com/boostorg/container/issues/323 GitHub #323: ['"flat_tree::try_emplace UB"]]. @@ -1447,7 +1448,7 @@ use [*Boost.Container]? There are several reasons for that: * Reimplemented [classref boost::container::deque]. The original implementation was based on the SGI's original data structure (similar to libstdc++). Main changes: * `sizeof(deque)` was 10 words, now is 4 words. Probably the lightest implementation around. - * `sizeof(deque::iterator)` was 4 words, now is is 2 words (similar to libc++ and MSVC).) + * `sizeof(deque::iterator)` was 4 words, now is is 2 words (similar to libc++ and MSVC). * Several internal algorithms were reimplemented to speed up the segmented nature of deque. * Defaults were slightly changed, 64 bit platforms now use 1024 byte blocks by default instead of classic SGI 512 byte blocks. diff --git a/include/boost/container/detail/workaround.hpp b/include/boost/container/detail/workaround.hpp index 055cf24..a4b9a33 100644 --- a/include/boost/container/detail/workaround.hpp +++ b/include/boost/container/detail/workaround.hpp @@ -242,4 +242,8 @@ namespace boost { #define BOOST_CONTAINER_GCC_COMPATIBLE_HAS_DIAGNOSTIC_IGNORED #endif +#if defined(__cpp_concepts) && (__cpp_concepts >= 202002L) +# define BOOST_CONTAINER_CONCEPTS_BASED_OVERLOADING +#endif + #endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index 162766f..a2476db 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -1223,12 +1223,22 @@ private: //! //! Complexity: Linear to the number of elements. ~vector() BOOST_NOEXCEPT_OR_NOTHROW + #if defined(BOOST_INTRUSIVE_CONCEPTS_BASED_OVERLOADING) + requires (dtl::version::value != 0 || !::boost::move_detail::is_trivially_destructible::value) + #endif { boost::container::destroy_alloc_n (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size); //vector_alloc_holder deallocates the data } + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) && defined(BOOST_INTRUSIVE_CONCEPTS_BASED_OVERLOADING) + //Default destructor for normal links (allows conditional triviality) + ~vector() + requires (dtl::version::value == 0 && ::boost::move_detail::is_trivially_destructible::value) + = default; + #endif + //! Effects: Makes *this contain the same elements as x. //! //! Postcondition: this->size() == x.size(). *this contains a copy diff --git a/test/static_vector_test.cpp b/test/static_vector_test.cpp index 1fa1ea6..68d58fe 100644 --- a/test/static_vector_test.cpp +++ b/test/static_vector_test.cpp @@ -671,6 +671,35 @@ bool default_init_test()//Test for default initialization return true; } +#if defined(BOOST_INTRUSIVE_CONCEPTS_BASED_OVERLOADING) + +#include + +template +void static_vector_destructor_triviality_impl() +{ + typedef static_vector vector_t; + BOOST_CONTAINER_STATIC_ASSERT(( Result == std::is_trivially_destructible_v )); +} + +struct non_trivial +{ + non_trivial(){} + ~non_trivial(){} +}; + +void static_vector_triviality() +{ + static_vector_destructor_triviality_impl(); + static_vector_destructor_triviality_impl(); + static_vector_destructor_triviality_impl(); +} + +#else + +void static_vector_triviality(){} + +#endif //BOOST_INTRUSIVE_CONCEPTS_BASED_OVERLOADING int main(int, char* []) { @@ -787,6 +816,8 @@ int main(int, char* []) boost::intrusive::test::test_iterator_random< cont_int >(a); } + static_vector_triviality(); + return boost::report_errors(); }