[rtc_base] Replace manual element initialization and movement with C++17 standard functions

This CL focuses on addressing the remaining TODO items in the
`//rtc_base/bounded_inline_vector_impl.h` file, mainly involving the two
functions `void DefaultInitializeElements` and `void MoveElements`.

In the `void DefaultInitializeElements` function, the placement new usage is
adopted. When using placement new, manual construction operations on objects are
usually required, and a fair amount of logic needs to be written to ensure
correct object construction. In contrast, the
`std::uninitialized_default_construct_n()` function only requires passing in the
starting address of the memory and the number of objects to be constructed, and
it can automatically construct objects in batches.

In the `void MoveElements` function, the original implementation also uses the
placement new usage. When using placement new to move objects, manual handling
of the moving operation for each object is required, and usually, `std::move`
needs to be combined to achieve the object's move semantics. However, the
`std::uninitialized_move_n()` function can automatically complete the object
moving process just by passing in specific parameters.

To improve the code's simplicity, it is considered to use
`std::uninitialized_default_construct_n()` and `std::uninitialized_move_n()` to
replace the original two placement new usages.

Fixed: webrtc:392037564
Change-Id: If8edcd9ac8a4d85be0ce0a23f6433d7f91b39ad3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375182
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Auto-Submit: Ho Cheung <hocheung@chromium.org>
Cr-Commit-Position: refs/heads/main@{#43831}
This commit is contained in:
Ho Cheung 2025-01-25 20:59:55 +08:00 committed by WebRTC LUCI CQ
parent de1735058b
commit 18b94b517d

View File

@ -46,13 +46,9 @@ void InitializeElements(T* data, U&& element, Us&&... elements) {
} }
// Default initializes uninitialized array elements. // Default initializes uninitialized array elements.
// TODO(kwiberg): Replace with std::uninitialized_default_construct_n() (C++17).
template <typename T> template <typename T>
void DefaultInitializeElements(T* data, int size) { void DefaultInitializeElements(T* data, int size) {
for (int i = 0; i < size; ++i) { std::uninitialized_default_construct_n(data, size);
// Placement new, because we construct a new object in uninitialized memory.
::new (&data[i]) T;
}
} }
// Copies from source to uninitialized destination. Caller is responsible for // Copies from source to uninitialized destination. Caller is responsible for
@ -74,12 +70,7 @@ void MoveElements(T* src_data, int src_size, T* dst_data, int* dst_size) {
if /*constexpr*/ (std::is_trivially_move_constructible<T>::value) { if /*constexpr*/ (std::is_trivially_move_constructible<T>::value) {
std::memcpy(dst_data, src_data, src_size * sizeof(T)); std::memcpy(dst_data, src_data, src_size * sizeof(T));
} else { } else {
// TODO(kwiberg): Use std::uninitialized_move_n() instead (C++17). std::uninitialized_move_n(src_data, src_size, dst_data);
for (int i = 0; i < src_size; ++i) {
// Placement new, because we create a new object in uninitialized
// memory.
::new (&dst_data[i]) T(std::move(src_data[i]));
}
} }
*dst_size = src_size; *dst_size = src_size;
} }