ARCS6 AR6-REV.24062600
読み取り中…
検索中…
一致する文字列を見つけられません
RingBuffer.hh
1
5//
6// Copyright (C) 2011-2020 Yokokura, Yuki
7// This program is free software;
8// you can redistribute it and/or modify it under the terms of the BSD License.
9// For details, see the License.txt file.
10//
11// リングバッファの動作例
12// GetRelativeValueFromFirst(k=13)
13// SetFirstValue (進む方向→) |
14// | |
15// [0][j=i+1+k-N=1][2][3][4][5][6][7][8][9][10][i=11][j=i+1=12][13][j=i+1+k=14][15][N-1=16] (N=17)
16// | | | | |
17// | | | GetFinalValue |
18// GetRelativeValueFromEnd(k=6) | | GetRelativeValueFromEnd(k=2)
19// | GetFirstValue
20// GetRelativeValueFromFirst(k=3)
21
22#ifndef RINGBUFFER
23#define RINGBUFFER
24
25#include <cassert>
26#include <pthread.h>
27#include <array>
28#include <string>
29#include "ARCSassert.hh"
30#include "Matrix.hh"
31
32// ARCS組込み用マクロ
33#ifdef ARCS_IN
34 // ARCSに組み込まれる場合
35 #include "ARCSassert.hh"
36 #include "ARCSeventlog.hh"
37#else
38 // ARCSに組み込まれない場合
39 #define arcs_assert(a) (assert(a))
40 #define PassedLog()
41 #define EventLog(a)
42 #define EventLogVar(a)
43#endif
44
45namespace ARCS { // ARCS名前空間
50template <typename T, unsigned long N, bool M = true>
52 public:
53 std::array<T, N> Buffer;
54
56 // Length;リングバッファの大きさ
58 : Buffer(), i(0), BufMutex()
59 {
60 PassedLog();
61 if constexpr(M == true) pthread_mutex_init(&BufMutex, NULL);// Mutexの初期化
62 ClearBuffer(); // バッファクリア
63 }
64
68 : i(r.i), Buffer(r.Buffer), BufMutex(r.BufMutex)
69 {
70
71 }
72
75 PassedLog();
76 }
77
80 void SetFirstValue(const T& u){
81 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
82 ++i; // リングバッファカウンタ
83 if(N <= i) i = 0; // バッファの最後まで行ったらカウンタリセット
84 Buffer[i] = u; // バッファに入力値を格納
85 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
86 }
87
91 T ret;
92 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
93 ret = Buffer[i]; // バッファから読み出す
94 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
95 return ret;
96 }
97
100 T GetRelativeValueFromFirst(const unsigned long k){
101 T ret;
102 long j;
103 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
104 j = i - k; // 今のリングバッファカウンタから相対値を減算
105 if(j < 0) j = j + N;// バッファ要素番号の最初を下回っていたら,先頭+はみ出た分にセット
106 arcs_assert((unsigned long)j < N);
107 ret = Buffer[j];
108 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
109 return ret;
110 }
111
114 T GetRelativeValueFromEnd(const unsigned long k){
115 T ret;
116 unsigned long j;
117 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
118 j = i + 1 + k; // 今のリングバッファカウンタに相対値を加算
119 if(N <= j) j = j - N; // バッファ要素番号の最後を超えていたら,先頭+はみ出た分にセット
120 arcs_assert(j < N);
121 ret = Buffer[j];
122 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
123 return ret;
124 }
125
129 T ret;
130 unsigned long j;
131 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
132 if(i == N - 1){ // バッファカウンタがリングの終端に達していたら,
133 j = 0; // リングの先端へ
134 }else{
135 j = i + 1; // それ以外は最後尾へ
136 }
137 ret = Buffer[j];
138 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
139 return ret;
140 }
141
144 void SetCounter(const unsigned long j){
145 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
146 i = j; // カウンタを任意値にセット
147 if(N <= i) i = N - 1; // バッファの最後を超えてたら終端でリミット
148 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
149 }
150
152 void ResetCounter(void){
153 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
154 i = 0;
155 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
156 }
157
160 void FillBuffer(const T& u){
161 if constexpr(M == true) pthread_mutex_lock(&BufMutex); // Mutexロック
162 for(unsigned long j = 0; j < N; ++j) Buffer[j] = u;
163 if constexpr(M == true) pthread_mutex_unlock(&BufMutex);// Mutexロック解除
164 }
165
167 void ClearBuffer(void){
168 if constexpr(std::is_same_v<T, std::string>){
169 // 文字列型のとき
170 FillBuffer(""); // 空文字で埋める
171 }else if constexpr(std::is_floating_point_v<T>){
172 // 浮動小数点型のとき
173 FillBuffer(0); // ゼロで埋める
174 }else if constexpr(std::is_integral_v<T>){
175 // 整数型のとき
176 FillBuffer(0); // ゼロで埋める
177 }else{
178 // それ以外のときは行列型と判断
179 for(size_t i = 0; i < N; ++i) Buffer.at(i).FillAllZero(); // バッファ内の全行列をクリア
180 }
181 }
182
183 private:
184 RingBuffer(const RingBuffer&) = delete;
185 const RingBuffer& operator=(const RingBuffer&) = delete;
186 unsigned long i;
187 pthread_mutex_t BufMutex;
188};
189}
190
191#endif
192
ARCS イベントログクラス
#define PassedLog()
イベントログ用マクロ(ファイルと行番号のみ記録版)
Definition ARCSeventlog.hh:26
ARCS用ASSERTクラス
#define arcs_assert(a)
ARCS用assertマクロ a : assert条件
Definition ARCSassert.hh:17
行列/ベクトル計算クラス(テンプレート版)
リングバッファクラス
Definition RingBuffer.hh:51
RingBuffer()
コンストラクタ
Definition RingBuffer.hh:57
T GetRelativeValueFromFirst(const unsigned long k)
バッファの最先端から k だけ後方側に戻ったところの値を取り出す関数
Definition RingBuffer.hh:100
T GetFinalValue(void)
バッファから最後尾の値を取り出す関数
Definition RingBuffer.hh:128
~RingBuffer()
デストラクタ
Definition RingBuffer.hh:74
void SetCounter(const unsigned long j)
カウンタを任意値に設定する関数
Definition RingBuffer.hh:144
void SetFirstValue(const T &u)
値をバッファの先頭に格納する関数
Definition RingBuffer.hh:80
void ResetCounter(void)
カウンタをリセットする関数
Definition RingBuffer.hh:152
T GetFirstValue(void)
値をバッファの現在の先頭から取り出す関数
Definition RingBuffer.hh:90
void ClearBuffer(void)
バッファのゼロクリア
Definition RingBuffer.hh:167
RingBuffer(RingBuffer &&r)
ムーブコンストラクタ
Definition RingBuffer.hh:67
void FillBuffer(const T &u)
バッファを指定値で埋める
Definition RingBuffer.hh:160
std::array< T, N > Buffer
リングバッファ
Definition RingBuffer.hh:53
T GetRelativeValueFromEnd(const unsigned long k)
バッファの最後尾から k だけ先頭側に進んだところの値を取り出す関数
Definition RingBuffer.hh:114