Skip to content

Commit 92f4bba

Browse files
feat: Add examples for basic usage, conversion, and algorithms
Signed-off-by: FrozenlemonTee <1115306170@qq.com>
1 parent f580e6b commit 92f4bba

3 files changed

Lines changed: 192 additions & 0 deletions

File tree

examples/ex01_basic_usage.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Example: ex01_basic_usage
3+
*
4+
* Purpose:
5+
* Combine checked literals, primitive factory helpers, and built-in framework
6+
* operators in one compact end-to-end example.
7+
*
8+
* Expected results:
9+
* - `with(...)` builds primitives directly from checked underlying literals.
10+
* - Arithmetic, unary, bitwise, comparison, mixed, and compound operators all
11+
* dispatch successfully.
12+
* - The printed values match: sum=42, neg=-2, mod=2, shl=40, band=8, final=43.
13+
* - Program exits with code 0; otherwise prints an error and exits non-zero.
14+
*/
15+
16+
#include <iostream>
17+
18+
import mcpplibs.primitives;
19+
20+
using namespace mcpplibs::primitives;
21+
22+
int main() {
23+
using namespace mcpplibs::primitives::literals;
24+
using namespace mcpplibs::primitives::operators;
25+
26+
constexpr auto base =
27+
with<policy::value::checked, policy::error::expected>(40_i32);
28+
constexpr auto step =
29+
with<policy::value::checked, policy::error::expected>(2_i32);
30+
constexpr auto mask =
31+
with<policy::value::checked, policy::error::expected>(10_i32);
32+
33+
constexpr auto sum = 2_i32 + base;
34+
if constexpr (!sum.has_value()) {
35+
std::cerr << "basic usage dispatch failed\n";
36+
return 1;
37+
}
38+
39+
constexpr auto neg = -step;
40+
constexpr auto mod = *sum % 5_i32;
41+
constexpr auto shl = mask << step;
42+
constexpr auto band = base & 12_i32;
43+
constexpr auto const eq = *sum == 42_i32;
44+
constexpr auto const cmp = *sum <=> 41_i32;
45+
46+
auto counter =
47+
with<policy::value::checked, policy::error::expected>(1_i32);
48+
auto const pre_inc = ++counter;
49+
constexpr auto bonus =
50+
with<policy::value::checked, policy::error::expected>(41_i32);
51+
auto const add_assign = (counter += bonus);
52+
53+
if (!pre_inc.has_value() || !add_assign.has_value()) {
54+
std::cerr << "basic usage dispatch failed\n";
55+
return 1;
56+
}
57+
58+
if (pre_inc->value() != 2 ||
59+
add_assign->value() != 43 || counter.load() != 43) {
60+
std::cerr << "basic usage produced unexpected values\n";
61+
return 1;
62+
}
63+
64+
std::cout << "sum=" << sum->value() << ", neg=" << neg->value()
65+
<< ", mod=" << mod->value() << ", shl=" << shl->value()
66+
<< ", band=" << band->value() << ", final=" << counter.load()
67+
<< '\n';
68+
69+
std::cout << "basic_usage demo passed\n";
70+
return 0;
71+
}

