-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcommon_types.h
228 lines (194 loc) · 5.77 KB
/
common_types.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#ifndef GPSLIB_COMMON_TYPES_H
#define GPSLIB_COMMON_TYPES_H
#ifndef CANLIB_CIRCULAR_BUFFER
#define CANLIB_CIRCULAR_BUFFER
#include <inttypes.h>
#include <stdlib.h>
namespace Helper {
template <bool FITS8, bool FITS16>
struct Index {
using Type = uint32_t;
};
template <>
struct Index<false, true> {
using Type = uint16_t;
};
template <>
struct Index<true, true> {
using Type = uint8_t;
};
} // namespace Helper
template <typename T, size_t S,
typename IT =
typename Helper::Index<(S <= UINT8_MAX), (S <= UINT16_MAX)>::Type>
class canlib_circular_buffer {
public:
static constexpr IT capacity = static_cast<IT>(S);
using index_t = IT;
constexpr canlib_circular_buffer();
canlib_circular_buffer(const canlib_circular_buffer &) = delete;
canlib_circular_buffer(canlib_circular_buffer &&) = delete;
canlib_circular_buffer &operator=(const canlib_circular_buffer &) = delete;
canlib_circular_buffer &operator=(canlib_circular_buffer &&) = delete;
bool unshift(T value);
bool push(T value);
T shift();
T pop();
const T &start() const;
T inline first() const;
T inline last() const;
const T &operator[](IT index) const;
IT inline size() const;
IT inline available() const;
bool inline empty() const;
bool inline full() const;
void inline clear();
size_t inline offset() const;
private:
T buffer[S];
T *head;
T *tail;
size_t _offset;
#ifndef CIRCULAR_BUFFER_INT_SAFE
IT count;
#else
volatile IT count;
#endif
};
template <typename T, size_t S, typename IT>
constexpr canlib_circular_buffer<T, S, IT>::canlib_circular_buffer()
: head(buffer), tail(buffer), _offset(0), count(0) {}
template <typename T, size_t S, typename IT>
bool canlib_circular_buffer<T, S, IT>::unshift(T value) {
if (head == buffer) {
head = buffer + capacity;
}
*--head = value;
if (count == capacity) {
if (tail-- == buffer) {
tail = buffer + capacity - 1;
}
return false;
} else {
if (count++ == 0) {
tail = head;
}
return true;
}
}
template <typename T, size_t S, typename IT>
bool canlib_circular_buffer<T, S, IT>::push(T value) {
if (++tail == buffer + capacity) {
tail = buffer;
}
*tail = value;
if (count == capacity) {
if (++head == buffer + capacity) {
head = buffer;
}
_offset = (_offset + 1) % capacity;
return false;
} else {
if (count++ == 0) {
head = tail;
}
return true;
}
}
template <typename T, size_t S, typename IT>
T canlib_circular_buffer<T, S, IT>::shift() {
if (count == 0) return *head;
T result = *head++;
if (head >= buffer + capacity) {
head = buffer;
}
count--;
return result;
}
template <typename T, size_t S, typename IT>
T canlib_circular_buffer<T, S, IT>::pop() {
if (count == 0) return *tail;
T result = *tail--;
if (tail < buffer) {
tail = buffer + capacity - 1;
}
count--;
return result;
}
template <typename T, size_t S, typename IT>
T inline canlib_circular_buffer<T, S, IT>::first() const {
return *head;
}
template <typename T, size_t S, typename IT>
T inline canlib_circular_buffer<T, S, IT>::last() const {
return *tail;
}
template <typename T, size_t S, typename IT>
const T &canlib_circular_buffer<T, S, IT>::start() const {
return buffer[1];
}
template <typename T, size_t S, typename IT>
const T &canlib_circular_buffer<T, S, IT>::operator[](IT index) const {
if (index >= count) return *tail;
return *(buffer + ((head - buffer + index) % capacity));
}
template <typename T, size_t S, typename IT>
IT inline canlib_circular_buffer<T, S, IT>::size() const {
return count;
}
template <typename T, size_t S, typename IT>
IT inline canlib_circular_buffer<T, S, IT>::available() const {
return capacity - count;
}
template <typename T, size_t S, typename IT>
bool inline canlib_circular_buffer<T, S, IT>::empty() const {
return count == 0;
}
template <typename T, size_t S, typename IT>
bool inline canlib_circular_buffer<T, S, IT>::full() const {
return count == capacity;
}
template <typename T, size_t S, typename IT>
void inline canlib_circular_buffer<T, S, IT>::clear() {
head = tail = buffer;
count = 0;
}
template <typename T, size_t S, typename IT>
size_t inline canlib_circular_buffer<T, S, IT>::offset() const {
return _offset;
}
#endif // CANLIB_CIRCULAR_BUFFER
#ifndef CANLIB_CIRCULAR_BUFFER_SIZE
#define CANLIB_CIRCULAR_BUFFER_SIZE 2000
#endif // CANLIB_CIRCULAR_BUFFER_SIZE
#ifndef CANLIB_PROTO_INTERFACE_TYPES
#define CANLIB_PROTO_INTERFACE_TYPES
#include <string>
#include <unordered_map>
/**
* Use network_<> to get all the values from the protobuffer.
* Every network can be consensed into one network_<> as all the
* messages names are unique.
**/
typedef std::string field_name;
typedef std::string messages_name;
typedef canlib_circular_buffer<double, CANLIB_CIRCULAR_BUFFER_SIZE>
double_buffer;
typedef canlib_circular_buffer<uint64_t, CANLIB_CIRCULAR_BUFFER_SIZE>
uint64_buffer;
typedef canlib_circular_buffer<std::string, CANLIB_CIRCULAR_BUFFER_SIZE>
string_buffer;
// structure contains all the messages with a enum value associated
// the type is unified to uint64_t
typedef std::unordered_map<field_name, uint64_buffer> message_enums;
typedef std::unordered_map<messages_name, message_enums> network_enums;
// structure contains all the messages with a signal associated
// the type is unified to double
typedef std::unordered_map<field_name, double_buffer> message_signals;
typedef std::unordered_map<messages_name, message_signals> network_signals;
// structure contains all the messages with a string associated
// the type is unified to string
typedef std::unordered_map<field_name, string_buffer> message_strings;
typedef std::unordered_map<messages_name, message_strings> network_strings;
#endif // CANLIB_PROTO_INTERFACE_TYPES
#endif // GPSLIB_COMMON_TYPES_H