Skip to content

SpscQueue: Add move semantics support for push(T&&) #56

@jsrivaya

Description

@jsrivaya

Summary

Add push(T&&) overload to SpscQueue to enable zero-copy insertion of moveable types.

Motivation

The current push(const T&) always copies the value into the buffer. For types with expensive copy constructors (large structs, types managing heap memory), this is unnecessary overhead when the caller no longer needs the original value.

Proposed API

// Existing (copy)
bool push(const T& value);

// New (move)
bool push(T&& value);

// Optionally, emplace (construct in-place)
template <typename... Args>
bool emplace(Args&&... args);

Implementation Notes

bool push(T&& value) {
    auto write = write_idx_.load(std::memory_order_relaxed);
    if (write - read_idx_cache_ == N) {
        read_idx_cache_ = read_idx_.load(std::memory_order_acquire);
        if (write - read_idx_cache_ == N)
            return false;
    }
    data_[write % N] = std::move(value);
    write_idx_.store(write + 1, std::memory_order_release);
    return true;
}

For emplace, construct directly in the buffer slot:

template <typename... Args>
bool emplace(Args&&... args) {
    auto write = write_idx_.load(std::memory_order_relaxed);
    if (write - read_idx_cache_ == N) {
        read_idx_cache_ = read_idx_.load(std::memory_order_acquire);
        if (write - read_idx_cache_ == N)
            return false;
    }
    new (&data_[write % N]) T(std::forward<Args>(args)...);
    write_idx_.store(write + 1, std::memory_order_release);
    return true;
}

Impact

  • Zero overhead for trivially copyable types (compiler will optimize both paths identically)
  • Significant win for types like std::string, std::vector, or large POD structs
  • Consistent with STL container conventions (push_back vs emplace_back)

References

  • rigtorp/SPSCQueue: provides try_push(T&&) and try_emplace(Args&&...)
  • std::queue::push(T&&) — STL precedent

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions