// // Copyright(c) 2018 Gabi Melman. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // // cirucal q view of std::vector. #pragma once #include namespace spdlog { namespace details { template class circular_q { public: using item_type = T; explicit circular_q(size_t max_items) : max_items_(max_items + 1) // one item is reserved as marker for full q , v_(max_items_) { } // push back, overrun (oldest) item if no room left void push_back(T &&item) { v_[tail_] = std::move(item); tail_ = (tail_ + 1) % max_items_; if (tail_ == head_) // overrun last item if full { head_ = (head_ + 1) % max_items_; ++overrun_counter_; } } // Pop item from front. // If there are no elements in the container, the behavior is undefined. void pop_front(T &popped_item) { popped_item = std::move(v_[head_]); head_ = (head_ + 1) % max_items_; } bool empty() { return tail_ == head_; } bool full() { // head is ahead of the tail by 1 return ((tail_ + 1) % max_items_) == head_; } size_t overrun_counter() const { return overrun_counter_; } private: size_t max_items_; typename std::vector::size_type head_ = 0; typename std::vector::size_type tail_ = 0; std::vector v_; size_t overrun_counter_ = 0; }; } // namespace details } // namespace spdlog