1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

            
6
// Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
// 	http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17

            
18
//! Primitive traits for the runtime arithmetic.
19

            
20
use codec::HasCompact;
21
use core::ops::{
22
	Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, Shr, Sub, SubAssign,
23
};
24
pub use ensure::{
25
	ensure_pow, Ensure, EnsureAdd, EnsureAddAssign, EnsureDiv, EnsureDivAssign,
26
	EnsureFixedPointNumber, EnsureFrom, EnsureInto, EnsureMul, EnsureMulAssign, EnsureOp,
27
	EnsureOpAssign, EnsureSub, EnsureSubAssign,
28
};
29
pub use integer_sqrt::IntegerSquareRoot;
30
pub use num_traits::{
31
	checked_pow, Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl,
32
	CheckedShr, CheckedSub, One, Signed, Unsigned, Zero,
33
};
34

            
35
use crate::MultiplyRational;
36

            
37
/// A meta trait for arithmetic type operations, regardless of any limitation on size.
38
pub trait BaseArithmetic:
39
	From<u8>
40
	+ Zero
41
	+ One
42
	+ IntegerSquareRoot
43
	+ Add<Self, Output = Self>
44
	+ AddAssign<Self>
45
	+ Sub<Self, Output = Self>
46
	+ SubAssign<Self>
47
	+ Mul<Self, Output = Self>
48
	+ MulAssign<Self>
49
	+ Div<Self, Output = Self>
50
	+ DivAssign<Self>
51
	+ Rem<Self, Output = Self>
52
	+ RemAssign<Self>
53
	+ Shl<u32, Output = Self>
54
	+ Shr<u32, Output = Self>
55
	+ CheckedShl
56
	+ CheckedShr
57
	+ CheckedAdd
58
	+ CheckedSub
59
	+ CheckedMul
60
	+ CheckedDiv
61
	+ CheckedRem
62
	+ CheckedNeg
63
	+ Ensure
64
	+ Saturating
65
	+ PartialOrd<Self>
66
	+ Ord
67
	+ Bounded
68
	+ HasCompact
69
	+ Sized
70
	+ Clone
71
	+ TryFrom<u8>
72
	+ TryInto<u8>
73
	+ TryFrom<u16>
74
	+ TryInto<u16>
75
	+ TryFrom<u32>
76
	+ TryInto<u32>
77
	+ TryFrom<u64>
78
	+ TryInto<u64>
79
	+ TryFrom<u128>
80
	+ TryInto<u128>
81
	+ TryFrom<usize>
82
	+ TryInto<usize>
83
	+ UniqueSaturatedFrom<u8>
84
	+ UniqueSaturatedInto<u8>
85
	+ UniqueSaturatedFrom<u16>
86
	+ UniqueSaturatedInto<u16>
87
	+ UniqueSaturatedFrom<u32>
88
	+ UniqueSaturatedInto<u32>
89
	+ UniqueSaturatedFrom<u64>
90
	+ UniqueSaturatedInto<u64>
91
	+ UniqueSaturatedFrom<u128>
92
	+ UniqueSaturatedInto<u128>
93
{
94
}
95

            
96
impl<
97
		T: From<u8>
98
			+ Zero
99
			+ One
100
			+ IntegerSquareRoot
101
			+ Add<Self, Output = Self>
102
			+ AddAssign<Self>
103
			+ Sub<Self, Output = Self>
104
			+ SubAssign<Self>
105
			+ Mul<Self, Output = Self>
106
			+ MulAssign<Self>
107
			+ Div<Self, Output = Self>
108
			+ DivAssign<Self>
109
			+ Rem<Self, Output = Self>
110
			+ RemAssign<Self>
111
			+ Shl<u32, Output = Self>
112
			+ Shr<u32, Output = Self>
113
			+ CheckedShl
114
			+ CheckedShr
115
			+ CheckedAdd
116
			+ CheckedSub
117
			+ CheckedMul
118
			+ CheckedDiv
119
			+ CheckedRem
120
			+ CheckedNeg
121
			+ Ensure
122
			+ Saturating
123
			+ PartialOrd<Self>
124
			+ Ord
125
			+ Bounded
126
			+ HasCompact
127
			+ Sized
128
			+ Clone
129
			+ TryFrom<u8>
130
			+ TryInto<u8>
131
			+ TryFrom<u16>
132
			+ TryInto<u16>
133
			+ TryFrom<u32>
134
			+ TryInto<u32>
135
			+ TryFrom<u64>
136
			+ TryInto<u64>
137
			+ TryFrom<u128>
138
			+ TryInto<u128>
139
			+ TryFrom<usize>
140
			+ TryInto<usize>
141
			+ UniqueSaturatedFrom<u8>
142
			+ UniqueSaturatedInto<u8>
143
			+ UniqueSaturatedFrom<u16>
144
			+ UniqueSaturatedInto<u16>
145
			+ UniqueSaturatedFrom<u32>
146
			+ UniqueSaturatedInto<u32>
147
			+ UniqueSaturatedFrom<u64>
148
			+ UniqueSaturatedInto<u64>
149
			+ UniqueSaturatedFrom<u128>
150
			+ UniqueSaturatedInto<u128>,
151
	> BaseArithmetic for T
152
{
153
}
154

            
155
/// A meta trait for arithmetic.
156
///
157
/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
158
/// be able to represent at least `u8` values without loss, hence the trait implies `From<u8>`
159
/// and smaller integers. All other conversions are fallible.
160
pub trait AtLeast8Bit: BaseArithmetic + From<u8> {}
161

            
162
impl<T: BaseArithmetic + From<u8>> AtLeast8Bit for T {}
163

            
164
/// A meta trait for arithmetic.  Same as [`AtLeast8Bit `], but also bounded to be unsigned.
165
pub trait AtLeast8BitUnsigned: AtLeast8Bit + Unsigned {}
166

            
167
impl<T: AtLeast8Bit + Unsigned> AtLeast8BitUnsigned for T {}
168

            
169
/// A meta trait for arithmetic.
170
///
171
/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
172
/// be able to represent at least `u16` values without loss, hence the trait implies `From<u16>`
173
/// and smaller integers. All other conversions are fallible.
174
pub trait AtLeast16Bit: BaseArithmetic + From<u16> {}
175

            
176
impl<T: BaseArithmetic + From<u16>> AtLeast16Bit for T {}
177

            
178
/// A meta trait for arithmetic.  Same as [`AtLeast16Bit `], but also bounded to be unsigned.
179
pub trait AtLeast16BitUnsigned: AtLeast16Bit + Unsigned {}
180

            
181
impl<T: AtLeast16Bit + Unsigned> AtLeast16BitUnsigned for T {}
182

            
183
/// A meta trait for arithmetic.
184
///
185
/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
186
/// be able to represent at least `u32` values without loss, hence the trait implies `From<u32>`
187
/// and smaller integers. All other conversions are fallible.
188
pub trait AtLeast32Bit: BaseArithmetic + From<u16> + From<u32> {}
189

            
190
impl<T: BaseArithmetic + From<u16> + From<u32>> AtLeast32Bit for T {}
191

            
192
/// A meta trait for arithmetic.  Same as [`AtLeast32Bit `], but also bounded to be unsigned.
193
pub trait AtLeast32BitUnsigned: AtLeast32Bit + Unsigned + MultiplyRational {}
194

            
195
impl<T: AtLeast32Bit + Unsigned + MultiplyRational> AtLeast32BitUnsigned for T {}
196

            
197
/// Just like `From` except that if the source value is too big to fit into the destination type
198
/// then it'll saturate the destination.
199
pub trait UniqueSaturatedFrom<T: Sized>: Sized {
200
	/// Convert from a value of `T` into an equivalent instance of `Self`.
201
	fn unique_saturated_from(t: T) -> Self;
202
}
203

            
204
/// Just like `Into` except that if the source value is too big to fit into the destination type
205
/// then it'll saturate the destination.
206
pub trait UniqueSaturatedInto<T: Sized>: Sized {
207
	/// Consume self to return an equivalent value of `T`.
208
	fn unique_saturated_into(self) -> T;
209
}
210

            
211
impl<T: Sized, S: TryFrom<T> + Bounded + Sized> UniqueSaturatedFrom<T> for S {
212
12
	fn unique_saturated_from(t: T) -> Self {
213
12
		S::try_from(t).unwrap_or_else(|_| Bounded::max_value())
214
12
	}
215
}
216

            
217
impl<T: Bounded + Sized, S: TryInto<T> + Sized> UniqueSaturatedInto<T> for S {
218
33761346
	fn unique_saturated_into(self) -> T {
219
33761346
		self.try_into().unwrap_or_else(|_| Bounded::max_value())
220
33761346
	}
221
}
222

            
223
/// Saturating arithmetic operations, returning maximum or minimum values instead of overflowing.
224
pub trait Saturating {
225
	/// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of
226
	/// overflowing.
227
	fn saturating_add(self, rhs: Self) -> Self;
228

            
229
	/// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of
230
	/// overflowing.
231
	fn saturating_sub(self, rhs: Self) -> Self;
232

            
233
	/// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of
234
	/// overflowing.
235
	fn saturating_mul(self, rhs: Self) -> Self;
236

            
237
	/// Saturating exponentiation. Compute `self.pow(exp)`, saturating at the numeric bounds
238
	/// instead of overflowing.
239
	fn saturating_pow(self, exp: usize) -> Self;
240

            
241
	/// Decrement self by one, saturating at zero.
242
	fn saturating_less_one(mut self) -> Self
243
	where
244
		Self: One,
245
	{
246
		self.saturating_dec();
247
		self
248
	}
249

            
250
	/// Increment self by one, saturating at the numeric bounds instead of overflowing.
251
	fn saturating_plus_one(mut self) -> Self
252
	where
253
		Self: One,
254
	{
255
		self.saturating_inc();
256
		self
257
	}
258

            
259
	/// Increment self by one, saturating.
260
195186
	fn saturating_inc(&mut self)
261
195186
	where
262
195186
		Self: One,
263
195186
	{
264
195186
		let mut o = Self::one();
265
195186
		core::mem::swap(&mut o, self);
266
195186
		*self = o.saturating_add(One::one());
267
195186
	}
268

            
269
	/// Decrement self by one, saturating at zero.
270
194763
	fn saturating_dec(&mut self)
271
194763
	where
272
194763
		Self: One,
273
194763
	{
274
194763
		let mut o = Self::one();
275
194763
		core::mem::swap(&mut o, self);
276
194763
		*self = o.saturating_sub(One::one());
277
194763
	}
278

            
279
	/// Increment self by some `amount`, saturating.
280
80
	fn saturating_accrue(&mut self, amount: Self)
281
80
	where
282
80
		Self: One,
283
80
	{
284
80
		let mut o = Self::one();
285
80
		core::mem::swap(&mut o, self);
286
80
		*self = o.saturating_add(amount);
287
80
	}
288

            
289
	/// Decrement self by some `amount`, saturating at zero.
290
246
	fn saturating_reduce(&mut self, amount: Self)
291
246
	where
292
246
		Self: One,
293
246
	{
294
246
		let mut o = Self::one();
295
246
		core::mem::swap(&mut o, self);
296
246
		*self = o.saturating_sub(amount);
297
246
	}
298
}
299

            
300
impl<T: Clone + Zero + One + PartialOrd + CheckedMul + Bounded + num_traits::Saturating> Saturating
301
	for T
302
{
303
1061516
	fn saturating_add(self, o: Self) -> Self {
304
1061516
		<Self as num_traits::Saturating>::saturating_add(self, o)
305
1061516
	}
306

            
307
1725228
	fn saturating_sub(self, o: Self) -> Self {
308
1725228
		<Self as num_traits::Saturating>::saturating_sub(self, o)
309
1725228
	}
310

            
311
197880
	fn saturating_mul(self, o: Self) -> Self {
312
197880
		self.checked_mul(&o).unwrap_or_else(|| {
313
			if (self < T::zero()) != (o < T::zero()) {
314
				Bounded::min_value()
315
			} else {
316
				Bounded::max_value()
317
			}
318
197880
		})
319
197880
	}
320

            
321
12
	fn saturating_pow(self, exp: usize) -> Self {
322
12
		let neg = self < T::zero() && exp % 2 != 0;
323
12
		checked_pow(self, exp).unwrap_or_else(|| {
324
			if neg {
325
				Bounded::min_value()
326
			} else {
327
				Bounded::max_value()
328
			}
329
12
		})
330
12
	}
331
}
332

            
333
/// Convenience type to work around the highly unergonomic syntax needed
334
/// to invoke the functions of overloaded generic traits, in this case
335
/// `SaturatedFrom` and `SaturatedInto`.
336
pub trait SaturatedConversion {
337
	/// Convert from a value of `T` into an equivalent instance of `Self`.
338
	///
339
	/// This just uses `UniqueSaturatedFrom` internally but with this
340
	/// variant you can provide the destination type using turbofish syntax
341
	/// in case Rust happens not to assume the correct type.
342
12
	fn saturated_from<T>(t: T) -> Self
343
12
	where
344
12
		Self: UniqueSaturatedFrom<T>,
345
12
	{
346
12
		<Self as UniqueSaturatedFrom<T>>::unique_saturated_from(t)
347
12
	}
348

            
349
	/// Consume self to return an equivalent value of `T`.
350
	///
351
	/// This just uses `UniqueSaturatedInto` internally but with this
352
	/// variant you can provide the destination type using turbofish syntax
353
	/// in case Rust happens not to assume the correct type.
354
23220960
	fn saturated_into<T>(self) -> T
355
23220960
	where
356
23220960
		Self: UniqueSaturatedInto<T>,
357
23220960
	{
358
23220960
		<Self as UniqueSaturatedInto<T>>::unique_saturated_into(self)
359
23220960
	}
360
}
361
impl<T: Sized> SaturatedConversion for T {}
362

            
363
/// Arithmetic operations with safe error handling.
364
///
365
/// This module provide a readable way to do safe arithmetics, turning this:
366
///
367
/// ```
368
/// # use sp_arithmetic::{traits::EnsureSub, ArithmeticError};
369
/// # fn foo() -> Result<(), ArithmeticError> {
370
/// # let mut my_value: i32 = 1;
371
/// # let other_value: i32 = 1;
372
/// my_value = my_value.checked_sub(other_value).ok_or(ArithmeticError::Overflow)?;
373
/// # Ok(())
374
/// # }
375
/// ```
376
///
377
/// into this:
378
///
379
/// ```
380
/// # use sp_arithmetic::{traits::EnsureSubAssign, ArithmeticError};
381
/// # fn foo() -> Result<(), ArithmeticError> {
382
/// # let mut my_value: i32 = 1;
383
/// # let other_value: i32 = 1;
384
/// my_value.ensure_sub_assign(other_value)?;
385
/// # Ok(())
386
/// # }
387
/// ```
388
///
389
/// choosing the correct [`ArithmeticError`](crate::ArithmeticError) it should return in case of
390
/// fail.
391
///
392
/// The *EnsureOps* family functions follows the same behavior as *CheckedOps* but
393
/// returning an [`ArithmeticError`](crate::ArithmeticError) instead of `None`.
394
mod ensure {
395
	use super::{checked_pow, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, One, Zero};
396
	use crate::{ArithmeticError, FixedPointNumber, FixedPointOperand};
397

            
398
	/// Performs addition that returns [`ArithmeticError`] instead of wrapping around on overflow.
399
	pub trait EnsureAdd: EnsureAddAssign {
400
		/// Adds two numbers, checking for overflow.
401
		///
402
		/// If it fails, [`ArithmeticError`] is returned.
403
		///
404
		/// Similar to [`CheckedAdd::checked_add()`] but returning an [`ArithmeticError`] error.
405
		///
406
		/// # Examples
407
		///
408
		/// ```
409
		/// use sp_arithmetic::traits::EnsureAdd;
410
		///
411
		/// let a: i32 = 10;
412
		/// let b: i32 = 20;
413
		///
414
		/// assert_eq!(a.ensure_add(b), Ok(30));
415
		/// ```
416
		///
417
		/// ```
418
		/// use sp_arithmetic::{traits::EnsureAdd, ArithmeticError};
419
		///
420
		/// fn overflow() -> Result<(), ArithmeticError> {
421
		///     u32::MAX.ensure_add(1)?;
422
		///     Ok(())
423
		/// }
424
		///
425
		/// fn underflow() -> Result<(), ArithmeticError> {
426
		///     i32::MIN.ensure_add(-1)?;
427
		///     Ok(())
428
		/// }
429
		///
430
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
431
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
432
		/// ```
433
		fn ensure_add(mut self, v: Self) -> Result<Self, ArithmeticError> {
434
			self.ensure_add_assign(v)?;
435
			Ok(self)
436
		}
437
	}
438

            
439
	/// Performs subtraction that returns [`ArithmeticError`] instead of wrapping around on
440
	/// underflow.
441
	pub trait EnsureSub: EnsureSubAssign {
442
		/// Subtracts two numbers, checking for overflow.
443
		///
444
		/// If it fails, [`ArithmeticError`] is returned.
445
		///
446
		/// Similar to [`CheckedSub::checked_sub()`] but returning an [`ArithmeticError`] error.
447
		///
448
		/// # Examples
449
		///
450
		/// ```
451
		/// use sp_arithmetic::traits::EnsureSub;
452
		///
453
		/// let a: i32 = 10;
454
		/// let b: i32 = 20;
455
		///
456
		/// assert_eq!(a.ensure_sub(b), Ok(-10));
457
		/// ```
458
		///
459
		/// ```
460
		/// use sp_arithmetic::{traits::EnsureSub, ArithmeticError};
461
		///
462
		/// fn underflow() -> Result<(), ArithmeticError> {
463
		///     0u32.ensure_sub(1)?;
464
		///     Ok(())
465
		/// }
466
		///
467
		/// fn overflow() -> Result<(), ArithmeticError> {
468
		///     i32::MAX.ensure_sub(-1)?;
469
		///     Ok(())
470
		/// }
471
		///
472
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
473
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
474
		/// ```
475
		fn ensure_sub(mut self, v: Self) -> Result<Self, ArithmeticError> {
476
			self.ensure_sub_assign(v)?;
477
			Ok(self)
478
		}
479
	}
480

            
481
	/// Performs multiplication that returns [`ArithmeticError`] instead of wrapping around on
482
	/// overflow.
483
	pub trait EnsureMul: EnsureMulAssign {
484
		/// Multiplies two numbers, checking for overflow.
485
		///
486
		/// If it fails, [`ArithmeticError`] is returned.
487
		///
488
		/// Similar to [`CheckedMul::checked_mul()`] but returning an [`ArithmeticError`] error.
489
		///
490
		/// # Examples
491
		///
492
		/// ```
493
		/// use sp_arithmetic::traits::EnsureMul;
494
		///
495
		/// let a: i32 = 10;
496
		/// let b: i32 = 20;
497
		///
498
		/// assert_eq!(a.ensure_mul(b), Ok(200));
499
		/// ```
500
		///
501
		/// ```
502
		/// use sp_arithmetic::{traits::EnsureMul, ArithmeticError};
503
		///
504
		/// fn overflow() -> Result<(), ArithmeticError> {
505
		///     u32::MAX.ensure_mul(2)?;
506
		///     Ok(())
507
		/// }
508
		///
509
		/// fn underflow() -> Result<(), ArithmeticError> {
510
		///     i32::MAX.ensure_mul(-2)?;
511
		///     Ok(())
512
		/// }
513
		///
514
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
515
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
516
		/// ```
517
		fn ensure_mul(mut self, v: Self) -> Result<Self, ArithmeticError> {
518
			self.ensure_mul_assign(v)?;
519
			Ok(self)
520
		}
521
	}
522

            
523
	/// Performs division that returns [`ArithmeticError`] instead of wrapping around on overflow.
524
	pub trait EnsureDiv: EnsureDivAssign {
525
		/// Divides two numbers, checking for overflow.
526
		///
527
		/// If it fails, [`ArithmeticError`] is returned.
528
		///
529
		/// Similar to [`CheckedDiv::checked_div()`] but returning an [`ArithmeticError`] error.
530
		///
531
		/// # Examples
532
		///
533
		/// ```
534
		/// use sp_arithmetic::traits::EnsureDiv;
535
		///
536
		/// let a: i32 = 20;
537
		/// let b: i32 = 10;
538
		///
539
		/// assert_eq!(a.ensure_div(b), Ok(2));
540
		/// ```
541
		///
542
		/// ```
543
		/// use sp_arithmetic::{traits::EnsureDiv, ArithmeticError};
544
		///
545
		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
546
		///     1.ensure_div(0)?;
547
		///     Ok(())
548
		/// }
549
		///
550
		/// fn overflow() -> Result<(), ArithmeticError> {
551
		///     i64::MIN.ensure_div(-1)?;
552
		///     Ok(())
553
		/// }
554
		///
555
		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
556
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
557
		/// ```
558
		fn ensure_div(mut self, v: Self) -> Result<Self, ArithmeticError> {
559
			self.ensure_div_assign(v)?;
560
			Ok(self)
561
		}
562
	}
563

            
564
	/// Raises a value to the power of exp, returning `ArithmeticError` if an overflow occurred.
565
	///
566
	/// Check [`checked_pow`] for more info about border cases.
567
	///
568
	/// ```
569
	/// use sp_arithmetic::{traits::ensure_pow, ArithmeticError};
570
	///
571
	/// fn overflow() -> Result<(), ArithmeticError> {
572
	///     ensure_pow(2u64, 64)?;
573
	///     Ok(())
574
	/// }
575
	///
576
	/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
577
	/// ```
578
	pub fn ensure_pow<T: One + CheckedMul + Clone>(
579
		base: T,
580
		exp: usize,
581
	) -> Result<T, ArithmeticError> {
582
		checked_pow(base, exp).ok_or(ArithmeticError::Overflow)
583
	}
584

            
585
	impl<T: EnsureAddAssign> EnsureAdd for T {}
586
	impl<T: EnsureSubAssign> EnsureSub for T {}
587
	impl<T: EnsureMulAssign> EnsureMul for T {}
588
	impl<T: EnsureDivAssign> EnsureDiv for T {}
589

            
590
	/// Meta trait that supports all immutable arithmetic `Ensure*` operations
591
	pub trait EnsureOp: EnsureAdd + EnsureSub + EnsureMul + EnsureDiv {}
592
	impl<T: EnsureAdd + EnsureSub + EnsureMul + EnsureDiv> EnsureOp for T {}
593

            
594
	/// Performs self addition that returns [`ArithmeticError`] instead of wrapping around on
595
	/// overflow.
596
	pub trait EnsureAddAssign: CheckedAdd + PartialOrd + Zero {
597
		/// Adds two numbers overwriting the left hand one, checking for overflow.
598
		///
599
		/// If it fails, [`ArithmeticError`] is returned.
600
		///
601
		/// # Examples
602
		///
603
		/// ```
604
		/// use sp_arithmetic::traits::EnsureAddAssign;
605
		///
606
		/// let mut a: i32 = 10;
607
		/// let b: i32 = 20;
608
		///
609
		/// a.ensure_add_assign(b).unwrap();
610
		/// assert_eq!(a, 30);
611
		/// ```
612
		///
613
		/// ```
614
		/// use sp_arithmetic::{traits::EnsureAddAssign, ArithmeticError};
615
		///
616
		/// fn overflow() -> Result<(), ArithmeticError> {
617
		///     let mut max = u32::MAX;
618
		///     max.ensure_add_assign(1)?;
619
		///     Ok(())
620
		/// }
621
		///
622
		/// fn underflow() -> Result<(), ArithmeticError> {
623
		///     let mut max = i32::MIN;
624
		///     max.ensure_add_assign(-1)?;
625
		///     Ok(())
626
		/// }
627
		///
628
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
629
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
630
		/// ```
631
		fn ensure_add_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
632
			*self = self.checked_add(&v).ok_or_else(|| error::equivalent(&v))?;
633
			Ok(())
634
		}
635
	}
636

            
637
	/// Performs self subtraction that returns [`ArithmeticError`] instead of wrapping around on
638
	/// underflow.
639
	pub trait EnsureSubAssign: CheckedSub + PartialOrd + Zero {
640
		/// Subtracts two numbers overwriting the left hand one, checking for overflow.
641
		///
642
		/// If it fails, [`ArithmeticError`] is returned.
643
		///
644
		/// # Examples
645
		///
646
		/// ```
647
		/// use sp_arithmetic::traits::EnsureSubAssign;
648
		///
649
		/// let mut a: i32 = 10;
650
		/// let b: i32 = 20;
651
		///
652
		/// a.ensure_sub_assign(b).unwrap();
653
		/// assert_eq!(a, -10);
654
		/// ```
655
		///
656
		/// ```
657
		/// use sp_arithmetic::{traits::EnsureSubAssign, ArithmeticError};
658
		///
659
		/// fn underflow() -> Result<(), ArithmeticError> {
660
		///     let mut zero: u32 = 0;
661
		///     zero.ensure_sub_assign(1)?;
662
		///     Ok(())
663
		/// }
664
		///
665
		/// fn overflow() -> Result<(), ArithmeticError> {
666
		///     let mut zero = i32::MAX;
667
		///     zero.ensure_sub_assign(-1)?;
668
		///     Ok(())
669
		/// }
670
		///
671
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
672
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
673
		/// ```
674
		fn ensure_sub_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
675
			*self = self.checked_sub(&v).ok_or_else(|| error::inverse(&v))?;
676
			Ok(())
677
		}
678
	}
679

            
680
	/// Performs self multiplication that returns [`ArithmeticError`] instead of wrapping around on
681
	/// overflow.
682
	pub trait EnsureMulAssign: CheckedMul + PartialOrd + Zero {
683
		/// Multiplies two numbers overwriting the left hand one, checking for overflow.
684
		///
685
		/// If it fails, [`ArithmeticError`] is returned.
686
		///
687
		/// # Examples
688
		///
689
		/// ```
690
		/// use sp_arithmetic::traits::EnsureMulAssign;
691
		///
692
		/// let mut a: i32 = 10;
693
		/// let b: i32 = 20;
694
		///
695
		/// a.ensure_mul_assign(b).unwrap();
696
		/// assert_eq!(a, 200);
697
		/// ```
698
		///
699
		/// ```
700
		/// use sp_arithmetic::{traits::EnsureMulAssign, ArithmeticError};
701
		///
702
		/// fn overflow() -> Result<(), ArithmeticError> {
703
		///     let mut max = u32::MAX;
704
		///     max.ensure_mul_assign(2)?;
705
		///     Ok(())
706
		/// }
707
		///
708
		/// fn underflow() -> Result<(), ArithmeticError> {
709
		///     let mut max = i32::MAX;
710
		///     max.ensure_mul_assign(-2)?;
711
		///     Ok(())
712
		/// }
713
		///
714
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
715
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
716
		/// ```
717
		fn ensure_mul_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
718
			*self = self.checked_mul(&v).ok_or_else(|| error::multiplication(self, &v))?;
719
			Ok(())
720
		}
