Skip to content

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

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

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

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions