Avionics
Core avionics package for CURE flight computers
Loading...
Searching...
No Matches
CircularArray.h
Go to the documentation of this file.
1#ifndef CIRCULARARRAY_H
2#define CIRCULARARRAY_H
3
4#include <algorithm>
5#include <array>
6#include <assert.h>
7#include <cstdint>
8
9constexpr std::size_t MAX_CIRCULAR_ARRAY_CAPACITY = 255;
10
11template<typename T, std::size_t N>
12int partition(std::array<T, N>& array, int left, int right, int pivotIndex) {
13 T pivotValue = array[pivotIndex];
14 std::swap(array[pivotIndex], array[right]); // Move pivot to end
15 int storeIndex = left;
16 for (int i = left; i < right; i++) {
17 if (array[i] < pivotValue) {
18 std::swap(array[i], array[storeIndex]);
19 storeIndex++;
20 }
21 }
22 std::swap(array[storeIndex], array[right]); // Move pivot to its final place
23 return storeIndex;
24}
25
26// Quick select implementation
27// Returns the kth smallest element in the array
28// left and right are the bounds of the array
29// O(n) average time complexity
30// O(n^2) worst case time complexity
31// If we were to just use bubble sort, that would be O(n^2) time complexity
32template<typename T, std::size_t N>
33T quickSelect(std::array<T, N> &array, int left, int right, int k){
34 while (left < right){
35 int pivotIndex = (left + right) / 2;
36 int pivotNewIndex = partition(array, left, right, pivotIndex);
37 if (pivotNewIndex == k){
38 return array[k];
39 } else if (k < pivotNewIndex){
40 right = pivotNewIndex - 1;
41 } else {
42 left = pivotNewIndex + 1;
43 }
44 }
45 return array[k];
46}
47
48
49template<typename T, std::size_t Capacity>
56 protected:
57 std::array<T, Capacity> array;
58 std::array<T, Capacity> scratchArray; // For median calculation
59 uint8_t maxSize; // 0 to 255
60 uint8_t head; // 0 to 255
61 uint8_t currentSize; // 0 to 255
62
63 public:
64 CircularArray(uint8_t maxSize = Capacity) : maxSize(maxSize) {
65 static_assert(Capacity > 0, "CircularArray capacity must be greater than 0");
66 static_assert(Capacity <= MAX_CIRCULAR_ARRAY_CAPACITY, "CircularArray capacity must be less than or equal to 255 b/c of head being uint8_t");
67 assert(maxSize > 0 && maxSize <= Capacity);
68 this->head = 0;
69 this->currentSize = 0; // How full is the circular buffer?
70 }
71
72 void push(T data){
73 // After the first push, start moving the head
74 if (currentSize)
75 head = (head + 1) % maxSize;
76 array[head] = data;
77
78 // Cap current size at maxSize
79 if (currentSize < maxSize){
81 }
82 }
83
84 T pop(){
85 if (currentSize == 0){
86 return T();
87 }
88 T data = array[head];
89 head = (head + maxSize - 1) % maxSize;
91 return data;
92 }
93
94 // How many indexes back from the head
95 T getFromHead(uint8_t index){
96 return array[(head + maxSize - index) % maxSize];
97 }
98
99 // Has the circular array been filled
100 bool isFull(){
101 return currentSize >= maxSize;
102 }
103
104 bool isEmpty(){
105 return currentSize == 0;
106 }
107
108 uint8_t getHead(){
109 return head;
110 }
111
112 uint8_t getMaxSize(){
113 return maxSize;
114 }
115
117 if (currentSize == 0) {
118 // Handle the case when the array is empty
119 return T();
120 }
121
122 size_t count = std::min(static_cast<size_t>(currentSize), static_cast<size_t>(maxSize));
123
124 // Collect the valid elements from the circular array
125 for (size_t i = 0; i < count; ++i) {
126 scratchArray[i] = array[(head + maxSize - i) % maxSize];
127 }
128
129 // Find the median
130 int n = static_cast<int>(count);
131 return quickSelect(scratchArray, 0, n - 1, n / 2);
132 }
133
134 void clear(){
135 head = 0;
136 currentSize = 0;
137 for (uint8_t i = 0; i < maxSize; i++){
138 array[i] = T();
139 }
140 }
141
142};
143
144
145
146#endif
constexpr std::size_t MAX_CIRCULAR_ARRAY_CAPACITY
T quickSelect(std::array< T, N > &array, int left, int right, int k)
int partition(std::array< T, N > &array, int left, int right, int pivotIndex)
uint8_t getHead()
uint8_t getMaxSize()
T getFromHead(uint8_t index)
uint8_t currentSize
std::array< T, Capacity > scratchArray
void push(T data)
std::array< T, Capacity > array
CircularArray(uint8_t maxSize=Capacity)