Developer World
Spresense SDK Library v3.2.0-ebc0364
buffer.h
1/****************************************************************************
2 * modules/include/memutils/s_stl/buffer.h
3 *
4 * Copyright 2018 Sony Semiconductor Solutions Corporation
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * 3. Neither the name of Sony Semiconductor Solutions Corporation nor
17 * the names of its contributors may be used to endorse or promote
18 * products derived from this software without specific prior written
19 * permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ****************************************************************************/
35
36#ifndef BUFFER_H_INCLUDED
37#define BUFFER_H_INCLUDED
38
39#include "memutils/s_stl/s_stl_config.h"
40#include <new>
41
42__STL_BEGIN_NAMESPACE
43
44/*-------------------------------------------------------------------*/
45template<class T,int N> class Buffer{
46
47private:
48
49 struct SEG {
50 unsigned char data[sizeof(T)];
51 uint index;
52
53 SEG() : index(EMPTY){}
54 };
55
56 SEG buffer[N];
57 SEG* search_top;
58
59public:
60 Buffer(): search_top(buffer) {}
61
62 T* alloc(void){
63 for(SEG* area_p = search_top;area_p<&buffer[N];area_p++){
64 if(area_p->index == EMPTY){
65 area_p->index = FULL;
66 search_top = area_p+1;
67// new (area_p->data) T;
68 return reinterpret_cast<T*>(&(area_p->data));
69 }
70 }
71 return NULL;
72 }
73
74 bool free(T* data_p){
75 SEG* area_p = reinterpret_cast<SEG*>(data_p);
76 if((area_p < &buffer[0]) || (area_p >= &buffer[N])) return FALSE;
77 if(area_p->index == EMPTY) return FALSE;
78 data_p->~T();
79 area_p->index = EMPTY;
80 if(search_top > area_p){ search_top = area_p;}
81 return TRUE;
82 }
83
84 void clear(void){
85 for(int i=0;i<N;i++){
86 T* area_p = reinterpret_cast<T*>(buffer[i].data);
87 if(buffer[i].index == FULL) area_p->~T();
88 buffer[i].index = EMPTY;
89 }
90 search_top = buffer;
91 }
92};
93
94/*-------------------------------------------------------------------*/
95template<class T,int N> class RingBuffer{
96
97private:
98
99 unsigned char buffer[sizeof(T)*N];
100 T* head_p;
101 T* tail_p;
102
103 int cnt;
104
105public:
106 RingBuffer(): head_p(static_cast<T*>(static_cast<void*>(buffer))), tail_p(head_p), cnt(0){}
107
108 bool alloc_front(const T& new_data){
109 if(cnt>=N){ return FALSE; } else { cnt++; }
110 if(cnt != 1){
111 if(head_p+1 > static_cast<T*>(static_cast<void*>(&buffer[sizeof(T)*(N-1)])) ){
112 head_p = static_cast<T*>(static_cast<void*>(&buffer[0]));
113 }else{
114 head_p++;
115 }
116 }
117 new(head_p) T(new_data);
118 return TRUE;
119 }
120
121 bool alloc_back(const T& new_data){
122 if(cnt>=N){ return FALSE; } else { cnt++; }
123 if(cnt != 1){
124 if(tail_p-1 < static_cast<T*>(static_cast<void*>(&buffer[0]))){
125 tail_p = static_cast<T*>(static_cast<void*>(&buffer[sizeof(T)*(N-1)]));
126 }else{
127 tail_p--;
128 }
129 }
130 new(tail_p) T(new_data);
131 return TRUE;
132 }
133
134 bool free_front(void){
135 if(cnt<=0){ return FALSE; } else { cnt--; }
136 head_p->~T();
137 if(cnt != 0){
138 if(head_p-1 < static_cast<T*>(static_cast<void*>(&buffer[0]))){
139 head_p = static_cast<T*>(static_cast<void*>(&buffer[sizeof(T)*(N-1)]));
140 }else{
141 head_p--;
142 }
143 }
144 return TRUE;
145 }
146
147 bool free_back(void){
148 if(cnt<=0){ return FALSE; } else {cnt--;}
149 tail_p->~T();
150 if(cnt != 0){
151 if(tail_p+1 > static_cast<T*>(static_cast<void*>(&buffer[sizeof(T)*(N-1)]))){
152 tail_p = static_cast<T*>(static_cast<void*>(&buffer[0]));
153 }else{
154 tail_p++;
155 }
156 }
157 return TRUE;
158 }
159
160 const T& get_front(void) const {
161 if(cnt <= 0) _fatal;
162 return *head_p;
163 }
164
165 const T& get_back(void) const {
166 if(cnt <= 0) _fatal;
167 return *tail_p;
168 }
169
170
171 const T& at_front(const int n) const {
172 if(cnt <= n) _fatal;
173 if(head_p-n+N > reinterpret_cast<const T*>(&buffer[sizeof(T)*(N-1)])){
174 return *(head_p-n);
175 }else{
176 return *(head_p-n+N);
177 }
178 }
179
180 const T& at_back(const int n) const {
181 if(cnt <= n) _fatal;
182 if(tail_p+n > reinterpret_cast<const T*>(&buffer[sizeof(T)*(N-1)])){
183 return *(tail_p+n-N);
184 }else{
185 return *(tail_p+n);
186 }
187 }
188
189
190 bool empty(void) const { return (cnt==0); }
191 bool full(void) const { return (cnt==N); }
192
193 void clear(void){
194 while(cnt>0){
195 free_back();
196 }
197 }
198};
199
200__STL_END_NAMESPACE
201
202#endif /* BUFFER_H_INCLUDED */
203
Definition: buffer.h:45
Definition: buffer.h:95