Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:41

0001 // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
0002 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
0003 
0004 // circular q view of std::vector.
0005 #pragma once
0006 
0007 #include <vector>
0008 #include <cassert>
0009 
0010 namespace spdlog {
0011 namespace details {
0012 template<typename T>
0013 class circular_q
0014 {
0015     size_t max_items_ = 0;
0016     typename std::vector<T>::size_type head_ = 0;
0017     typename std::vector<T>::size_type tail_ = 0;
0018     size_t overrun_counter_ = 0;
0019     std::vector<T> v_;
0020 
0021 public:
0022     using value_type = T;
0023 
0024     // empty ctor - create a disabled queue with no elements allocated at all
0025     circular_q() = default;
0026 
0027     explicit circular_q(size_t max_items)
0028         : max_items_(max_items + 1) // one item is reserved as marker for full q
0029         , v_(max_items_)
0030     {}
0031 
0032     circular_q(const circular_q &) = default;
0033     circular_q &operator=(const circular_q &) = default;
0034 
0035     // move cannot be default,
0036     // since we need to reset head_, tail_, etc to zero in the moved object
0037     circular_q(circular_q &&other) SPDLOG_NOEXCEPT
0038     {
0039         copy_moveable(std::move(other));
0040     }
0041 
0042     circular_q &operator=(circular_q &&other) SPDLOG_NOEXCEPT
0043     {
0044         copy_moveable(std::move(other));
0045         return *this;
0046     }
0047 
0048     // push back, overrun (oldest) item if no room left
0049     void push_back(T &&item)
0050     {
0051         if (max_items_ > 0)
0052         {
0053             v_[tail_] = std::move(item);
0054             tail_ = (tail_ + 1) % max_items_;
0055 
0056             if (tail_ == head_) // overrun last item if full
0057             {
0058                 head_ = (head_ + 1) % max_items_;
0059                 ++overrun_counter_;
0060             }
0061         }
0062     }
0063 
0064     // Return reference to the front item.
0065     // If there are no elements in the container, the behavior is undefined.
0066     const T &front() const
0067     {
0068         return v_[head_];
0069     }
0070 
0071     T &front()
0072     {
0073         return v_[head_];
0074     }
0075 
0076     // Return number of elements actually stored
0077     size_t size() const
0078     {
0079         if (tail_ >= head_)
0080         {
0081             return tail_ - head_;
0082         }
0083         else
0084         {
0085             return max_items_ - (head_ - tail_);
0086         }
0087     }
0088 
0089     // Return const reference to item by index.
0090     // If index is out of range 0…size()-1, the behavior is undefined.
0091     const T &at(size_t i) const
0092     {
0093         assert(i < size());
0094         return v_[(head_ + i) % max_items_];
0095     }
0096 
0097     // Pop item from front.
0098     // If there are no elements in the container, the behavior is undefined.
0099     void pop_front()
0100     {
0101         head_ = (head_ + 1) % max_items_;
0102     }
0103 
0104     bool empty() const
0105     {
0106         return tail_ == head_;
0107     }
0108 
0109     bool full() const
0110     {
0111         // head is ahead of the tail by 1
0112         if (max_items_ > 0)
0113         {
0114             return ((tail_ + 1) % max_items_) == head_;
0115         }
0116         return false;
0117     }
0118 
0119     size_t overrun_counter() const
0120     {
0121         return overrun_counter_;
0122     }
0123 
0124     void reset_overrun_counter()
0125     {
0126         overrun_counter_ = 0;
0127     }
0128 
0129 private:
0130     // copy from other&& and reset it to disabled state
0131     void copy_moveable(circular_q &&other) SPDLOG_NOEXCEPT
0132     {
0133         max_items_ = other.max_items_;
0134         head_ = other.head_;
0135         tail_ = other.tail_;
0136         overrun_counter_ = other.overrun_counter_;
0137         v_ = std::move(other.v_);
0138 
0139         // put &&other in disabled, but valid state
0140         other.max_items_ = 0;
0141         other.head_ = other.tail_ = 0;
0142         other.overrun_counter_ = 0;
0143     }
0144 };
0145 } // namespace details
0146 } // namespace spdlog