blob: cf78572fc8c2fdc161aa80d233113405d722f29e [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_ETHERNET_DRIVERS_GVNIC_CIRCULAR_QUEUE_H_
#define SRC_CONNECTIVITY_ETHERNET_DRIVERS_GVNIC_CIRCULAR_QUEUE_H_
#include <stdint.h>
#include <zircon/assert.h>
#include <memory>
// Only designed to work with POD types.
template <class T>
class CircularQueue {
private:
std::unique_ptr<T[]> contents_;
uint32_t read_index_;
uint32_t write_index_;
uint32_t count_{0};
uint32_t capacity_{0};
public:
CircularQueue() = default;
virtual ~CircularQueue() = default;
void Init(uint32_t capacity) {
ZX_ASSERT_MSG(count_ == 0, "Init when not empty. There are still %u elements in the queue.",
count_);
contents_.reset(capacity > 0 ? new T[capacity] : nullptr);
capacity_ = capacity;
read_index_ = 0;
write_index_ = 0;
}
void Enqueue(T elem) {
ZX_ASSERT_MSG(count_ < capacity_, "Enqueue when full.");
contents_[write_index_] = elem;
write_index_ = (write_index_ + 1) % capacity_;
count_++;
}
const T& Front() {
ZX_ASSERT_MSG(count_ > 0, "Front when empty.");
return contents_[read_index_];
}
void Dequeue() {
ZX_ASSERT_MSG(count_ > 0, "Dequeue when empty.");
read_index_ = (read_index_ + 1) % capacity_;
count_--;
}
uint32_t Count() { return count_; }
};
#endif // SRC_CONNECTIVITY_ETHERNET_DRIVERS_GVNIC_CIRCULAR_QUEUE_H_