# 库开发规范
## 基本结构
- 源代码: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);
}
```