examples/ex06_conversion.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Example: ex06_conversion
3+
*
4+
* Purpose:
5+
* Demonstrate the conversion helpers for checked, saturating, truncating, and
6+
* exact casts across both underlying values and primitives.
7+
*
8+
* Expected results:
9+
* - checked_cast succeeds for in-range primitive-to-underlying conversion.
10+
* - checked_cast reports underflow for negative-to-unsigned conversion.
11+
* - saturating_cast clamps out-of-range input.
12+
* - truncating_cast drops the fractional part when targeting an integral
13+
* primitive.
14+
* - exact_cast preserves exact values and reports precision loss otherwise.
15+
* - Program prints a success message and exits with code 0.
16+
*/
17+
18+
#include <cstdint>
19+
#include <iostream>
20+
21+
import mcpplibs.primitives;
22+
23+
using namespace mcpplibs::primitives;
24+
25+
int main() {
26+
using namespace mcpplibs::primitives::literals;
27+
28+
using expected_i32 =
29+
types::I32<policy::value::checked, policy::error::expected>;
30+
using expected_f32 =
31+
types::F32<policy::value::checked, policy::error::expected>;
32+
33+
constexpr auto source =
34+
with<policy::value::checked, policy::error::expected>(255_i32);
35+
36+
constexpr auto checked_u16 = conversion::checked_cast<std::uint16_t>(source);
37+
constexpr auto checked_bad = conversion::checked_cast<std::uint16_t>(-1_i32);
38+
constexpr auto saturated_u16 =
39+
conversion::saturating_cast<std::uint16_t>(100000_i32);
40+
auto const truncated_i32 =
41+
conversion::truncating_cast<expected_i32>(12.75_f64);
42+
auto const exact_f32 = conversion::exact_cast<expected_f32>(16777216_i32);
43+
auto const exact_bad = conversion::exact_cast<expected_f32>(16777217_i32);
44+
constexpr auto risk = conversion::numeric_risk<std::uint16_t>(-1_i32);
45+
46+
if (!checked_u16.has_value() || checked_bad.has_value() ||
47+
!exact_f32.has_value() || exact_bad.has_value() || !risk.has_value()) {
48+
std::cerr << "conversion demo expected success path missing\n";
49+
return 1;
50+
}
51+
52+
if (*checked_u16 != static_cast<std::uint16_t>(255) ||
53+
checked_bad.error() != conversion::risk::kind::underflow ||
54+
saturated_u16 != static_cast<std::uint16_t>(65535) ||
55+
truncated_i32.load() != 12 ||
56+
exact_f32->load() != 16777216.0F ||
57+
exact_bad.error() != conversion::risk::kind::precision_loss ||
58+
*risk != conversion::risk::kind::underflow) {
59+
std::cerr << "conversion demo produced unexpected values\n";
60+
return 1;
61+
}
62+
63+
std::cout << "conversion demo passed\n";
64+
return 0;
65+
}

examples/ex07_algorithms.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Example: ex07_algorithms
3+
*
4+
* Purpose:
5+
* Demonstrate the built-in algorithms helpers for numeric limits metadata,
6+
* special values, and hashing.
7+
*
8+
* Expected results:
9+
* - limits<> mirrors std::numeric_limits for supported built-in underlying types.
10+
* - helpers expose lowest/max/epsilon/infinity/quiet_nan values.
11+
* - hash_value() matches std::hash for the same underlying literal value.
12+
* - Program prints a success message and exits with code 0.
13+
*/
14+
15+
#include <cstdint>
16+
#include <iostream>
17+
#include <limits>
18+
19+
import mcpplibs.primitives;
20+
21+
using namespace mcpplibs::primitives;
22+
23+
int main() {
24+
using namespace mcpplibs::primitives::literals;
25+
26+
using int_limits = algorithms::limits<decltype(42_i32)>;
27+
using float_limits = algorithms::limits<double>;
28+
29+
static_assert(int_limits::enabled);
30+
static_assert(float_limits::has_infinity);
31+
static_assert(algorithms::hashable<std::int32_t>);
32+
33+
constexpr auto min_i32 = algorithms::min_value<std::int32_t>();
34+
constexpr auto max_i32 = algorithms::max_value<std::int32_t>();
35+
constexpr auto lowest_f64 = algorithms::lowest_value<double>();
36+
constexpr auto epsilon_f64 = algorithms::epsilon_value<double>();
37+
constexpr auto infinity_f64 = algorithms::infinity_value<double>();
38+
constexpr auto nan_f64 = algorithms::quiet_nan_value<double>();
39+
auto const hash_literal = algorithms::hash_value(42_i32);
40+
auto const hash_builtin = algorithms::hash_value(std::int32_t{42});
41+
42+
if (min_i32 != std::numeric_limits<std::int32_t>::min() ||
43+
max_i32 != std::numeric_limits<std::int32_t>::max() ||
44+
lowest_f64 != std::numeric_limits<double>::lowest() ||
45+
epsilon_f64 != std::numeric_limits<double>::epsilon() ||
46+
!std::isinf(infinity_f64) || !std::isnan(nan_f64) ||
47+
hash_literal != hash_builtin ||
48+
int_limits::digits != std::numeric_limits<std::int32_t>::digits ||
49+
float_limits::kind != underlying::category::floating) {
50+
std::cerr << "algorithms demo produced unexpected values\n";
51+
return 1;
52+
}
53+
54+
std::cout << "algorithms demo passed\n";
55+
return 0;
56+
}

0 commit comments

Comments
 (0)