Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Viaro_SpandiConcime_V2b by
CB1.h
00001 /* 00002 CB1.h - Circular buffer library for Arduino. 00003 Copyright (c) 2017 Roberto Lo Giacco. All right reserved. 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 #ifndef __CIRCULAR_BUFFER__ 00020 #define __CIRCULAR_BUFFER__ 00021 #include <inttypes.h> 00022 00023 #ifndef CIRCULAR_BUFFER_XS 00024 #define __CB_ST__ uint16_t 00025 #else 00026 #define __CB_ST__ uint8_t 00027 #endif 00028 00029 #ifdef CIRCULAR_BUFFER_DEBUG 00030 #include <Print.h> 00031 #endif 00032 00033 #include <string.h> 00034 00035 template<typename T, __CB_ST__ S> class CB1 { 00036 public: 00037 00038 CB1(); 00039 00040 ~CB1(); 00041 00042 /** 00043 * Adds an element to the beginning of buffer: the operation returns `false` if the addition caused overwriting an existing element. 00044 */ 00045 bool unshift(T value); 00046 00047 /** 00048 * Adds an element to the end of buffer: the operation returns `false` if the addition caused overwriting an existing element. 00049 */ 00050 bool push(T value); 00051 00052 /** 00053 * Removes an element from the beginning of the buffer. 00054 */ 00055 T shift(); 00056 00057 /** 00058 * Removes an element from the end of the buffer. 00059 */ 00060 T pop(); 00061 00062 /** 00063 * Returns the element at the beginning of the buffer. 00064 */ 00065 T inline first(); 00066 00067 /** 00068 * Returns the element at the end of the buffer. 00069 */ 00070 T inline last(); 00071 00072 /** 00073 * Array-like access to buffer 00074 */ 00075 T operator [] (__CB_ST__ index); 00076 00077 /** 00078 * Returns how many elements are actually stored in the buffer. 00079 */ 00080 __CB_ST__ inline size(); 00081 00082 /** 00083 * Returns how many elements can be safely pushed into the buffer. 00084 */ 00085 __CB_ST__ inline available(); 00086 00087 /** 00088 * Returns how many elements can be potentially stored into the buffer. 00089 */ 00090 __CB_ST__ inline capacity(); 00091 00092 /** 00093 * Returns `true` if no elements can be removed from the buffer. 00094 */ 00095 bool inline isEmpty(); 00096 00097 /** 00098 * Returns `true` if no elements can be added to the buffer without overwriting existing elements. 00099 */ 00100 bool inline isFull(); 00101 00102 /** 00103 * Resets the buffer to a clean status, dropping any reference to current elements 00104 * and making all buffer positions available again. 00105 */ 00106 void inline clear(); 00107 00108 #ifdef CIRCULAR_BUFFER_DEBUG 00109 void inline debug(Print* out); 00110 void inline debugFn(Print* out, void (*printFunction)(Print*, T)); 00111 #endif 00112 00113 private: 00114 T buffer[S]; 00115 T *head; 00116 T *tail; 00117 uint16_t count; 00118 }; 00119 00120 00121 template<typename T, __CB_ST__ S> 00122 CB1<T,S>::CB1() : 00123 head(buffer), tail(buffer), count(0) { 00124 } 00125 00126 template<typename T, __CB_ST__ S> 00127 CB1<T,S>::~CB1() { 00128 } 00129 00130 template<typename T, __CB_ST__ S> 00131 bool CB1<T,S>::unshift(T value) { 00132 if (head == buffer) { 00133 head = buffer + S; 00134 } 00135 *--head = value; 00136 if (count == S) { 00137 if (tail-- == buffer) { 00138 tail = buffer + S - 1; 00139 } 00140 return false; 00141 } else { 00142 if (count++ == 0) { 00143 tail = head; 00144 } 00145 return true; 00146 } 00147 } 00148 00149 template<typename T, __CB_ST__ S> 00150 bool CB1<T,S>::push(T value) { 00151 if (++tail == buffer + S) { 00152 tail = buffer; 00153 } 00154 *tail = value; 00155 if (count == S) { 00156 if (++head == buffer + S) { 00157 head = buffer; 00158 } 00159 return false; 00160 } else { 00161 if (count++ == 0) { 00162 head = tail; 00163 } 00164 return true; 00165 } 00166 } 00167 00168 template<typename T, __CB_ST__ S> 00169 T CB1<T,S>::shift() { 00170 void(* crash) (void) = 0; 00171 if (count <= 0) crash(); 00172 T result = *head++; 00173 if (head >= buffer + S) { 00174 head = buffer; 00175 } 00176 count--; 00177 return result; 00178 } 00179 00180 template<typename T, __CB_ST__ S> 00181 T CB1<T,S>::pop() { 00182 void(* crash) (void) = 0; 00183 if (count <= 0) crash(); 00184 T result = *tail--; 00185 if (tail < buffer) { 00186 tail = buffer + S - 1; 00187 } 00188 count--; 00189 return result; 00190 } 00191 00192 template<typename T, __CB_ST__ S> 00193 T inline CB1<T,S>::first() { 00194 return *head; 00195 } 00196 00197 template<typename T, __CB_ST__ S> 00198 T inline CB1<T,S>::last() { 00199 return *tail; 00200 } 00201 00202 template<typename T, __CB_ST__ S> 00203 T CB1<T,S>::operator [](__CB_ST__ index) { 00204 return *(buffer + ((head - buffer + index) % S)); 00205 } 00206 00207 template<typename T, __CB_ST__ S> 00208 __CB_ST__ inline CB1<T,S>::size() { 00209 return count; 00210 } 00211 00212 template<typename T, __CB_ST__ S> 00213 __CB_ST__ inline CB1<T,S>::available() { 00214 return S - count; 00215 } 00216 00217 template<typename T, __CB_ST__ S> 00218 __CB_ST__ inline CB1<T,S>::capacity() { 00219 return S; 00220 } 00221 00222 template<typename T, __CB_ST__ S> 00223 bool inline CB1<T,S>::isEmpty() { 00224 return count == 0; 00225 } 00226 00227 template<typename T, __CB_ST__ S> 00228 bool inline CB1<T,S>::isFull() { 00229 return count == S; 00230 } 00231 00232 template<typename T, __CB_ST__ S> 00233 void inline CB1<T,S>::clear() { 00234 memset(buffer, 0, sizeof(buffer)); 00235 head = tail = buffer; 00236 count = 0; 00237 } 00238 00239 #ifdef CIRCULAR_BUFFER_DEBUG 00240 template<typename T, __CB_ST__ S> 00241 void inline CB1<T,S>::debug(Print* out) { 00242 for (__CB_ST__ i = 0; i < S; i++) { 00243 int hex = (int)buffer + i; 00244 out->print(hex, HEX); 00245 out->print(" "); 00246 out->print(*(buffer + i)); 00247 if (head == buffer + i) { 00248 out->print(" head"); 00249 } 00250 if (tail == buffer + i) { 00251 out->print(" tail"); 00252 } 00253 out->println(); 00254 } 00255 } 00256 00257 template<typename T, __CB_ST__ S> 00258 void inline CB1<T,S>::debugFn(Print* out, void (*printFunction)(Print*, T)) { 00259 for (__CB_ST__ i = 0; i < S; i++) { 00260 int hex = (int)buffer + i; 00261 out->print(hex, HEX); 00262 out->print(" "); 00263 printFunction(out, *(buffer + i)); 00264 if (head == buffer + i) { 00265 out->print(" head"); 00266 } 00267 if (tail == buffer + i) { 00268 out->print(" tail"); 00269 } 00270 out->println(); 00271 } 00272 } 00273 #endif 00274 00275 #endif
Generated on Tue Jul 12 2022 21:04:29 by
