3 use crate::{Checked, CheckedAdd, Limb, WideWord, Word, Wrapping, Zero}
;
4 use core
::ops
::{Add, AddAssign}
;
8 /// Computes `self + rhs + carry`, returning the result along with the new carry.
10 pub const fn adc(self, rhs
: Limb
, carry
: Limb
) -> (Limb
, Limb
) {
11 let a
= self.0 as WideWord
;
12 let b
= rhs
.0 as WideWord
;
13 let carry
= carry
.0 as WideWord
;
14 let ret
= a
+ b
+ carry
;
15 (Limb(ret
as Word
), Limb((ret
>> Self::BIT_SIZE
) as Word
))
18 /// Perform saturating addition.
20 pub const fn saturating_add(&self, rhs
: Self) -> Self {
21 Limb(self.0.saturating_add(rhs
.0))
24 /// Perform wrapping addition, discarding overflow.
26 pub const fn wrapping_add(&self, rhs
: Self) -> Self {
27 Limb(self.0.wrapping_add(rhs
.0))
31 impl CheckedAdd
for Limb
{
35 fn checked_add(&self, rhs
: Self) -> CtOption
<Self> {
36 let (result
, carry
) = self.adc(rhs
, Limb
::ZERO
);
37 CtOption
::new(result
, carry
.is_zero())
41 impl Add
for Wrapping
<Limb
> {
44 fn add(self, rhs
: Self) -> Wrapping
<Limb
> {
45 Wrapping(self.0.wrapping_add(rhs
.0))
49 impl Add
<&Wrapping
<Limb
>> for Wrapping
<Limb
> {
50 type Output
= Wrapping
<Limb
>;
52 fn add(self, rhs
: &Wrapping
<Limb
>) -> Wrapping
<Limb
> {
53 Wrapping(self.0.wrapping_add(rhs
.0))
57 impl Add
<Wrapping
<Limb
>> for &Wrapping
<Limb
> {
58 type Output
= Wrapping
<Limb
>;
60 fn add(self, rhs
: Wrapping
<Limb
>) -> Wrapping
<Limb
> {
61 Wrapping(self.0.wrapping_add(rhs
.0))
65 impl Add
<&Wrapping
<Limb
>> for &Wrapping
<Limb
> {
66 type Output
= Wrapping
<Limb
>;
68 fn add(self, rhs
: &Wrapping
<Limb
>) -> Wrapping
<Limb
> {
69 Wrapping(self.0.wrapping_add(rhs
.0))
73 impl AddAssign
for Wrapping
<Limb
> {
74 fn add_assign(&mut self, other
: Self) {
75 *self = *self + other
;
79 impl AddAssign
<&Wrapping
<Limb
>> for Wrapping
<Limb
> {
80 fn add_assign(&mut self, other
: &Self) {
81 *self = *self + other
;
85 impl Add
for Checked
<Limb
> {
88 fn add(self, rhs
: Self) -> Checked
<Limb
> {
91 .and_then(|lhs
| rhs
.0.and_then(|rhs
| lhs
.checked_add(rhs
))),
96 impl Add
<&Checked
<Limb
>> for Checked
<Limb
> {
97 type Output
= Checked
<Limb
>;
99 fn add(self, rhs
: &Checked
<Limb
>) -> Checked
<Limb
> {
102 .and_then(|lhs
| rhs
.0.and_then(|rhs
| lhs
.checked_add(rhs
))),
107 impl Add
<Checked
<Limb
>> for &Checked
<Limb
> {
108 type Output
= Checked
<Limb
>;
110 fn add(self, rhs
: Checked
<Limb
>) -> Checked
<Limb
> {
113 .and_then(|lhs
| rhs
.0.and_then(|rhs
| lhs
.checked_add(rhs
))),
118 impl Add
<&Checked
<Limb
>> for &Checked
<Limb
> {
119 type Output
= Checked
<Limb
>;
121 fn add(self, rhs
: &Checked
<Limb
>) -> Checked
<Limb
> {
124 .and_then(|lhs
| rhs
.0.and_then(|rhs
| lhs
.checked_add(rhs
))),
129 impl AddAssign
for Checked
<Limb
> {
130 fn add_assign(&mut self, other
: Self) {
131 *self = *self + other
;
135 impl AddAssign
<&Checked
<Limb
>> for Checked
<Limb
> {
136 fn add_assign(&mut self, other
: &Self) {
137 *self = *self + other
;
143 use crate::{CheckedAdd, Limb}
;
147 let (res
, carry
) = Limb
::ZERO
.adc(Limb
::ONE
, Limb
::ZERO
);
148 assert_eq
!(res
, Limb
::ONE
);
149 assert_eq
!(carry
, Limb
::ZERO
);
153 fn adc_with_carry() {
154 let (res
, carry
) = Limb
::MAX
.adc(Limb
::ONE
, Limb
::ZERO
);
155 assert_eq
!(res
, Limb
::ZERO
);
156 assert_eq
!(carry
, Limb
::ONE
);
160 fn wrapping_add_no_carry() {
161 assert_eq
!(Limb
::ZERO
.wrapping_add(Limb
::ONE
), Limb
::ONE
);
165 fn wrapping_add_with_carry() {
166 assert_eq
!(Limb
::MAX
.wrapping_add(Limb
::ONE
), Limb
::ZERO
);
170 fn checked_add_ok() {
171 let result
= Limb
::ZERO
.checked_add(Limb
::ONE
);
172 assert_eq
!(result
.unwrap(), Limb
::ONE
);
176 fn checked_add_overflow() {
177 let result
= Limb
::MAX
.checked_add(Limb
::ONE
);
178 assert
!(!bool
::from(result
.is_some()));