Skip to content

SmallVector: Exception safety #75

Description

@jsrivaya

Parent

Part of #5. Depends on #71, #72, #74.

Summary

Audit and enforce exception safety guarantees across all SmallVector operations, with specific handling for the heap transition — the most dangerous point for correctness.

Guarantees to provide

Operation Guarantee
push_back / emplace_back Strong — if T's ctor throws, SmallVector unchanged
insert / emplace Strong if no reallocation; Basic if reallocation needed
erase No-throw if T's move/dtor is no-throw
reserve Strong — old storage untouched until move succeeds
Heap transition Strong — allocate new block, move all elements, then destroy old
Copy constructor Strong
Move constructor No-throw for heap mode; Basic for inline mode if T's move throws

The heap transition in detail

This is the riskiest operation:

void grow() {
    size_t new_cap = capacity_ * 2;
    T* new_heap = static_cast<T*>(::operator new(new_cap * sizeof(T)));

    // Move elements — if any move throws, we must clean up new_heap
    size_t moved = 0;
    try {
        for (; moved < size_; ++moved)
            new(new_heap + moved) T(std::move(data()[moved]));
    } catch (...) {
        // Destroy successfully moved elements
        for (size_t i = 0; i < moved; ++i)
            new_heap[i].~T();
        ::operator delete(new_heap);
        throw;  // re-throw, original storage untouched
    }

    // Destroy originals and switch to heap
    for (size_t i = 0; i < size_; ++i)
        data()[i].~T();
    if (!is_small()) ::operator delete(heap_ptr);
    heap_ptr = new_heap;
    capacity_ = new_cap;
}

If T's move constructor is noexcept, the try/catch can be skipped entirely (compiler will optimise this with if constexpr (std::is_nothrow_move_constructible_v<T>)).

Testing requirements

  • Push into a type whose copy constructor throws on the Nth call — SmallVector must be unchanged
  • Heap transition with a throwing move type — old data preserved
  • Verify noexcept propagation: push_back is noexcept when T's move is noexcept

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions