# SimpleBuffer

可変長の配列ですが、最大長は固定の配列クラスです。

```cpp
template <class T, 
          class SOUT=_SimpleBuffer_DummyStreamOut,
          int is_string_type=0>
class SimpleBuffer : public SOUT
```

配列のメモリは、外部の固定バッファを参照する方法と、内部にコストラクタで確保する方法の２種類があります。

{% hint style="warning" %}
外部のバッファを参照する場合、参照先のメモリを安全に利用できるようユーザプログラムで管理しなければなりません。
{% endhint %}

## template 引数

いくつかの派生クラスを定義するためtemplateによる定義となっています。

| 引数              | 意味                                                                                                                                                                                                 |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `T`             | データ型                                                                                                                                                                                               |
| `SOUT`          | <p><code>IStreamOut</code> 派生クラスを継承することで<code><<</code>演算子などを用いたデータ追加を可能とします。<br><code>IStreamOut</code>クラスを継承するとメンバー変数が増えるため、デフォルトはダミーとなっています。</p>                                                |
| `is_sting_type` | <p><code>1</code>を指定すると、文字列型 (<code>uint8\_t</code>や<code>wchar\_t</code>) の場合に、NUL終端を意識したコードを有効にします。</p><ul><li>バッファを確保する際に終端文字分を余分に確保する</li><li>固定長配列によるコピーコンストラクトなどではNUL文字までをコピー対象とする</li></ul> |

## メソッド

### SimpleBuffer() - コストラクタ

```cpp
SimpleBuffer()
SimpleBuffer(T* p, uint16_t u16len, uint16_t u16maxlen)
SimpleBuffer(uint16_t u16maxlen)
```

パラメータなしのコンストラクタは、バッファ未登録として初期化します。バッファが未登録の場合は`length_max()`が0になります。このオブジェクトを配列として利用するには`attach()`メソッドにより改めてバッファを登録する必要があります。

外部のバッファを参照する場合は、バッファへのポインタ`p`、配列の初期長`u16len`、配列の最大長`u16maxlen`を指定します。

メモリを動的確保するには`u16maxlen`のみを指定するコンストラクタを呼び出します。

### 代入演算子、コピーコンストラクタ

```cpp
SimpleBuffer(const SimpleBuffer<T>& ref)
SimpleBuffer<T>& operator = (const SimpleBuffer<T>& ref)
```

コピー元が、外部メモリ参照の場合は、コピー元の参照先をそのままコピーします。

コピー元が、内部にメモリ確保している場合は、コピー元のメモリ領域をそのまま利用します。新たにメモリのコピーを作成するわけではありません。本クラスでの内部確保したメモリは、スマートポインタ`shared_ptr`で管理されます。コピー先とコピー元すべてのオブジェクトが破棄された時点で、メモリ領域を破棄します。

### attach()

```cpp
void attach(T* p, uint16_t l, uint16_t lm)
```

配列の参照先を再設定します。

{% hint style="warning" %}
内部メモリ確保のオブジェクトの場合、内部メモリのスマートポインタを破棄しません。

一時的に部分配列として取り扱うといった使い方を想定します。以下の例では、128バイトの長さの`buf`を生成した後に、先頭17バイト目から末尾までの部分配列`buf_sub`を生成しています。

```cpp
SimpleBuffer<uint8_t> buf(128), buf_sub;

buf_sub = buf;
buf_sub.attach(buf.begin() + 16, 0, buf.max_length() - 16);
```

{% endhint %}

### begin(), end()

```cpp
T* begin()
T* end()
```

配列の先頭ポインタ、末尾＋１のアドレスのポインタを返します。STLのアルゴリズムや範囲for文などで利用されます。

配列バッファの先頭ポインタを得るときに`begin()`を用います。

### append()

⇒`push_back()`

### push\_back()

```cpp
bool append(T c)
void push_back(T c) { append(c); }
```

配列の末尾に要素を追加します。要素が追加できないときはfalseが戻ります。

### length(), length\_max()

⇒`size(), capacity()`

### size(), capacity()

```cpp
uint16_t length()
uint16_t size() { return length(); }

uint16_t length_max()
uint16_t capacity() { return length_max(); }
```

`size()`は配列の長さ、`capacity()`は配列の最大長を返します。

### redim()

⇒`reserve()`

### reserve()

```cpp
bool redim(uint16_t len)
bool reserve(uint16_t len) { return redim(len); }
```

配列の長さを変更します。現在の長さより大きくなる場合は要素型`T`のデフォルトの初期化方法`T{}`にて初期化されます。数値型なら0です。

### operator \[]

```cpp
inline T& operator [] (int i)
```

配列へのアクセス手段を提供します。

インデックス`i`は、負の値の場合は配列の末尾からのインデックスとなります。`-1`が末尾になります。
