# 現代 CPP. 容器
###### tags: `CPP`
- [slide:https://hackmd.io/@ewnlm/H1swdFAca] <!-- Put the link to this slide here so people can follow -->
---
# Lambda expression
- C++11 新功能。類似函式,但不需用名稱。
- Statment
- y = a+b;
- Expression
- a+b
- 在C/C++裡,函式必須先宣告才能使用,而且不能在函式裡再宣告新函式。 :
- **Lambda experssion**可以接受外部參數並做運算 :+1:
----
```cpp=
int op_code(int a, int b) {
int _mul2(int din) { return din<<2; }
// Compile error.
auto _mul2 = [](int din)->int { return din<<2; }
// OK. Lambda expression.
int const_nu (4);
// for_each in <algorithm>
vector<int> some_data {0, 2, 3, 4} ;
for_each(some_data.begin(), some_data.end(), _mul2);
// ref or value
}
```
----
# Syntax
```cpp=
[capture](parameter)->trailing-type { body }
```
- capture. 擷取外部變數於body使用。
- parameter. 代入的參數,類似函式的參數列。
- trailing-type. body的回傳值。
- body. 主題
- 詳情請參閱[Lambda expression](https://en.cppreference.com/w/cpp/language/lambda) :thinking_face:
---
# [容器](https://en.cppreference.com/w/cpp/container)
- 顧名思義,就是存放資料的地方。
- 分兩大類,循序式及關聯式,與各自儲存的機制有關,
- Sequence container
- Associate container
- 容器 + <algorithm> 幫助你快速實現你的想法 :sunglasses:
---
# Example 1.
- :question: 不同變數執行相同函式
- 設定每個訊號的極性。
```cpp=
polarity_set(signal1, true);
polarity_set(signal2, true);
polarity_set(signal3, true);
polarity_set(signal4, false);
polarity_set(signal5, false);
```
----
## Solution
- 利用for\_each以及lambda.
```cpp=
vector<SIGNAL> true_cond { signal1, signal2, signal3 };
for_each(true_cond.begin(), true_cond.end(),
[](SIGNAL din) ->void
{ polarity_set(din, true); });
```
----
### Spot light
- list inistialize 直接列出vector的內容。
- iterator of vector. [vector begin](https://en.cppreference.com/w/cpp/container/vector/begin)
- for_each()類似 range-based for loop, 形式不同而已。
- for_each()頭兩個參數是指定容器的範圍,第三個參數是動作,函式或lambda.
- 若需要更改容器內容,記得用參考.
---
# Example 2.
- :question: 設計Shmoo圖外框。
- 能跟隨不同軸的長度變化。
- `#`標示10倍數, `+`標示5倍數, 其餘以`-`標示。
----
## Solution
```cpp=
string boundary;
vector<int> steps(N);
iota(begin(steps), end(steps), 0);
// let steps from 0~N
transform(steps.begin(), steps.end(),
back_inserter(boundary),
[](int i)->char {
return ((i%10)==0)?('#'):((i%5)==0)?('+'):('-');})
// base on steps and generate boundary of SHMOO.
```
----
### Spot light
- 目的是產生SHMOO邊框,為了方便看,在5與10倍數對應位置上標示符號。
- 利用iota()產生數列。
- transform()可以利用其他容器的內容來決定新容器。
- 所以利用steps數列去產生新的string.
---
# Example 3.
- :question: 找出SHMOO邊界值。
- 可能有 Pass to Fail or Fail to Pass.
- 也可能全滿或是全空的狀況。
----
## Solution
```cpp=
vector<PFState> result;
auto bound1 = adjacent_find(begin(result), end(result),
[](auto a, auto b)->bool { return(a!=b)?(true):(false); });
auto bound2 = adjacent_find(next(bound1, 1), end(result),
[](auto a, auto b)->bool { return(a!=b)?(true):(false); });
```
----
### Spot light
```cpp=
auto bound1 = adjacent_find(result.begin(), result.end());
```
- adjacent_find() 本意是找出鄰近兩兩相同的位址,回傳迭代器。
- 但我們可以修改成尋找兩兩不相同的位址。
- 為了確認SHMOO是否有破洞,可以更改尋找的起始位址。
- next(iter, N) 可以回傳iter後第N個迭代器。
---
# Example 4.
- :question: Testbench裡,如何用文字找到對應函式.
----
## Solution
```cpp=
#define COUPLE(sth) make_pair(#sth, sth)
using fptrTest = void(*)(void);
typedef void (*fptrTest)(void);
void RDID_test();
unordered_map<string, fptrTest> store_um {
{"RDID_test", RDID_test},
COUPLE(NR_test),
COUPLE(BE_test),
COUPLE(PP_test),
}
```
----
## Solution
```cpp=
string item ("NR_test");
if(store_um.find(item)!=store_um.end()) {
store_um.at(item)();
}
```
----
### Spot light
- 利用map建立字串與函式指標的關係。unordered_map搜尋較map快.
- 利用巨集簡化. 詳閱macro stringication.
- find()用來尋找Key是否存在.
- 如果不存在, 通常會回傳 end() iterator.
- at(Key)回傳對應Value.用字串去回傳對應函式, 因為要執行此函式, 背後再加圓括弧. :baby_bottle:
- :space_invader: 當Key是struct or class 該怎麼處理?
---
### Thank you! :sheep:
{"contributors":"[{\"id\":\"0b93a0f4-2322-4e3e-9569-2c17e87a9819\",\"add\":4469,\"del\":2820}]","title":"CPP Container","breaks":true,"description":"Brief of container of CPP.","showTags":"true"}