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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

project(mcpplibs-primitives VERSION 1.0.0 LANGUAGES CXX)
project(mcpplibs-primitives VERSION 0.1.0 LANGUAGES CXX)

find_package(Threads REQUIRED)

Expand Down
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,39 @@

本仓库实现了底层强类型 primitive 基础设施(traits、policy、underlying 类型分类),供上层 `Integer`/`Floating`/`Boolean` 等封装使用。

> [!WARNING]
> 目前项目还在开发中,API会随着后续演进而改变

## 特性

- **C++23 模块** — `import mcpplibs.templates;`
- **C++23 模块** — `import mcpplibs.primitives;`
- **双构建系统** — 同时支持 xmake 和 CMake
- **CI/CD** — GitHub Actions 多平台构建(Linux / macOS / Windows)
- **标准化结构** — 遵循 [mcpp-style-ref](https://github.com/mcpp-community/mcpp-style-ref) 编码规范
- **开箱即用** — 包含示例、测试和架构文档

## Operators

该库在 `primitive` 类型上重载了常见的 C++ 算术、位运算和一元运算符。算术行为受策略(policy)控制:

- 值策略(`checked_value` / `saturating_value` / `unchecked_value`)决定溢出行为;
- 错误策略(`throw_error` / `expected_error` / `terminate_error`)决定在 `checked_value` 且发生错误时的处理方式。

示例:

```cpp
import mcpplibs.primitives;
using namespace mcpplibs::primitives;
using namespace mcpplibs::primitives::policy;

primitive<int> a{1}, b{2};
auto c = a + b; // primitive<int>

primitive<int, expected_error> x{std::numeric_limits<int>::max()};
primitive<int, expected_error> y{1};
auto maybe = x + y; // std::expected<primitive<int, expected_error>, std::overflow_error>
```

## 项目结构

```
Expand Down
52 changes: 38 additions & 14 deletions examples/basic.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,50 @@
#include <iostream>
#include <limits>

import mcpplibs.primitives;

int main() {
using namespace mcpplibs::primitives;
using namespace mcpplibs::primitives::policy;
using namespace mcpplibs::primitives::operators;
using namespace mcpplibs::primitives::types;

std::cout << "=== mcpplibs.primitives traits & policy example ===\n";
std::cout << std::boolalpha;
std::cout << "int is std_integer: " << std_integer<int> << "\n";
std::cout << "double is std_floating: " << std_floating<double> << "\n";
std::cout << "int is underlying_type: " << underlying_type<int> << "\n";

std::cout
<< "default value policy is unchecked_value: "
<< std::is_same_v<default_value, checked_value> << "\n";

std::cout << "checked_value is a policy_type: "
<< policy_type<checked_value> << "\n";
std::cout << "checked_value category == value: "
<< (policy::traits<checked_value>::kind == category::value)
// Operators
I32<> a{3};
I32<> b{4};
auto c = a + b; // primitive<int>
std::cout << "3 + 4 = " << static_cast<int>(c) << "\n";

// Error handling
I32<checked_value> lhs{1};
I32<checked_value> rhs{std::numeric_limits<std::int32_t>::max()};

try {
auto res = lhs + rhs;
} catch (const std::exception &e) {
std::cout << "An exception occurred: " << e.what() << "\n";
}

I64<checked_value, expected_error> lhs2{1};
I64<checked_value, expected_error> rhs2{std::numeric_limits<std::int64_t>::max()};

auto res2 = lhs2 + rhs2;

// Saturating
I32<saturating_value> s1{std::numeric_limits<std::int32_t>::max()};
I32<saturating_value> s2{1};
auto sat = s1 + s2; // saturating -> stays max
std::cout << "saturating max + 1 = " << static_cast<std::int32_t>(sat)
<< "\n";

// Mixed-type addition
using expected_type = I64<category_compatible_type>;
expected_type L1{5};
I32<category_compatible_type> L2{6};
auto mix = L1 + L2; // common_type -> I64
std::cout << "5 + 6 = " << mix.value() << "\n";
std::cout << std::boolalpha;
std::cout << "Does type of mix is I64<category_compatible_type>: " << std::same_as<decltype(mix), expected_type> << std::endl;

return 0;
}
Loading
Loading