721
	}
722

            
723
	/// Performs self division that returns [`ArithmeticError`] instead of wrapping around on
724
	/// overflow.
725
	pub trait EnsureDivAssign: CheckedDiv + PartialOrd + Zero {
726
		/// Divides two numbers overwriting the left hand one, checking for overflow.
727
		///
728
		/// If it fails, [`ArithmeticError`] is returned.
729
		///
730
		/// # Examples
731
		///
732
		/// ```
733
		/// use sp_arithmetic::traits::EnsureDivAssign;
734
		///
735
		/// let mut a: i32 = 20;
736
		/// let b: i32 = 10;
737
		///
738
		/// a.ensure_div_assign(b).unwrap();
739
		/// assert_eq!(a, 2);
740
		/// ```
741
		///
742
		/// ```
743
		/// use sp_arithmetic::{traits::EnsureDivAssign, ArithmeticError, FixedI64};
744
		///
745
		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
746
		///     let mut one = 1;
747
		///     one.ensure_div_assign(0)?;
748
		///     Ok(())
749
		/// }
750
		///
751
		/// fn overflow() -> Result<(), ArithmeticError> {
752
		///     let mut min = FixedI64::from(i64::MIN);
753
		///     min.ensure_div_assign(FixedI64::from(-1))?;
754
		///     Ok(())
755
		/// }
756
		///
757
		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
758
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
759
		/// ```
760
		fn ensure_div_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
761
			*self = self.checked_div(&v).ok_or_else(|| error::division(self, &v))?;
762
			Ok(())
763
		}
764
	}
765

            
766
	impl<T: CheckedAdd + PartialOrd + Zero> EnsureAddAssign for T {}
767
	impl<T: CheckedSub + PartialOrd + Zero> EnsureSubAssign for T {}
768
	impl<T: CheckedMul + PartialOrd + Zero> EnsureMulAssign for T {}
769
	impl<T: CheckedDiv + PartialOrd + Zero> EnsureDivAssign for T {}
770

            
771
	/// Meta trait that supports all assigned arithmetic `Ensure*` operations
772
	pub trait EnsureOpAssign:
773
		EnsureAddAssign + EnsureSubAssign + EnsureMulAssign + EnsureDivAssign
774
	{
775
	}
776
	impl<T: EnsureAddAssign + EnsureSubAssign + EnsureMulAssign + EnsureDivAssign> EnsureOpAssign
777
		for T
778
	{
779
	}
780

            
781
	pub trait Ensure: EnsureOp + EnsureOpAssign {}
782
	impl<T: EnsureOp + EnsureOpAssign> Ensure for T {}
783

            
784
	/// Extends [`FixedPointNumber`] with the Ensure family functions.
785
	pub trait EnsureFixedPointNumber: FixedPointNumber {
786
		/// Creates `self` from a rational number. Equal to `n / d`.
787
		///
788
		/// Returns [`ArithmeticError`] if `d == 0` or `n / d` exceeds accuracy.
789
		///
790
		/// Similar to [`FixedPointNumber::checked_from_rational()`] but returning an
791
		/// [`ArithmeticError`] error.
792
		///
793
		/// ```
794
		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
795
		///
796
		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
797
		///     FixedI64::ensure_from_rational(1, 0)?;
798
		///     Ok(())
799
		/// }
800
		///
801
		/// fn underflow() -> Result<(), ArithmeticError> {
802
		///     FixedI64::ensure_from_rational(i64::MAX, -1)?;
803
		///     Ok(())
804
		/// }
805
		///
806
		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
807
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
808
		/// ```
809
		fn ensure_from_rational<N: FixedPointOperand, D: FixedPointOperand>(
810
			n: N,
811
			d: D,
812
		) -> Result<Self, ArithmeticError> {
813
			<Self as FixedPointNumber>::checked_from_rational(n, d)
814
				.ok_or_else(|| error::division(&n, &d))
815
		}
816

            
817
		/// Ensure multiplication for integer type `N`. Equal to `self * n`.
818
		///
819
		/// Returns [`ArithmeticError`] if the result does not fit in `N`.
820
		///
821
		/// Similar to [`FixedPointNumber::checked_mul_int()`] but returning an [`ArithmeticError`]
822
		/// error.
823
		///
824
		/// ```
825
		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
826
		///
827
		/// fn overflow() -> Result<(), ArithmeticError> {
828
		///     FixedI64::from(i64::MAX).ensure_mul_int(2)?;
829
		///     Ok(())
830
		/// }
831
		///
832
		/// fn underflow() -> Result<(), ArithmeticError> {
833
		///     FixedI64::from(i64::MAX).ensure_mul_int(-2)?;
834
		///     Ok(())
835
		/// }
836
		///
837
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
838
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
839
		/// ```
840
		fn ensure_mul_int<N: FixedPointOperand>(self, n: N) -> Result<N, ArithmeticError> {
841
			self.checked_mul_int(n).ok_or_else(|| error::multiplication(&self, &n))
842
		}
843

            
844
		/// Ensure division for integer type `N`. Equal to `self / d`.
845
		///
846
		/// Returns [`ArithmeticError`] if the result does not fit in `N` or `d == 0`.
847
		///
848
		/// Similar to [`FixedPointNumber::checked_div_int()`] but returning an [`ArithmeticError`]
849
		/// error.
850
		///
851
		/// ```
852
		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
853
		///
854
		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
855
		///     FixedI64::from(1).ensure_div_int(0)?;
856
		///     Ok(())
857
		/// }
858
		///
859
		/// fn overflow() -> Result<(), ArithmeticError> {
860
		///     FixedI64::from(i64::MIN).ensure_div_int(-1)?;
861
		///     Ok(())
862
		/// }
863
		///
864
		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
865
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
866
		/// ```
867
		fn ensure_div_int<D: FixedPointOperand>(self, d: D) -> Result<D, ArithmeticError> {
868
			self.checked_div_int(d).ok_or_else(|| error::division(&self, &d))
869
		}
870
	}
