template <typename T, int N> smplbuf_local
template <typename T> smplbuf_attach
template <typename T> smplbuf_heap
smplbuf
は要素の型T
とメモリの確保方法alloc
で指定したメモリ領域に対して配列の操作を提供するコンテナクラスです。alloc
の指定は煩雑であるためusing
を用いた別名定義が行っています。
オブジェクトの宣言例です。宣言の直後に初期化用のメソッド呼び出しを行います。いずれも初期化直後の最大サイズは128バイトで、サイズは0です。必要に応じてサイズを拡張しながら使用します。
// 配列領域は、クラスメンバー変数の固定配列
smplbuf_local<uint8_t, 128> b1;
// 配列領域は、すでにある領域を参照
uint8_t buf[128];
smplbuf_attach<uint8_t> b2(;
// 配列領域は、ヒープに確保
smplbuf_heap<uint8_t> b3;
// 初期化(グローバル定義の場合はsetup()で行う)
void setup() {
b1.init_local();
b2.attach(buf, 0, 128);
b3.init_heap(128);
}
// 処理関数内
void some_func() {
smplbuf_local<uint8_t, 128> bl;
// bl.init_local(); // smplbuf_localがローカル定義の場合は省略可能
bl.push_back('a');
}
上記のuint8_t
型に限り別名定義があります。
template <int N>
smplbuf_u8
// smplbuf<uint8_t, alloc_local<uint8_t, N>>
smplbuf_u8_attach
// smplbuf<uint8_t, alloc_attach<uint8_t>>
smplbuf_u8_heap
// smplbuf<uint8_t, alloc_heap<uint8_t>>
通常の配列のように[]演算子などを用いて要素にアクセスできますし、イテレータを用いたアクセスも可能です。
void begin() { // begin()は起動時1回だけ動作する
smplbuf_u8<32> b1;
b1.reserve(5); // 5バイト分利用領域に初期化(b1[0..5]にアクセスできる)
b1[0] = 1;
b1[1] = 4;
b1[2] = 9;
b1[3] = 16;
b1[4] = 25;
for(uint8_t x : b1) { // 暗黙に .begin() .end() を用いたループ
Serial << int(x) << ",";
}
}
push_back()
メソッドを定義しています。末尾にデータを追記するタイプのアルゴリズムが使用可能になります。
宣言・初期化
smplbuf_local<T,N>()
smplbuf_local<T,N>::init_local()
smplbuf_attach<T>(T* buf, uint16_t size, uint16_t N)
smplbuf_attach<T>::attach(T* buf, uint16_t size, uint16_t N)
smplbuf_heap<T>()
smplbuf_heap<T>::init_heap(uint16_t N)
// 例
// 内部に固定配列
smplbuf_local<uint8_t, 128> b1;
b1.init_local();
// すでにある配列を利用する
uint8_t buf[128];
smplbuf_attach<uint8_t> b2;
b2.attach(buf, 0, 128);
// ヒープに確保する
smplbuf_heap<uint8_t> b3;
b3.init_heap(128);
型T
でサイズN
のコンテナを宣言します。宣言後に初期化のメソッドを呼び出します。
smplbuf_local
は、内部に固定配列により領域を確保します。コンストラクタによる初期化も可能です。
smplbuf_attach
では、使用するバッファの先頭ポインタT* buf
と配列の初期サイズsize
と最大サイズN
を指定します。コンストラクタによる初期化も可能です。
smplbuf_heap
は、HEAP領域(解放は不可能だが随時確保可能なメモリ領域)にメモリを確保します。一度確保したら開放できない領域ですので通常はグローバル領域に定義します。領域確保はinit_heap()
で行います。コンストラクタによるメモリ確保はできません。必ずinit_heap()
を呼び出して利用してください。
setup()
を推奨)に初期化関数init_local()
,attach()
,init_heap()
を呼び出すようにしてください。初期化子リスト
void in_some_func() {
smplbuf_local<uint8_t, 5> b1;
b1.init_local();
b1 = { 0, 1, 2, 3, 4 };
smplbuf_local<uint8_t, 5> b2{0, 1, 2, 3, 4};
}
初期化子リスト(イニシャライザリスト){ ... }
によるメンバーの初期化をできます。smplbuf_local
のローカル宣言でのコンストラクタでの利用を除き、初期化のメソッドを呼び出した後に有効です。
- 代入演算子の右辺値 (
smplbuf_local
,smplbuf_attach
,smplbuf_heap
) - コンストラクタ(
smplbuf_local
のローカル宣言、グローバル宣言は不可)
メソッド
append()
, push_back()
, pop_back()
inline bool append(T&& c)
inline bool append(const T& c)
inline void push_back(T&& c)
inline void push_back(const T& c)
inline void pop_back()
末尾にメンバーc
を追加します。append()
の戻り値はbool
で、バッファが一杯で追加できないときにfalse
が返ります。
pop_back()
は末尾のエントリを抹消します。ただしエントリのクリアはしません。
empty()
, size()
, capacity()
inline bool empty()
inline bool is_end()
inline uint16_t size()
inline uint16_t capacity()
empty()
は配列に要素が格納されていない場合にtrue
を戻します。is_end()
は反対に配列サイズ一杯まで要素が格納されているときにtrue
を戻します。
size()
は配列の要素数を返します。
capacity()
は配列の最大格納数を返します。
reserve()
, reserve_head()
, redim()
inline bool reserve(uint16_t len)
inline void reserve_head(uint16_t len)
inline void redim(uint16_t len)
reserve()
は配列のサイズを拡張します。配列が格納されていない領域はデフォルトで初期化されます。
reserve_hear()
は配列の先頭部に指定したサイズの領域を確保します。コンテナオブジェクトからは参照できない領域となります。例えばパケットペイロードのヘッダ部分を読み飛ばした部分配列にアクセスするようなコンテナとして利用できるようにします。確保した領域を戻しすべてアクセスできるようにコンテナを戻すには確保時と同じ負の値を与えます。
redim()
は利用領域のサイズを変更します。reserve()
と違い、未使用領域の初期化を行いません。
operator []
inline T& operator [] (int i)
inline T operator [] (int i) const
要素にアクセスします。
i
に負の値を与えるとバッファー末尾からの要素となります。-1
の場合は末尾の要素、-2
は末尾から一つ手前となります。
mwx::stream
への出力
uint8_t
型の配列オブジェクト(smplbuf<uint8_t, *>
)は、mwx::stream
の派生オブジェクトに対して、そのまま出力できます。
<<
演算子
template <class L_STRM, class AL>
mwx::stream<L_STRM>& operator << (
mwx::stream<L_STRM>& lhs, mwx::_smplbuf<uint8_t, AL>& rhs)
//例
smplbuf_u8<128> buf;
buf.push_back('a');
buf.push_back('b');
buf.push_back('c');
Serial << buf;
// 出力: abc
Serial
などmwx::stream
の派生オブジェクトに対して、バイト列を出力します。
to_stream()
inline std::pair<T*, T*> to_stream()
//例
smplbuf_u8<128> buf;
buf.push_back('a');
buf.push_back('b');
buf.push_back('c');
Serial << buf.to_stream();
// 出力:0123
ストリームへの出力目的で利用します。«演算子の実装に用いられています。
mwx::stream
でデータ生成
mwx::stream
では<<
演算子やprintfmt()
メソッドと行ったストリームに対してバイト列を出力するための関数・演算子が定義されています。uint8_t
型のsmplbufの配列を出力先と見立ててストリーム出力手続きを行えます。
方法は2種類あります。
get_stream_helper()
により生成されるヘルパーオブジェクトを利用する。mwx::stream
を継承したsmplbufクラスを利用する。