リングバッファを示すクラス。 サウンドバッファとしても,ゲームのコントローラ情報キューとしても たぶん使えるはずです。
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
- - | | | | | - | | | | | - | | | | | | | - | | | | ! | | | | | | | | | | | | ! | | | | | | | | | - | | ! | | | | | | - | | | ! | | | - | ! | | | | | | | - | | | | | | | | | | | | - | | ! ! | | | | | | | | | | | | | | | | | | - | - | | ! | | | ! | | | | | | | | | | | | | | - | | | | | - | | ! | | ! | | - | | | | | - | | ! | | ! | | | | | | | | | | | - | | ! | | | | | | | ! | | !
/** * @file * リングバッファクラスを記述する。 */ #pragma once //----------------------------------------------------------- #include <apcl/debug/Assert.hpp> #include <apcl/util/Types.hpp> //----------------------------------------------------------- namespace apcl { namespace container { using ::apcl::util::u32; /// リングバッファのクラス template< typename T > class Ring { public: typedef T ValType; ///< テンプレートの型 /// UnitTest static void unitTest() { const int aSize = 30; Ring<int> ring( aSize ); apclAssert( ring.size() == 1 ); apclAssert( ring.sizeMax() == aSize ); for ( int i = 0; i < aSize; ++i ) { apclAssert( ring.index() == i+1 ); apclAssert( ring.size() == i+2 ); ring.at(0) = i; ring.next(); } apclAssert( ring.index() == 0 ); apclAssert( ring.size() == ring.sizeMax() ); Ring<int> ring2( ring ); for ( int i = 0; i < aSize; ++i ) apclAssert( ring.at(i) == ring2.at(i) ); Ring<int> ring3( 1 ); ring3 = ring; for ( int i = 0; i < aSize; ++i ) apclAssert( ring.at(i) == ring3.at(i) ); apclAssert( ring3.at(0) == 0 ); } //================================================= /// @name 生成・破棄 //@{ /// バッファサイズを指定して作成 explicit Ring( const u32 aSizeMax ): size_( aSizeMax ), index_( 0 ), loopedFlg_( false ) { apclAssert( aSizeMax > 0 ); buff_ = new T[size_]; } /// コピーコンストラクタ explicit Ring( const Ring<T>& aRing ): size_( aRing.sizeMax() ), index_( 0 ), loopedFlg_( false ) { apclAssert( size_ > 0 ); buff_ = new T[size_]; copy( aRing ); } /// デストラクタ virtual ~Ring() { delete[] buff_; } //@} //================================================= /// @name 複製 //@{ /// 引数の内容をコピーする。 void copy( const Ring<T>& aRing ) { // 解放 delete[] buff_; // 初期化 size_ = aRing.sizeMax(); index_ = aRing.index(); loopedFlg_ = aRing.size() == aRing.sizeMax(); buff_ = new T[size_]; // コピー const u32 max = aRing.size(); for ( u32 i = 0; i < max; ++i ) { const u32 index = index_ >= i ? index_-i : size_-(i-index_); buff_[index] = aRing.at(i); } } //@} //================================================= /// @name サイズ //@{ /// 現在のサイズを取得する。 u32 size()const { return loopedFlg_ ? size_ : index_+1; } /// 最大サイズを取得する。 u32 sizeMax()const { return size_; } //@} //================================================= /// @name インデックス //@{ /// 現在指してるバッファのインデックス値を取得する。 u32 index()const { return index_; } /// 現在指しているバッファのインデックスを1つ移動する。 void next() { if ( index_ == size_ -1 ) { loopedFlg_ = true; index_ = 0; } else ++index_; apclAssert( index_ >=0 && index_ < size_ ); } //@} //================================================= /** * @name 参照取得 * <pre> * index = 0が,現在指してるバッファのインデックス。 * インデックス値が増えるほど,過去にさかのぼる。 * また,インデックス値は0以上,size()未満である必要がある。 * </pre> */ //@{ /// 要素の参照を取得する。 T& at( const u32 aIndex ) { apclAssert( aIndex >= 0 && aIndex < size() ); u32 index; if ( aIndex <= index_ ) index = index_ - aIndex; else { const u32 subMemo = aIndex - index_; index = size_ - subMemo; } apclAssert( index < size_ ); return buff_[index]; } /// at(aIndex)のconst版 const T& at( const u32 aIndex )const { apclAssert( aIndex >= 0 && aIndex < size() ); u32 index; if ( aIndex <= index_ ) index = index_ - aIndex; else { const u32 subMemo = aIndex - index_; index = size_ - subMemo; } apclAssert( index < size_ ); return buff_[index]; } //@} //================================================= /// @name 演算子 //@{ /// at()のカバー T& operator[]( const u32 aIndex ){ return at(aIndex); } /// at()のカバー const T& operator[]( const u32 aIndex )const{ return at(aIndex); } /// copy()のカバー const Ring<T>& operator=( const Ring<T>& aRing ) { copy( aRing ); return *this; } //@} private: T* buff_; u32 size_; u32 index_; bool loopedFlg_; }; }} // end of namespace ::apcl::container //----------------------------------------------------------- // EOF
1 2 3 4 5 6 7 8
/** * @file * Ring.hppの実装を記述する。 */ #include <apcl/container/Ring.hpp> //----------------------------------------------------------- // EOF