871

            
872
	impl<T: FixedPointNumber> EnsureFixedPointNumber for T {}
873

            
874
	/// Similar to [`TryFrom`] but returning an [`ArithmeticError`] error.
875
	pub trait EnsureFrom<T: PartialOrd + Zero>: TryFrom<T> + PartialOrd + Zero {
876
		/// Performs the conversion returning an [`ArithmeticError`] if fails.
877
		///
878
		/// Similar to [`TryFrom::try_from()`] but returning an [`ArithmeticError`] error.
879
		///
880
		/// ```
881
		/// use sp_arithmetic::{traits::EnsureFrom, ArithmeticError};
882
		///
883
		/// fn overflow() -> Result<(), ArithmeticError> {
884
		///     let byte: u8 = u8::ensure_from(256u16)?;
885
		///     Ok(())
886
		/// }
887
		///
888
		/// fn underflow() -> Result<(), ArithmeticError> {
889
		///     let byte: i8 = i8::ensure_from(-129i16)?;
890
		///     Ok(())
891
		/// }
892
		///
893
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
894
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
895
		/// ```
896
		fn ensure_from(other: T) -> Result<Self, ArithmeticError> {
897
			let err = error::equivalent(&other);
898
			Self::try_from(other).map_err(|_| err)
899
		}
900
	}
901

            
902
	/// Similar to [`TryInto`] but returning an [`ArithmeticError`] error.
903
	pub trait EnsureInto<T: PartialOrd + Zero>: TryInto<T> + PartialOrd + Zero {
904
		/// Performs the conversion returning an [`ArithmeticError`] if fails.
905
		///
906
		/// Similar to [`TryInto::try_into()`] but returning an [`ArithmeticError`] error
907
		///
908
		/// ```
909
		/// use sp_arithmetic::{traits::EnsureInto, ArithmeticError};
910
		///
911
		/// fn overflow() -> Result<(), ArithmeticError> {
912
		///     let byte: u8 = 256u16.ensure_into()?;
913
		///     Ok(())
914
		/// }
915
		///
916
		/// fn underflow() -> Result<(), ArithmeticError> {
917
		///     let byte: i8 = (-129i16).ensure_into()?;
918
		///     Ok(())
919
		/// }
920
		///
921
		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
922
		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
923
		/// ```
924
		fn ensure_into(self) -> Result<T, ArithmeticError> {
925
			let err = error::equivalent(&self);
926
			self.try_into().map_err(|_| err)
927
		}
928
	}
929

            
930
	impl<T: TryFrom<S> + PartialOrd + Zero, S: PartialOrd + Zero> EnsureFrom<S> for T {}
931
	impl<T: TryInto<S> + PartialOrd + Zero, S: PartialOrd + Zero> EnsureInto<S> for T {}
