# 庫開發規范
## 基本結構
- 源代碼:C++代碼,是庫的核心部分,用于實現庫的功能
- 庫信息文件:定義該庫實現的所有命令、類型、常量等,格式詳見相關專題頁
- CMake配置文件:用于在CMake構建系統中配置庫的信息,格式詳見相關專題頁
## 函數命名
系統不對函數命名的具體規范做限制,但**建議在同一支持庫中使用統一風格**,如統一使用 帕斯卡命名法(PascalCase)
注意到,由于歷史原因、固定習慣等因素,EplOnCpp的系統庫出現了混合風格,但這**并不**代表EplOnCpp官方推薦您使用混合風格編程
## 命名空間
庫命令通常應放在命名空間`e::lib::{LibName}`下,其中`{LibName}`為庫的英文名
## 自定義類型
自定義結構通常為智能指針類型`e::system::struct_ptr<Raw>`的別名(`typedef`),其中`Raw`為原始類型
自定義類通常為智能指針類型`e::system::object_ptr<Raw>`的別名(`typedef`),其中`Raw`為原始類型,通常需要繼承自`e::system::basic_object`**并正確實現`clone`方式**
特殊情況可使用其他智能指針類型
我們要求該智能指針必須滿足:
- 可以通過 `->` 操作符訪問指針內容
- 支持拷貝賦值操作
- 擁有拷貝構造函數
- 能夠處理類型的向上/向下轉型,即以下代碼必須有效:
```cpp
static_cast<SmartPtr<Super>>(SmartPtr<Sub>())
static_cast<SmartPtr<Sub>>(SmartPtr<Super>())
```
- 正確處理`e::system::basic_object`,使用`clone`方式完成拷貝操作,以實現 多態 _(特殊情況下,自定義類可以不從`e::system::basic_object`繼承,此時該要求作廢)_
## 命令/成員方法
對于任何命令/成員方法,應當遵循以下約定:
- 對于末尾的可空參數,其在C++層面應當包含默認值(通常為`std::nullopt`)
正確實例:
```cpp
namespace e::lib::demo
{
int32_t foo(std::optional<int32_t> a = std::nullopt);
}
```
錯誤示例:
```cpp
namespace e::lib::demo
{
int32_t foo(std::optional<int32_t> a);
}
```
- 對于通用型參數,在庫層面建議結合模板以便加快效率(此時使用自適應型`*`聲明)
- 通常情況下,任何類型聲明為`*`的函數應當能夠接受`e::system::any`,以便在和 通用型變量 和 其他命令的通用型返回值 組合使用時,能夠正確工作
```
到文本 (取字節集數據 ({ 1, 2, 3, 4, 5, 6, 7, 8 }, #長整數型, ))
```
- 對于`e::system::string`、`e::system::bin`、`e::system::array<T>`等復雜類型,您應當始終避免使用ByVal形式傳遞參數,請應當優先考慮使用常量引用(`const T&`),而后考慮使用非常量引用(`T&`,此時需在庫信息文件中設置`ByRef: true`)
正確實例:
```cpp
namespace e::lib::demo
{
int32_t foo(const e::system::string &a);
}
```
錯誤示例:
```cpp
namespace e::lib::demo
{
int32_t foo(e::system::string a);
}
```