From 6e51fd83429be907bd901593635b9282a6065bf3 Mon Sep 17 00:00:00 2001 From: Martin Leitner-Ankerl Date: Sun, 24 Apr 2022 12:55:57 +0200 Subject: [PATCH] prevector: only allow trivially copyable types The prevector implementation currently can't be used with types that are not trivially copyable, due to the use of memmove. Trivially copyable implies that it is trivially destructible, see https://eel.is/c++draft/class.prop#1.3 That means that the checks for std::is_trivially_destructible are not necessary, and in fact where used it wouldn't be enough. E.g. in `erase(iterator, iterator)` the elements in range first-last are destructed, but it does not destruct elements left after `memmove`. This commit removes the checks for `std::is_trivially_destructible` and instead adds a `static_assert(std::is_trivially_copyable_v);` to make sure `prevector` is only used with supported types. --- src/prevector.h | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/prevector.h b/src/prevector.h index d4865bfcee..d0945d4bea 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -35,6 +35,8 @@ */ template class prevector { + static_assert(std::is_trivially_copyable_v); + public: typedef Size size_type; typedef Diff difference_type; @@ -411,15 +413,7 @@ class prevector { // representation (with capacity N and size <= N). iterator p = first; char* endp = (char*)&(*end()); - if (!std::is_trivially_destructible::value) { - while (p != last) { - (*p).~T(); - _size--; - ++p; - } - } else { - _size -= last - p; - } + _size -= last - p; memmove(&(*first), &(*last), endp - ((char*)(&(*last)))); return first; } @@ -464,9 +458,6 @@ class prevector { } ~prevector() { - if (!std::is_trivially_destructible::value) { - clear(); - } if (!is_direct()) { free(_union.indirect_contents.indirect); _union.indirect_contents.indirect = nullptr;