You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/modules/ROOT/pages/design.adoc
+10-10Lines changed: 10 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,7 +26,7 @@ Bugs like these are subtle, difficult to catch in code review, and can have seve
26
26
27
27
Existing tools help but leave gaps.
28
28
Compiler flags like `-Wsign-conversion` and `-Wconversion` catch many issues at compile time, and UBSan catches undefined behavior at runtime.
29
-
But UBSan explicitly allows unsigned integer rollover because the standard defines it as well-defined behavior -- even though silent rollover is the source of countless bugs.
29
+
But UBSan explicitly allows unsigned integer rollover because the standard defines it as well-defined behavior, even though silent rollover is the source of countless bugs.
30
30
Boost.SafeNumbers aims to go further: by default, unsigned rollover is an error.
31
31
32
32
== Core Design Principles
@@ -42,15 +42,15 @@ The cost is slightly more verbose code at type boundaries; the benefit is that e
42
42
43
43
=== Fail Early, Fail Loudly
44
44
45
-
When an operation would produce an incorrect result -- overflow, underflow, division by zero -- the library makes this visible rather than silently continuing with a wrong value.
45
+
When an operation produces an incorrect result, (e.g., overflow, underflow, division by zero) the library makes this visible rather than silently continuing with a wrong value.
46
46
47
47
At compile time, errors become compiler errors.
48
48
At runtime, errors throw exceptions by default.
49
49
There is no mode where an error is silently ignored unless the programmer explicitly opts into wrapping behavior.
50
50
51
51
=== Type Safety as a First-Class Concern
52
52
53
-
The safe types (`u8`, `u16`, `u32`, `u64`, `u128`) are concrete, named types -- not template wrappers around a policy.
53
+
The safe types (`u8`, `u16`, `u32`, `u64`, `u128`) are concrete, named types, not template wrappers around a policy.
54
54
This makes them easy to read, easy to teach, and easy to use as drop-in replacements for builtin types.
55
55
56
56
Overflow policies are expressed through named free functions (`saturating_add`, `wrapping_add`, etc.) rather than through type-level policy parameters.
@@ -101,7 +101,7 @@ Different domains require different responses to overflow:
101
101
- General application code benefits from *exceptions*: the error is reported and can be handled.
102
102
- Some code needs to *detect and branch*: check whether overflow occurred without changing control flow.
103
103
104
-
The library's default -- `throw_exception` -- is the safest general-purpose choice because it makes errors impossible to ignore.
104
+
The library's default, `throw_exception`, is the safest general-purpose choice because it makes errors impossible to ignore.
105
105
For other needs, named free functions make the policy explicit at each call site:
106
106
107
107
[source,c++]
@@ -135,24 +135,24 @@ See xref:policies.adoc[] for the full API reference.
135
135
136
136
The library intentionally prohibits several operations that are legal in pass:[C++] but are common sources of bugs:
137
137
138
-
**Construction from `bool`** -- Prevents conflation of boolean logic and integer arithmetic.
138
+
**Construction from `bool`**: Prevents conflation of boolean logic and integer arithmetic.
139
139
In pass:[C++], `true + true == 2`, which is rarely the intended behavior.
140
140
Constructing a safe integer from `bool` is a compile-time error.
141
141
142
-
**Mixed-width arithmetic** -- Adding a `u8` to a `u32` is a compile-time error.
142
+
**Mixed-width arithmetic**: Adding a `u8` to a `u32` is a compile-time error.
143
143
In pass:[C++], the narrower operand would be implicitly promoted, which hides the fact that two different-sized values are being combined.
144
144
The library requires an explicit conversion so the programmer acknowledges the width difference.
145
145
146
-
**Unary minus on unsigned types** -- In pass:[C++], `-x` on an unsigned value performs modular negation, producing a large positive number.
146
+
**Unary minus on unsigned types**: In pass:[C++], `-x` on an unsigned value performs modular negation, producing a large positive number.
147
147
This is almost never intentional.
148
-
The library does not define unary minus for unsigned types, so attempting it is a compile-time error.
148
+
The library will provide a `static_assert` message should this operation be attempted.
149
149
150
-
**Implicit conversions to and from builtin types** -- All conversions between safe types and builtin types require an explicit cast.
150
+
**Implicit conversions to and from builtin types**: All conversions between safe types and builtin types require an explicit cast.
151
151
This prevents accidental loss of safety guarantees when passing values across API boundaries.
152
152
153
153
== Performance Considerations
154
154
155
-
The library uses compiler intrinsics for overflow detection: `__builtin_add_overflow`, `__builtin_sub_overflow`, and `__builtin_mul_overflow` on GCC and Clang, and platform-specific intrinsics (`_addcarry_u64`, `_subborrow_u64`, `_umul128`) on MSVC.
155
+
The library uses compiler intrinsics for overflow detection: `pass:[__builtin_add_overflow]`, `pass:[__builtin_sub_overflow]`, and `pass:[__builtin_mul_overflow]` on GCC and Clang, and platform-specific intrinsics (`_addcarry_u64`, `_subborrow_u64`, `_umul128`) on MSVC.
156
156
These compile to efficient hardware instructions (typically a single arithmetic instruction followed by a conditional branch on the carry or overflow flag).
157
157
158
158
The target is a runtime penalty of less than 2x compared to builtin types.
consteval auto is_power_10(const verified_type_basis<T> n) -> bool;
233
+
----
234
+
235
+
Compile-time only overload for verified types.
236
+
237
+
Since `is_power_10` is `consteval` for verified types, the result is guaranteed to be a compile-time constant and can be used directly in `static_assert`.
0 commit comments