Better_Software_Header_MobileBetter_Software_Header_Web

Find what you need - explore our website and developer resources

Qt and Trivial Relocation (Part 1)

What is relocation?

Elements are being moved. The red, underlined elements in the source represent moved-from objects. C will be moved next.

template <typename T>;
vector<T>::reallocate_impl(size_t new_capacity)
{
    assert(m_size <= new_capacity);
    T *new_storage = allocate(new_capacity);

    std::uninitialized_move(m_begin, m_begin + m_size, new_storage);
    std::destroy(m_begin, m_begin + m_size);

    deallocate(m_begin);
    m_begin = new_storage;
    m_capacity = new_capacity;
}
template <typename T>;
vector<T>::reallocate_impl(size_t new_capacity)
{
    assert(m_size <= new_capacity);
    T *new_storage = allocate(new_capacity);

    if constexpr (/* ... magic ... */) {
        std::memcpy(new_storage, m_begin, m_size * sizeof(T));
    } else if constexpr (std::is_nothrow_move_constructible_v<T>) {
        std::uninitialized_move(m_begin, m_begin + m_size, new_storage);
        std::destroy(m_begin, m_begin + m_size);
    } else {
        // ...
    }

    deallocate(m_begin);
    m_begin = new_storage;
    m_capacity = new_capacity;
}
// Given:
T *ptrA = ~~~;   // points to a valid object
T *ptrB = ~~~;   // points to uninitialized storage

// Then this:
new (ptrB) T(std::move(*ptrA));   // move-construct A into new storage (placement new)
ptrA->~T();                       // destroy A

// can be implemented like this:
memcpy(ptrB, ptrA, sizeof(T));

QString is trivially relocatable: we can memcpy the QString object (just a pointer, really) and deallocate the original without running its destructor. This achieves the same effects as move-construction + destruction.

class string
{
    // may point to the heap, or into `m_buffer` if the string
    // is short enough:
    char *m_begin;   

    size_t m_size;
    size_t m_capacity;

    char m_buffer[SSO_BUFFER_SIZE];
};

string s = "Hello";
class MyClass {
    ~~~
};

Q_DECLARE_TYPEINFO(MyClass, Q_RELOCATABLE_TYPE);

About KDAB


2 Comments

13 - Jun - 2024

Robert

14 - Jun - 2024

Giuseppe D'Angelo

GiuseppeD'Angelo

Giuseppe D’Angelo

Senior Software Engineer

Learn Modern C++

Learn more