Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions document/DOXYGEN_REQUEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Every file must start with a file-level block like:
* @since <project version or "N/A">
* @ingroup <module or "none">
*/
```yaml
```

* Fill `@author`, `@date`, `@version` from git metadata if available; otherwise set to `"N/A"`.
* Keep the file-level description concise (≤ 2–3 short sentences).
Expand Down Expand Up @@ -87,7 +87,7 @@ Block style example:
* @since Version or "N/A".
* @ingroup Module name or "none".
*/
```text
```

Line-style equivalent:

Expand All @@ -96,7 +96,7 @@ Line-style equivalent:
/// @details Optional extended description in third-person present tense.
/// @param[in] name Description...
/// @return Description...
```yaml
```

* **MUST** include `@tparam` for templates.
* **MUST** include `@throws` (or `@throws None`).
Expand Down Expand Up @@ -178,7 +178,7 @@ Class example:
* @endcode
*/
class RingBuffer { ... };
```yaml
```

---

Expand All @@ -202,7 +202,7 @@ enum class PowerState {
Sleep, ///< Low-power sleep mode.
On ///< Fully powered.
};
```yaml
```

---

Expand All @@ -217,7 +217,7 @@ Example:
```cpp
/// @brief Pointer to underlying device context. Ownership: observer; may be nullptr.
DeviceContext* ctx_;
```yaml
```

---

Expand Down Expand Up @@ -302,14 +302,14 @@ Provide exact failure messages for each check so the generator can iterate.
* @ingroup util
*/
uint64_t parse_le_uint(const uint8_t* buf, size_t len);
```text
```

### Bad (function)

```cpp
/** Parses bytes into a number. This function will parse and return value. */
uint64_t parse_le_uint(const uint8_t* buf, size_t len);
```yaml
```

* Issues: first-person / future tense; no tags; no units; no param directions; too short; possibly misleading.

Expand Down Expand Up @@ -378,7 +378,7 @@ Return an object with fields:
],
"fixme_count": M
}
```yaml
```

---

Expand Down
18 changes: 9 additions & 9 deletions document/HandBook/base/expected.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ cf::expected<std::ifstream, std::string> open_file(const std::string& path) {
}
return file;
}
```text
```

`expected` 强制调用者处理错误——你想拿到值,就必须先检查有没有错误。而且类型系统会帮你看住:一个 `expected<int, ErrorCode>` 要么包含 `int`,要么包含 `ErrorCode`,不可能同时存在或都不存在。

Expand All @@ -66,7 +66,7 @@ cf::expected<int, ParseError> parse_number(std::string_view str) {
return cf::unexpected(ParseError::Overflow);
}
}
```text
```

调用方需要检查结果:

Expand All @@ -85,7 +85,7 @@ if (result.has_value()) {
break;
}
}
```text
```

⚠️ 如果不检查直接调用 `value()`,会抛出 `bad_expected_access` 异常。但这个异常是你在"错误地使用 expected"时才抛出的,和业务逻辑异常是两码事。正常流程下,`expected` 的使用是不抛异常的。

Expand All @@ -107,7 +107,7 @@ int value = result.value_or(-1); // 如果是错误状态,返回 -1

// 方式三:直接访问(如果确实是错误状态,会抛异常)
int value = result.value(); // 可能抛 bad_expected_access
```cpp
```

`operator*` 和 `operator->` 的行为类似指针,但不做边界检查——如果 `expected` 处于错误状态,调用它们的后果是未定义行为。这和原生指针的越界访问一样,性能优先,安全你自己负责。

Expand All @@ -130,7 +130,7 @@ auto result = save_config("config.txt");
if (!result) {
std::cerr << "保存失败: " << result.error() << std::endl;
}
```text
```

`expected<void, E>` 的"值"是虚拟的,成功状态下没有实际数据存储,只有一个标志位。这意味着它的内存开销比 `expected<T, E>` 小——只需要存一个 `bool` 和可能的 `E`。

Expand Down Expand Up @@ -170,7 +170,7 @@ cf::expected<int, std::string> result =
.transform_error([](ParseError err) {
return "解析错误: " + std::to_string(static_cast<int>(err));
});
```text
```

这些操作的组合可以实现复杂的错误处理逻辑,而且代码是线性的,不是嵌套的:

Expand All @@ -194,7 +194,7 @@ return result3;
return parse_number(input)
.and_then(fetch_user)
.and_then(calculate_score);
```text
```

## 与异常的对比

