1
0

doc: add doc for num namespace

This commit is contained in:
2026-01-20 14:30:14 +08:00
parent e161dafac5
commit 044c04aa07
4 changed files with 185 additions and 0 deletions

View File

@@ -43,6 +43,12 @@
\li \subpage num__parser
\li \subpage num__op
\li \subpage num__safe_cast
\li \subpage num__safe_op
\li \subpage patch
<B>Text Encoding</B>

30
doc/src/num/op.dox Normal file
View File

@@ -0,0 +1,30 @@
namespace yycc::num::op {
/**
\page num__op Numeric Operations
Namespace yycc::num::op provides functions for robust numeric operations inspired by Rust's approach to primitive type operations.
Currently, this namespace only supports unsigned integer ceiling division, though more operations may be added in the future based on demand.
\section num__op__div_ceil Ceiling Division
The \c div_ceil function performs division between two unsigned integers and rounds up the result.
It uses a safe algorithm that avoids potential overflow issues that could occur with the traditional formula <TT>(lhs + rhs - 1) / rhs</TT>.
The function computes: <TT>(lhs % rhs == 0) ? (lhs / rhs) : (lhs / rhs) + 1u</TT>
The function prevents division by zero by checking the divisor before performing the operation and throwing a std::logic_error if the divisor is zero.
Here are some examples showing how to use this function:
\code
#include <yycc/num/op.hpp>
// Ceiling division examples
uint32_t result1 = op::div_ceil(uint32_t(10), uint32_t(3)); // Results in 4
uint32_t result2 = op::div_ceil(uint32_t(9), uint32_t(3)); // Results in 3
uint32_t result3 = op::div_ceil(uint32_t(1), uint32_t(10)); // Results in 1
\endcode
*/
}

63
doc/src/num/safe_cast.dox Normal file
View File

@@ -0,0 +1,63 @@
namespace yycc::num::safe_cast {
/**
\page num__safe_cast Numeric Safe Casting
Namespace yycc::num::safe_cast provides functions which safely cast numeric value from one type to another.
\section num__safe_cast__overview Overview
When writing C++ code, casting between types with different ranges is very important
but greatly easy to make mistakes which finally cause fatal errors.
Inspired by Rust's approach to type conversion,
this namespace provides safe casting functions that handle potential overflow and underflow issues.
\section num__safe_cast__functions Functions
The namespace provides two main functions:
\li \c to() - Direct conversion for cases where the destination type can definitely hold the source value
which means definitely safe conversions (widening conversions).
\li \c try_to() - Attempt conversion and return a Result type that includes error information if the conversion fails
which means potentially risky conversions (narrowing conversions).
The \c try_to function returns a \c std::expected.
If the conversion succeeds, the result contains the converted value.
If it fails, it contains a error info.
\section num__safe_cast__examples Examples
Here are some examples showing how to use the safe casting functions:
\code
#include <yycc/num/safe_cast.hpp>
// Safe conversion using 'to' function
uint32_t val1 = safe_cast::to<uint32_t>(static_cast<int16_t>(123));
// Potentially risky conversion using 'try_to' function
auto result = safe_cast::try_to<int16_t>(static_cast<int32_t>(12345));
if (result.has_value()) {
auto converted = result.value();
// Use converted value
} else {
// Handle error
}
\endcode
\section num__safe_cast__notes Notes
The safety of conversions is determined at compile time using the \c CAN_SAFE_TO meta-programming concept.
However, for variable-length data types (like \c size_t ), the safety determination may vary across platforms,
which could affect code portability. For this reason, it would be better to use \c try_to for these types
for better robust application on different platforms.
\section num__safe_cast__limitations Limitations
This namespace supports safe casting between integral types only.
Currently unsupported conversions include:
\li Floating-point to floating-point conversions
\li Floating-point to integer conversions
*/
}

86
doc/src/num/safe_op.dox Normal file
View File

@@ -0,0 +1,86 @@
namespace yycc::num::safe_op {
/**
\page num__safe_op Numeric Safe Arithmetic Operations
Namespace yycc::num::safe_op provides Rust-like safe arithmetic operations
for handling overflow, underflow, and other undefined behaviors in C++.
\section num__safe_op__overview Overview
Inspired by Rust's rich set of arithmetic operators,
this namespace provides safe arithmetic operations that handle potential overflow, underflow, and other undefined behaviors that commonly occur in C++.
It offers multiple strategies for handling arithmetic operations including wrapping, checked, overflowing, saturating, and strict operations.
\section num__safe_op__operation_types Operation Types
The namespace provides several families of arithmetic operations:
\li \c wrapping_* operations: Perform arithmetic with wrapping on overflow/underflow (similar to unsigned integer behavior)
\li \c checked_* operations: Return std::optional containing the result, or std::nullopt if overflow/underflow occurs
\li \c overflowing_* operations: Return a pair with the result and a boolean indicating whether overflow occurred
\li \c saturating_* operations: Clamp the result to the min/max value when overflow/underflow occurs
\li \c strict_* operations: Throw exceptions when overflow/underflow occurs
\li \c ordinary operations (add, sub, mul, div): Alias to wrapping operations for safe default behavior
\section num__safe_op__arithmetic_functions Arithmetic Functions
For each operation type, the namespace provides functions for the four basic arithmetic operations:
\li \c _add : Addition
\li \c _sub : Subtraction
\li \c _mul : Multiplication
\li \c _div : Division
For example, for wrapping operations: \c wrapping_add, \c wrapping_sub, \c wrapping_mul, \c wrapping_div.
\section num__safe_op__examples Examples
Here are some examples showing how to use the safe arithmetic functions:
\code
#include <yycc/num/safe_op.hpp>
#include <iostream>
// Wrapping addition - wraps around on overflow
uint8_t result1 = safe_op::wrapping_add(uint8_t(200), uint8_t(100)); // Results in 44
// Checked multiplication - returns std::optional
auto result2 = safe_op::checked_mul(int32_t(1000000), int32_t(1000000));
if (!result2.has_value()) {
std::cout << "Multiplication overflowed!" << std::endl;
} else {
std::cout << "Result: " << result2.value() << std::endl;
}
// Overflowing subtraction - returns pair of result and overflow flag
auto [result3, overflowed] = safe_op::overflowing_sub(int32_t(-10), int32_t(INT32_MIN));
if (overflowed) {
std::cout << "Subtraction overflowed!" << std::endl;
}
// Saturating multiplication - clamps to min/max on overflow
int32_t result4 = safe_op::saturating_mul(int32_t(1000000), int32_t(1000000)); // Clamps to INT32_MAX
// Ordinary operations - safe defaults without undefined behavior
int32_t result5 = safe_op::add(int32_t(10), int32_t(20)); // 30
\endcode
\section num__safe_op__undefined_behaviors Handling of Undefined Behaviors
This namespace handles several undefined behaviors in C++ arithmetic:
\li Signed integer overflow and underflow (e.g. INT_MAX + 1)
\li Division by zero
\li Performing INT_MIN / -1 division (which would result in a value that doesn't fit in the type)
For division operations, special care is taken to handle these undefined behaviors appropriately depending on the operation type.
\section num__safe_op__platform_support Platform Support
The implementation uses hardware-specific overflow detection functions:
\li GCC/Clang: Uses built-in functions like __builtin_add_overflow
\li Windows: Uses Windows API functions from \c intsafe.h
This ensures optimal performance across different platforms.
*/
}