-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix Bugs
- Loading branch information
Showing
1 changed file
with
32 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,84 @@ | ||
#ifndef CIRCULAR_LIST_H | ||
#define CIRCULAR_LIST_H | ||
|
||
template <class T, int LEN> | ||
template <class T, uint32_t LEN> | ||
class CircularList { | ||
private: | ||
int_32 tail_, head_; // indices | ||
T list_[LEN]; // buffer | ||
uint32_t head_, tail_; // indices | ||
T list_[LEN]; // buffer | ||
|
||
public: | ||
CircularList() { | ||
head_ = tail_ = 0; | ||
CircularList() noexcept : head_{0}, tail_{0} { | ||
static_assert((LEN > 0 && ((LEN & (LEN - 1)) == 0)) != 0, | ||
"LIST IS NOT POWER OF TWO"); | ||
} | ||
|
||
~CircularList(void) {} | ||
~CircularList(void) noexcept {} | ||
|
||
void Clear() { head_ = tail_ = 0; } | ||
void clear() noexcept { head_ = tail_ = 0; } | ||
|
||
// Enqueue one element | ||
inline void Push(const T &element) { | ||
inline void Push(const T &element) noexcept { | ||
// test for buffer full | ||
if (IsFull()) head_ = (head_ + 1) & (LEN - 1); | ||
list_[tail_] = element; | ||
tail_ = (tail_ + 1) & (LEN - 1); | ||
} | ||
|
||
void PushAll(const T element[], int_32 len) { | ||
for (int_32 i = 0; i < len; i++) Push(element[i]); | ||
inline void PushAll(const T element[], uint32_t len) noexcept { | ||
for (uint32_t i = 0; i < len; i++) Push(element[i]); | ||
} | ||
|
||
// read top element or last enqueued element | ||
bool At(int_32 idx, T &element) const { | ||
bool At(uint32_t idx, T *element) const noexcept { | ||
// check for empty list | ||
if (GetLength() <= idx) return false; | ||
if (Length() <= idx) return false; | ||
|
||
int_32 _idx = (head_ + idx) % LEN; | ||
element = list_[_idx]; | ||
uint32_t _idx = (head_ + idx) & (LEN - 1); | ||
*element = list_[_idx]; | ||
|
||
return true; | ||
} | ||
bool AtLast(uint32_t idx, T *element) const noexcept { | ||
// check for empty list | ||
if (Length() <= idx) return false; | ||
|
||
const auto _idx = (tail_ - 1 - idx + LEN) & (LEN - 1); | ||
*element = list_[_idx]; | ||
|
||
return true; | ||
} | ||
|
||
// dequeue one element | ||
inline bool Pop(T &element) { | ||
inline bool pop(T *element) noexcept { | ||
// check for empty list | ||
if (IsEmpty()) return false; | ||
element = list_[head_]; | ||
*element = list_[head_]; | ||
head_ = (head_ + 1) & (LEN - 1); | ||
return true; | ||
} | ||
|
||
bool Top(T &element) { | ||
bool Top(const T *element) const noexcept { | ||
// check for empty list | ||
if (IsEmpty()) return false; | ||
|
||
element = list_[head_]; | ||
*element = list_[head_]; | ||
return true; | ||
} | ||
|
||
int_32 GetLength() const { | ||
uint32_t Length() const noexcept { | ||
if (IsEmpty()) return 0; | ||
return LEN - ((head_ - tail_) & (LEN - 1)); | ||
} | ||
|
||
inline int_32 GetCapacity() const { return (LEN - 1); } | ||
inline uint32_t Capacity() const noexcept { return (LEN - 1); } | ||
|
||
inline int_32 RemainingCapacity() const { | ||
return (GetCapacity() - GetLength()); | ||
inline uint32_t RemainingCapacity() const noexcept { | ||
return (Capacity() - Length()); | ||
} | ||
|
||
bool IsEmpty() const { return (head_ == tail_); } | ||
|
||
inline bool IsFull() const { return (RemainingCapacity() <= 0); } | ||
bool IsEmpty() const noexcept { return (head_ == tail_); } | ||
inline bool IsFull() const noexcept { return (RemainingCapacity() <= 0); } | ||
}; | ||
|
||
#endif // !1 |