0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-03 09:56:38 -05:00

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<T>);` to
make sure `prevector` is only used with supported types.
This commit is contained in:
Martin Leitner-Ankerl 2022-04-24 12:55:57 +02:00
parent b1c5991eeb
commit 11e7908484
No known key found for this signature in database
GPG key ID: FBEAAD7FC6FFFE81

View file

@ -35,6 +35,8 @@
*/
template<unsigned int N, typename T, typename Size = uint32_t, typename Diff = int32_t>
class prevector {
static_assert(std::is_trivially_copyable_v<T>);
public:
typedef Size size_type;
typedef Diff difference_type;
@ -411,15 +413,7 @@ public:
// representation (with capacity N and size <= N).
iterator p = first;
char* endp = (char*)&(*end());
if (!std::is_trivially_destructible<T>::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 @@ public:
}
~prevector() {
if (!std::is_trivially_destructible<T>::value) {
clear();
}
if (!is_direct()) {
free(_union.indirect_contents.indirect);
_union.indirect_contents.indirect = nullptr;