Expand All @@ -220,7 +220,7 @@ union {
E error;
} storage_;
bool has_value_;
```cpp
```

大小是 `max(sizeof(T), sizeof(E)) + sizeof(bool)`,对齐后可能会有一点 padding。如果你在意内存占用,可以让错误类型尽量小——比如用 `enum` 代替 `std::string`。

Expand Down Expand Up @@ -257,7 +257,7 @@ namespace std {
// 类型别名可以帮助过渡
template <typename T, typename E>
using expected = std::expected<T, E>;
```text
```

当然,我们还是建议直接用 `cf::expected`,这样可以保持代码的跨平台兼容性,而且我们可以根据自己的需求定制实现。

Expand Down
16 changes: 8 additions & 8 deletions document/HandBook/base/factory.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ cf::PlainFactory<Widget, int, int> factory;
Widget* w = factory.make(10, 20);
// 使用 w...
delete w; // 调用方负责删除
```text
```

`PlainFactory` 的设计目标之一是跨 ABI 边界。动态库导出的接口通常不适合直接返回 `std::unique_ptr`(不同编译器/标准库的 `unique_ptr` 布局可能不同),但裸指针永远兼容。

Expand All @@ -49,7 +49,7 @@ using WidgetFactory = cf::StaticPlainFactory<Widget, int, int>;
// 在任何地方
auto& factory = WidgetFactory::instance();
Widget* w = factory.make(10, 20);
```text
```

`StaticPlainFactory` 继承了 `PlainFactory` 和 `SimpleSingleton`,线程安全的单例由 Meyer's Singleton 保证。

Expand All @@ -71,15 +71,15 @@ auto unique_svc = factory.make_unique("Logger"); // std::unique_ptr<Service>
auto shared_svc = factory.make_shared("Config"); // std::shared_ptr<Service>

// 不需要手动 delete
```text
```

### StaticSmartPtrPlainFactory - 单例版智能指针工厂

```cpp
using ServiceFactory = cf::StaticSmartPtrPlainFactory<Service, std::string>;

auto svc = ServiceFactory::instance().make_unique("MyService");
```text
```

## RegisteredFactory - 注册式工厂

Expand Down Expand Up @@ -117,7 +117,7 @@ renderer_factory.register_creator([]() -> IRenderer* {
// 创建
auto renderer = renderer_factory.make_unique();
renderer->draw();
```text
```

### 自定义删除器

Expand All @@ -128,7 +128,7 @@ renderer_factory.register_creator(
[]() -> IRenderer* { return new VulkanRenderer; },
[](IRenderer* p) { /* 自定义清理逻辑 */ delete p; }
);
```text
```

### StaticRegisteredFactory - 单例版注册式工厂

Expand All @@ -142,7 +142,7 @@ RendererFactory::instance().register_creator([]() -> IRenderer* {

// 使用
auto renderer = RendererFactory::instance().make_unique();
```text
```

### 检查注册状态

Expand All @@ -152,7 +152,7 @@ if (RendererFactory::instance().has_creator()) {
} else {
// 没有注册任何 creator,无法创建
}
```bash
```

## 线程安全说明

Expand Down
16 changes: 8 additions & 8 deletions document/HandBook/base/hash.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ switch (fnv1a64(token)) {
case fnv1a64("START"): /* ... */ break;
case fnv1a64("STOP"): /* ... */ break;
}
```text
```

编译器会在编译期算出 `fnv1a64("START")` 的值,switch 语句变成了一组整数比较,非常高效。

Expand All @@ -43,7 +43,7 @@ static_assert(h1 != h2, "Different strings must produce different hashes");
// 运行时使用 std::string_view
std::string_view sv = "some_string";
uint64_t h3 = fnv1a64(sv);
```text
```

### 32 位哈希

Expand All @@ -53,7 +53,7 @@ constexpr uint32_t h32 = fnv1a32("TokenA");

// 运行时
uint32_t h = fnv1a32(std::string_view("dynamic"));
```text
```

32 位版本适用于内存受限的场景,但碰撞概率比 64 位高。如果哈希表不大(几千个条目以内),32 位通常够用。

Expand All @@ -64,7 +64,7 @@ uint32_t h = fnv1a32(std::string_view("dynamic"));
constexpr uint64_t h1 = fnv1a64("data"); // 默认种子
constexpr uint64_t h2 = fnv1a64("data", 12345678ULL); // 自定义种子
// h1 != h2,相同输入不同种子产生不同哈希
```text
```

### 用户自定义字面量

Expand All @@ -74,7 +74,7 @@ using namespace cf::hash;
// "_hash" 后缀,编译期计算
constexpr uint64_t h = "MyToken"_hash;
static_assert(h == fnv1a64("MyToken"), "UDL must match function call");
```text
```

`_hash` 字面量让代码更简洁,特别是在 switch-case 里:

Expand All @@ -86,7 +86,7 @@ switch (fnv1a64(cmd)) {
case "save"_hash: save_file(); break;
default: unknown_cmd(); break;
}
```text
```

## FNV-1a 算法

Expand All @@ -98,7 +98,7 @@ for each byte in input:
hash = hash XOR byte
hash = hash * prime
return hash
```bash
```

参数值:

Expand Down Expand Up @@ -138,7 +138,7 @@ if (it != hashmap.end()) {
// 确认是真正的匹配
}
}
```text
```

3. **不要用于安全场景**:FNV-1a 不是加密哈希,不应该用于密码存储、完整性校验等安全场景。

Expand Down
20 changes: 10 additions & 10 deletions document/HandBook/base/linux/proc_parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ auto model = cf::parse_cpuinfo_field(line, "model name");
// 字段不存在时返回空视图
auto missing = cf::parse_cpuinfo_field(line, "vendor_id");
// missing.data() == nullptr
```text
```

实际使用时通常是逐行读取:

Expand All @@ -41,7 +41,7 @@ while (std::getline(cpuinfo, line)) {
std::cout << "厂商: " << vendor << std::endl;
}
}
```text
```

## 字符串去空格

Expand All @@ -52,7 +52,7 @@ std::string_view sv = " hello world ";
auto trimmed = cf::trim_whitespace(sv); // "hello world"
auto left_trimmed = cf::ltrim_whitespace(sv); // "hello world "
auto right_trimmed = cf::rtrim_whitespace(sv);// " hello world"
```text
```

## 解析缓存大小

Expand All @@ -63,7 +63,7 @@ auto size1 = cf::parse_cache_size("32K"); // 32
auto size2 = cf::parse_cache_size("1M"); // 1024
auto size3 = cf::parse_cache_size("2G"); // 2097152
auto invalid = cf::parse_cache_size("xyz"); // std::nullopt
```text
```

这在读取 `/sys/devices/system/cpu/cpu0/cache/index*/size` 时特别有用:

Expand All @@ -73,7 +73,7 @@ auto size_kb = cf::parse_cache_size(l1_size);
if (size_kb) {
std::cout << "L1 缓存: " << *size_kb << " KB" << std::endl;
}
```text
```

## 解析数字

Expand All @@ -84,7 +84,7 @@ auto value = cf::parse_uint32("4096"); // 4096
auto hex1 = cf::parse_hex_uint32("0x41"); // 65
auto hex2 = cf::parse_hex_uint32("FF"); // 255
auto invalid = cf::parse_uint32("abc"); // std::nullopt
```text
```

十六进制解析在处理 ARM 的 `CPU implementer` 字段时很常见:

Expand All @@ -94,7 +94,7 @@ if (auto impl_val = cf::parse_hex_uint32(impl)) {
auto vendor = cf::arm_implementer_to_vendor(*impl_val);
// impl_val = 0x41 -> vendor = "ARM"
}
```text
```

## 读取文件

Expand All @@ -107,7 +107,7 @@ auto max_freq = cf::read_uint32_file(
if (max_freq.has_value()) {
std::cout << "最大频率: " << *max_freq << " kHz" << std::endl;
}
```text
```

⚠️ 这个函数会执行文件 I/O,可能因为权限或文件不存在而失败。返回 `std::nullopt` 时可以判断是文件问题还是解析失败。

Expand All @@ -120,7 +120,7 @@ auto vendor = cf::arm_implementer_to_vendor(0x41); // "ARM"
auto vendor2 = cf::arm_implementer_to_vendor(0x51); // "Qualcomm"
auto vendor3 = cf::arm_implementer_to_vendor(0x69); // "Intel"
auto unknown = cf::arm_implementer_to_vendor(0xFF); // "Unknown"
```text
```

支持的厂商 ID 包括 ARM (0x41)、Broadcom (0x42)、Qualcomm (0x51)、NVIDIA (0x4E) 等。

Expand All @@ -137,7 +137,7 @@ std::string_view bad() {
std::string_view good(const std::string& line) {
return cf::parse_cpuinfo_field(line, "model name"); // OK,调用方保证 line 有效
}
```text
```

## 相关文档

Expand Down
Loading
Loading