932

            
933
	mod error {
934
		use super::{ArithmeticError, Zero};
935

            
936
		#[derive(PartialEq)]
937
		enum Signum {
938
			Negative,
939
			Positive,
940
		}
941

            
942
		impl<T: PartialOrd + Zero> From<&T> for Signum {
943
			fn from(value: &T) -> Self {
944
				if value < &Zero::zero() {
945
					Signum::Negative
946
				} else {
947
					Signum::Positive
948
				}
949
			}
950
		}
951

            
952
		impl core::ops::Mul for Signum {
953
			type Output = Self;
954

            
955
			fn mul(self, rhs: Self) -> Self {
956
				if self != rhs {
957
					Signum::Negative
958
				} else {
959
					Signum::Positive
960
				}
961
			}
962
		}
963

            
964
		pub fn equivalent<R: PartialOrd + Zero>(r: &R) -> ArithmeticError {
965
			match Signum::from(r) {
966
				Signum::Negative => ArithmeticError::Underflow,
967
				Signum::Positive => ArithmeticError::Overflow,
968
			}
969
		}
970

            
971
		pub fn inverse<R: PartialOrd + Zero>(r: &R) -> ArithmeticError {
972
			match Signum::from(r) {
973
				Signum::Negative => ArithmeticError::Overflow,
974
				Signum::Positive => ArithmeticError::Underflow,
975
			}
976
		}
977

            
978
		pub fn multiplication<L: PartialOrd + Zero, R: PartialOrd + Zero>(
979
			l: &L,
980
			r: &R,
981
		) -> ArithmeticError {
982
			match Signum::from(l) * Signum::from(r) {
983
				Signum::Negative => ArithmeticError::Underflow,
984
				Signum::Positive => ArithmeticError::Overflow,
985
			}
986
		}
987

            
988
		pub fn division<N: PartialOrd + Zero, D: PartialOrd + Zero>(
989
			n: &N,
990
			d: &D,
991
		) -> ArithmeticError {
992
			if d.is_zero() {
993
				ArithmeticError::DivisionByZero
994
			} else {
995
				multiplication(n, d)
996
			}
997
		}
998
	}
999
}
#[cfg(test)]
mod tests {
	use super::*;
	use crate::ArithmeticError;
	use rand::{seq::SliceRandom, thread_rng, Rng};
	#[test]
	fn ensure_add_works() {
		test_ensure(values(), &EnsureAdd::ensure_add, &CheckedAdd::checked_add);
	}
	#[test]
	fn ensure_sub_works() {
		test_ensure(values(), &EnsureSub::ensure_sub, &CheckedSub::checked_sub);
	}
	#[test]
	fn ensure_mul_works() {
		test_ensure(values(), &EnsureMul::ensure_mul, &CheckedMul::checked_mul);
	}
	#[test]
	fn ensure_div_works() {
		test_ensure(values(), &EnsureDiv::ensure_div, &CheckedDiv::checked_div);
	}
	#[test]
	fn ensure_pow_works() {
		test_ensure(
			values().into_iter().map(|(base, exp)| (base, exp as usize)).collect(),
			ensure_pow,
			|&a, &b| checked_pow(a, b),
		);
	}
	#[test]
	fn ensure_add_assign_works() {
		test_ensure_assign(values(), &EnsureAddAssign::ensure_add_assign, &EnsureAdd::ensure_add);
	}
	#[test]
	fn ensure_sub_assign_works() {
		test_ensure_assign(values(), &EnsureSubAssign::ensure_sub_assign, &EnsureSub::ensure_sub);
	}
	#[test]
	fn ensure_mul_assign_works() {
		test_ensure_assign(values(), &EnsureMulAssign::ensure_mul_assign, &&EnsureMul::ensure_mul);
	}
	#[test]
	fn ensure_div_assign_works() {
		test_ensure_assign(values(), &EnsureDivAssign::ensure_div_assign, &EnsureDiv::ensure_div);
	}
	/// Test that the ensured function returns the expected un-ensured value.
	fn test_ensure<V, W, E, P>(pairs: Vec<(V, W)>, ensured: E, unensured: P)
	where
		V: Ensure + core::fmt::Debug + Copy,
		W: Ensure + core::fmt::Debug + Copy,
		E: Fn(V, W) -> Result<V, ArithmeticError>,
		P: Fn(&V, &W) -> Option<V>,
	{
		for (a, b) in pairs.into_iter() {
			match ensured(a, b) {
				Ok(c) => {
					assert_eq!(unensured(&a, &b), Some(c))
				},
				Err(_) => {
					assert!(unensured(&a, &b).is_none());
				},
			}
		}
	}
	/// Test that the ensured function modifies `self` to the expected un-ensured value.
	fn test_ensure_assign<V, W, E, P>(pairs: Vec<(V, W)>, ensured: E, unensured: P)
	where
		V: Ensure + std::panic::RefUnwindSafe + std::panic::UnwindSafe + core::fmt::Debug + Copy,
		W: Ensure + std::panic::RefUnwindSafe + std::panic::UnwindSafe + core::fmt::Debug + Copy,
		E: Fn(&mut V, W) -> Result<(), ArithmeticError>,
		P: Fn(V, W) -> Result<V, ArithmeticError> + std::panic::RefUnwindSafe,
	{
		for (mut a, b) in pairs.into_iter() {
			let old_a = a;
			match ensured(&mut a, b) {
				Ok(()) => {
					assert_eq!(unensured(old_a, b), Ok(a));
				},
				Err(err) => {
					assert_eq!(a, old_a, "A stays unmodified in the error case");
					assert_eq!(unensured(old_a, b), Err(err));
				},
			}
		}
	}
	/// Generates some good values for testing integer arithmetic.
	fn values() -> Vec<(i32, i32)> {
		let mut rng = thread_rng();
		let mut one_dimension = || {
			let mut ret = vec![0i32; 1007];
			// Some hard-coded interesting values.
			ret[..7].copy_from_slice(&[-1, 0, 1, i32::MIN, i32::MAX, i32::MAX - 1, i32::MIN + 1]);
			// … and some random ones.
			rng.fill(&mut ret[7..]);
			ret.shuffle(&mut rng);
			ret
		};
		one_dimension().into_iter().zip(one_dimension().into_iter()).collect()
	}
}