sp_arithmetic/
traits.rs

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
20use codec::HasCompact;
21use core::ops::{
22	Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, Shr, Sub, SubAssign,
23};
24pub use ensure::{
25	ensure_pow, Ensure, EnsureAdd, EnsureAddAssign, EnsureDiv, EnsureDivAssign,
26	EnsureFixedPointNumber, EnsureFrom, EnsureInto, EnsureMul, EnsureMulAssign, EnsureOp,
27	EnsureOpAssign, EnsureSub, EnsureSubAssign,
28};
29pub use integer_sqrt::IntegerSquareRoot;
30pub use num_traits::{
31	checked_pow, Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl,
32	CheckedShr, CheckedSub, One, Signed, Unsigned, Zero,
33};
34
35use crate::MultiplyRational;
36
37/// A meta trait for arithmetic type operations, regardless of any limitation on size.
38pub 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
96impl<
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.
160pub trait AtLeast8Bit: BaseArithmetic + From<u8> {}
161
162impl<T: BaseArithmetic + From<u8>> AtLeast8Bit for T {}
163
164/// A meta trait for arithmetic.  Same as [`AtLeast8Bit `], but also bounded to be unsigned.
165pub trait AtLeast8BitUnsigned: AtLeast8Bit + Unsigned {}
166
167impl<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.
174pub trait AtLeast16Bit: BaseArithmetic + From<u16> {}
175
176impl<T: BaseArithmetic + From<u16>> AtLeast16Bit for T {}
177
178/// A meta trait for arithmetic.  Same as [`AtLeast16Bit `], but also bounded to be unsigned.
179pub trait AtLeast16BitUnsigned: AtLeast16Bit + Unsigned {}
180
181impl<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.
188pub trait AtLeast32Bit: BaseArithmetic + From<u16> + From<u32> {}
189
190impl<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.
193pub trait AtLeast32BitUnsigned: AtLeast32Bit + Unsigned + MultiplyRational {}
194
195impl<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.
199pub trait UniqueSaturatedFrom<T: Sized>: Sized {
200	/// Convert from a value of `T` into an equivalent instance of `Self`.
201	#[must_use]
202	fn unique_saturated_from(t: T) -> Self;
203}
204
205/// Just like `Into` except that if the source value is too big to fit into the destination type
206/// then it'll saturate the destination.
207pub trait UniqueSaturatedInto<T: Sized>: Sized {
208	/// Consume self to return an equivalent value of `T`.
209	#[must_use]
210	fn unique_saturated_into(self) -> T;
211}
212
213impl<T: Sized, S: TryFrom<T> + Bounded + Sized> UniqueSaturatedFrom<T> for S {
214	fn unique_saturated_from(t: T) -> Self {
215		S::try_from(t).unwrap_or_else(|_| Bounded::max_value())
216	}
217}
218
219impl<T: Bounded + Sized, S: TryInto<T> + Sized> UniqueSaturatedInto<T> for S {
220	fn unique_saturated_into(self) -> T {
221		self.try_into().unwrap_or_else(|_| Bounded::max_value())
222	}
223}
224
225/// Saturating arithmetic operations, returning maximum or minimum values instead of overflowing.
226pub trait Saturating {
227	/// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of
228	/// overflowing.
229	#[must_use]
230	fn saturating_add(self, rhs: Self) -> Self;
231
232	/// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of
233	/// overflowing.
234	#[must_use]
235	fn saturating_sub(self, rhs: Self) -> Self;
236
237	/// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of
238	/// overflowing.
239	#[must_use]
240	fn saturating_mul(self, rhs: Self) -> Self;
241
242	/// Saturating exponentiation. Compute `self.pow(exp)`, saturating at the numeric bounds
243	/// instead of overflowing.
244	#[must_use]
245	fn saturating_pow(self, exp: usize) -> Self;
246
247	/// Decrement self by one, saturating at zero.
248	#[must_use]
249	fn saturating_less_one(mut self) -> Self
250	where
251		Self: One,
252	{
253		self.saturating_dec();
254		self
255	}
256
257	/// Increment self by one, saturating at the numeric bounds instead of overflowing.
258	#[must_use]
259	fn saturating_plus_one(mut self) -> Self
260	where
261		Self: One,
262	{
263		self.saturating_inc();
264		self
265	}
266
267	/// Increment self by one, saturating.
268	fn saturating_inc(&mut self)
269	where
270		Self: One,
271	{
272		let mut o = Self::one();
273		core::mem::swap(&mut o, self);
274		*self = o.saturating_add(One::one());
275	}
276
277	/// Decrement self by one, saturating at zero.
278	fn saturating_dec(&mut self)
279	where
280		Self: One,
281	{
282		let mut o = Self::one();
283		core::mem::swap(&mut o, self);
284		*self = o.saturating_sub(One::one());
285	}
286
287	/// Increment self by some `amount`, saturating.
288	fn saturating_accrue(&mut self, amount: Self)
289	where
290		Self: One,
291	{
292		let mut o = Self::one();
293		core::mem::swap(&mut o, self);
294		*self = o.saturating_add(amount);
295	}
296
297	/// Decrement self by some `amount`, saturating at zero.
298	fn saturating_reduce(&mut self, amount: Self)
299	where
300		Self: One,
301	{
302		let mut o = Self::one();
303		core::mem::swap(&mut o, self);
304		*self = o.saturating_sub(amount);
305	}
306}
307
308impl<T: Clone + Zero + One + PartialOrd + CheckedMul + Bounded + num_traits::Saturating> Saturating
309	for T
310{
311	fn saturating_add(self, o: Self) -> Self {
312		<Self as num_traits::Saturating>::saturating_add(self, o)
313	}
314
315	fn saturating_sub(self, o: Self) -> Self {
316		<Self as num_traits::Saturating>::saturating_sub(self, o)
317	}
318
319	fn saturating_mul(self, o: Self) -> Self {
320		self.checked_mul(&o).unwrap_or_else(|| {
321			if (self < T::zero()) != (o < T::zero()) {
322				Bounded::min_value()
323			} else {
324				Bounded::max_value()
325			}
326		})
327	}
328
329	fn saturating_pow(self, exp: usize) -> Self {
330		let neg = self < T::zero() && exp % 2 != 0;
331		checked_pow(self, exp).unwrap_or_else(|| {
332			if neg {
333				Bounded::min_value()
334			} else {
335				Bounded::max_value()
336			}
337		})
338	}
339}
340
341/// Convenience type to work around the highly unergonomic syntax needed
342/// to invoke the functions of overloaded generic traits, in this case
343/// `SaturatedFrom` and `SaturatedInto`.
344pub trait SaturatedConversion {
345	/// Convert from a value of `T` into an equivalent instance of `Self`.
346	///
347	/// This just uses `UniqueSaturatedFrom` internally but with this
348	/// variant you can provide the destination type using turbofish syntax
349	/// in case Rust happens not to assume the correct type.
350	#[must_use]
351	fn saturated_from<T>(t: T) -> Self
352	where
353		Self: UniqueSaturatedFrom<T>,
354	{
355		<Self as UniqueSaturatedFrom<T>>::unique_saturated_from(t)
356	}
357
358	/// Consume self to return an equivalent value of `T`.
359	///
360	/// This just uses `UniqueSaturatedInto` internally but with this
361	/// variant you can provide the destination type using turbofish syntax
362	/// in case Rust happens not to assume the correct type.
363	#[must_use]
364	fn saturated_into<T>(self) -> T
365	where
366		Self: UniqueSaturatedInto<T>,
367	{
368		<Self as UniqueSaturatedInto<T>>::unique_saturated_into(self)
369	}
370}
371impl<T: Sized> SaturatedConversion for T {}
372
373/// Arithmetic operations with safe error handling.
374///
375/// This module provide a readable way to do safe arithmetics, turning this:
376///
377/// ```
378/// # use sp_arithmetic::{traits::EnsureSub, ArithmeticError};
379/// # fn foo() -> Result<(), ArithmeticError> {
380/// # let mut my_value: i32 = 1;
381/// # let other_value: i32 = 1;
382/// my_value = my_value.checked_sub(other_value).ok_or(ArithmeticError::Overflow)?;
383/// # Ok(())
384/// # }
385/// ```
386///
387/// into this:
388///
389/// ```
390/// # use sp_arithmetic::{traits::EnsureSubAssign, ArithmeticError};
391/// # fn foo() -> Result<(), ArithmeticError> {
392/// # let mut my_value: i32 = 1;
393/// # let other_value: i32 = 1;
394/// my_value.ensure_sub_assign(other_value)?;
395/// # Ok(())
396/// # }
397/// ```
398///
399/// choosing the correct [`ArithmeticError`](crate::ArithmeticError) it should return in case of
400/// fail.
401///
402/// The *EnsureOps* family functions follows the same behavior as *CheckedOps* but
403/// returning an [`ArithmeticError`](crate::ArithmeticError) instead of `None`.
404mod ensure {
405	use super::{checked_pow, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, One, Zero};
406	use crate::{ArithmeticError, FixedPointNumber, FixedPointOperand};
407
408	/// Performs addition that returns [`ArithmeticError`] instead of wrapping around on overflow.
409	pub trait EnsureAdd: EnsureAddAssign {
410		/// Adds two numbers, checking for overflow.
411		///
412		/// If it fails, [`ArithmeticError`] is returned.
413		///
414		/// Similar to [`CheckedAdd::checked_add()`] but returning an [`ArithmeticError`] error.
415		///
416		/// # Examples
417		///
418		/// ```
419		/// use sp_arithmetic::traits::EnsureAdd;
420		///
421		/// let a: i32 = 10;
422		/// let b: i32 = 20;
423		///
424		/// assert_eq!(a.ensure_add(b), Ok(30));
425		/// ```
426		///
427		/// ```
428		/// use sp_arithmetic::{traits::EnsureAdd, ArithmeticError};
429		///
430		/// fn overflow() -> Result<(), ArithmeticError> {
431		///     u32::MAX.ensure_add(1)?;
432		///     Ok(())
433		/// }
434		///
435		/// fn underflow() -> Result<(), ArithmeticError> {
436		///     i32::MIN.ensure_add(-1)?;
437		///     Ok(())
438		/// }
439		///
440		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
441		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
442		/// ```
443		fn ensure_add(mut self, v: Self) -> Result<Self, ArithmeticError> {
444			self.ensure_add_assign(v)?;
445			Ok(self)
446		}
447	}
448
449	/// Performs subtraction that returns [`ArithmeticError`] instead of wrapping around on
450	/// underflow.
451	pub trait EnsureSub: EnsureSubAssign {
452		/// Subtracts two numbers, checking for overflow.
453		///
454		/// If it fails, [`ArithmeticError`] is returned.
455		///
456		/// Similar to [`CheckedSub::checked_sub()`] but returning an [`ArithmeticError`] error.
457		///
458		/// # Examples
459		///
460		/// ```
461		/// use sp_arithmetic::traits::EnsureSub;
462		///
463		/// let a: i32 = 10;
464		/// let b: i32 = 20;
465		///
466		/// assert_eq!(a.ensure_sub(b), Ok(-10));
467		/// ```
468		///
469		/// ```
470		/// use sp_arithmetic::{traits::EnsureSub, ArithmeticError};
471		///
472		/// fn underflow() -> Result<(), ArithmeticError> {
473		///     0u32.ensure_sub(1)?;
474		///     Ok(())
475		/// }
476		///
477		/// fn overflow() -> Result<(), ArithmeticError> {
478		///     i32::MAX.ensure_sub(-1)?;
479		///     Ok(())
480		/// }
481		///
482		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
483		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
484		/// ```
485		fn ensure_sub(mut self, v: Self) -> Result<Self, ArithmeticError> {
486			self.ensure_sub_assign(v)?;
487			Ok(self)
488		}
489	}
490
491	/// Performs multiplication that returns [`ArithmeticError`] instead of wrapping around on
492	/// overflow.
493	pub trait EnsureMul: EnsureMulAssign {
494		/// Multiplies two numbers, checking for overflow.
495		///
496		/// If it fails, [`ArithmeticError`] is returned.
497		///
498		/// Similar to [`CheckedMul::checked_mul()`] but returning an [`ArithmeticError`] error.
499		///
500		/// # Examples
501		///
502		/// ```
503		/// use sp_arithmetic::traits::EnsureMul;
504		///
505		/// let a: i32 = 10;
506		/// let b: i32 = 20;
507		///
508		/// assert_eq!(a.ensure_mul(b), Ok(200));
509		/// ```
510		///
511		/// ```
512		/// use sp_arithmetic::{traits::EnsureMul, ArithmeticError};
513		///
514		/// fn overflow() -> Result<(), ArithmeticError> {
515		///     u32::MAX.ensure_mul(2)?;
516		///     Ok(())
517		/// }
518		///
519		/// fn underflow() -> Result<(), ArithmeticError> {
520		///     i32::MAX.ensure_mul(-2)?;
521		///     Ok(())
522		/// }
523		///
524		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
525		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
526		/// ```
527		fn ensure_mul(mut self, v: Self) -> Result<Self, ArithmeticError> {
528			self.ensure_mul_assign(v)?;
529			Ok(self)
530		}
531	}
532
533	/// Performs division that returns [`ArithmeticError`] instead of wrapping around on overflow.
534	pub trait EnsureDiv: EnsureDivAssign {
535		/// Divides two numbers, checking for overflow.
536		///
537		/// If it fails, [`ArithmeticError`] is returned.
538		///
539		/// Similar to [`CheckedDiv::checked_div()`] but returning an [`ArithmeticError`] error.
540		///
541		/// # Examples
542		///
543		/// ```
544		/// use sp_arithmetic::traits::EnsureDiv;
545		///
546		/// let a: i32 = 20;
547		/// let b: i32 = 10;
548		///
549		/// assert_eq!(a.ensure_div(b), Ok(2));
550		/// ```
551		///
552		/// ```
553		/// use sp_arithmetic::{traits::EnsureDiv, ArithmeticError};
554		///
555		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
556		///     1.ensure_div(0)?;
557		///     Ok(())
558		/// }
559		///
560		/// fn overflow() -> Result<(), ArithmeticError> {
561		///     i64::MIN.ensure_div(-1)?;
562		///     Ok(())
563		/// }
564		///
565		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
566		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
567		/// ```
568		fn ensure_div(mut self, v: Self) -> Result<Self, ArithmeticError> {
569			self.ensure_div_assign(v)?;
570			Ok(self)
571		}
572	}
573
574	/// Raises a value to the power of exp, returning `ArithmeticError` if an overflow occurred.
575	///
576	/// Check [`checked_pow`] for more info about border cases.
577	///
578	/// ```
579	/// use sp_arithmetic::{traits::ensure_pow, ArithmeticError};
580	///
581	/// fn overflow() -> Result<(), ArithmeticError> {
582	///     ensure_pow(2u64, 64)?;
583	///     Ok(())
584	/// }
585	///
586	/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
587	/// ```
588	pub fn ensure_pow<T: One + CheckedMul + Clone>(
589		base: T,
590		exp: usize,
591	) -> Result<T, ArithmeticError> {
592		checked_pow(base, exp).ok_or(ArithmeticError::Overflow)
593	}
594
595	impl<T: EnsureAddAssign> EnsureAdd for T {}
596	impl<T: EnsureSubAssign> EnsureSub for T {}
597	impl<T: EnsureMulAssign> EnsureMul for T {}
598	impl<T: EnsureDivAssign> EnsureDiv for T {}
599
600	/// Meta trait that supports all immutable arithmetic `Ensure*` operations
601	pub trait EnsureOp: EnsureAdd + EnsureSub + EnsureMul + EnsureDiv {}
602	impl<T: EnsureAdd + EnsureSub + EnsureMul + EnsureDiv> EnsureOp for T {}
603
604	/// Performs self addition that returns [`ArithmeticError`] instead of wrapping around on
605	/// overflow.
606	pub trait EnsureAddAssign: CheckedAdd + PartialOrd + Zero {
607		/// Adds two numbers overwriting the left hand one, checking for overflow.
608		///
609		/// If it fails, [`ArithmeticError`] is returned.
610		///
611		/// # Examples
612		///
613		/// ```
614		/// use sp_arithmetic::traits::EnsureAddAssign;
615		///
616		/// let mut a: i32 = 10;
617		/// let b: i32 = 20;
618		///
619		/// a.ensure_add_assign(b).unwrap();
620		/// assert_eq!(a, 30);
621		/// ```
622		///
623		/// ```
624		/// use sp_arithmetic::{traits::EnsureAddAssign, ArithmeticError};
625		///
626		/// fn overflow() -> Result<(), ArithmeticError> {
627		///     let mut max = u32::MAX;
628		///     max.ensure_add_assign(1)?;
629		///     Ok(())
630		/// }
631		///
632		/// fn underflow() -> Result<(), ArithmeticError> {
633		///     let mut max = i32::MIN;
634		///     max.ensure_add_assign(-1)?;
635		///     Ok(())
636		/// }
637		///
638		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
639		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
640		/// ```
641		fn ensure_add_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
642			*self = self.checked_add(&v).ok_or_else(|| error::equivalent(&v))?;
643			Ok(())
644		}
645	}
646
647	/// Performs self subtraction that returns [`ArithmeticError`] instead of wrapping around on
648	/// underflow.
649	pub trait EnsureSubAssign: CheckedSub + PartialOrd + Zero {
650		/// Subtracts two numbers overwriting the left hand one, checking for overflow.
651		///
652		/// If it fails, [`ArithmeticError`] is returned.
653		///
654		/// # Examples
655		///
656		/// ```
657		/// use sp_arithmetic::traits::EnsureSubAssign;
658		///
659		/// let mut a: i32 = 10;
660		/// let b: i32 = 20;
661		///
662		/// a.ensure_sub_assign(b).unwrap();
663		/// assert_eq!(a, -10);
664		/// ```
665		///
666		/// ```
667		/// use sp_arithmetic::{traits::EnsureSubAssign, ArithmeticError};
668		///
669		/// fn underflow() -> Result<(), ArithmeticError> {
670		///     let mut zero: u32 = 0;
671		///     zero.ensure_sub_assign(1)?;
672		///     Ok(())
673		/// }
674		///
675		/// fn overflow() -> Result<(), ArithmeticError> {
676		///     let mut zero = i32::MAX;
677		///     zero.ensure_sub_assign(-1)?;
678		///     Ok(())
679		/// }
680		///
681		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
682		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
683		/// ```
684		fn ensure_sub_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
685			*self = self.checked_sub(&v).ok_or_else(|| error::inverse(&v))?;
686			Ok(())
687		}
688	}
689
690	/// Performs self multiplication that returns [`ArithmeticError`] instead of wrapping around on
691	/// overflow.
692	pub trait EnsureMulAssign: CheckedMul + PartialOrd + Zero {
693		/// Multiplies two numbers overwriting the left hand one, checking for overflow.
694		///
695		/// If it fails, [`ArithmeticError`] is returned.
696		///
697		/// # Examples
698		///
699		/// ```
700		/// use sp_arithmetic::traits::EnsureMulAssign;
701		///
702		/// let mut a: i32 = 10;
703		/// let b: i32 = 20;
704		///
705		/// a.ensure_mul_assign(b).unwrap();
706		/// assert_eq!(a, 200);
707		/// ```
708		///
709		/// ```
710		/// use sp_arithmetic::{traits::EnsureMulAssign, ArithmeticError};
711		///
712		/// fn overflow() -> Result<(), ArithmeticError> {
713		///     let mut max = u32::MAX;
714		///     max.ensure_mul_assign(2)?;
715		///     Ok(())
716		/// }
717		///
718		/// fn underflow() -> Result<(), ArithmeticError> {
719		///     let mut max = i32::MAX;
720		///     max.ensure_mul_assign(-2)?;
721		///     Ok(())
722		/// }
723		///
724		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
725		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
726		/// ```
727		fn ensure_mul_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
728			*self = self.checked_mul(&v).ok_or_else(|| error::multiplication(self, &v))?;
729			Ok(())
730		}
731	}
732
733	/// Performs self division that returns [`ArithmeticError`] instead of wrapping around on
734	/// overflow.
735	pub trait EnsureDivAssign: CheckedDiv + PartialOrd + Zero {
736		/// Divides two numbers overwriting the left hand one, checking for overflow.
737		///
738		/// If it fails, [`ArithmeticError`] is returned.
739		///
740		/// # Examples
741		///
742		/// ```
743		/// use sp_arithmetic::traits::EnsureDivAssign;
744		///
745		/// let mut a: i32 = 20;
746		/// let b: i32 = 10;
747		///
748		/// a.ensure_div_assign(b).unwrap();
749		/// assert_eq!(a, 2);
750		/// ```
751		///
752		/// ```
753		/// use sp_arithmetic::{traits::EnsureDivAssign, ArithmeticError, FixedI64};
754		///
755		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
756		///     let mut one = 1;
757		///     one.ensure_div_assign(0)?;
758		///     Ok(())
759		/// }
760		///
761		/// fn overflow() -> Result<(), ArithmeticError> {
762		///     let mut min = FixedI64::from(i64::MIN);
763		///     min.ensure_div_assign(FixedI64::from(-1))?;
764		///     Ok(())
765		/// }
766		///
767		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
768		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
769		/// ```
770		fn ensure_div_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
771			*self = self.checked_div(&v).ok_or_else(|| error::division(self, &v))?;
772			Ok(())
773		}
774	}
775
776	impl<T: CheckedAdd + PartialOrd + Zero> EnsureAddAssign for T {}
777	impl<T: CheckedSub + PartialOrd + Zero> EnsureSubAssign for T {}
778	impl<T: CheckedMul + PartialOrd + Zero> EnsureMulAssign for T {}
779	impl<T: CheckedDiv + PartialOrd + Zero> EnsureDivAssign for T {}
780
781	/// Meta trait that supports all assigned arithmetic `Ensure*` operations
782	pub trait EnsureOpAssign:
783		EnsureAddAssign + EnsureSubAssign + EnsureMulAssign + EnsureDivAssign
784	{
785	}
786	impl<T: EnsureAddAssign + EnsureSubAssign + EnsureMulAssign + EnsureDivAssign> EnsureOpAssign
787		for T
788	{
789	}
790
791	pub trait Ensure: EnsureOp + EnsureOpAssign {}
792	impl<T: EnsureOp + EnsureOpAssign> Ensure for T {}
793
794	/// Extends [`FixedPointNumber`] with the Ensure family functions.
795	pub trait EnsureFixedPointNumber: FixedPointNumber {
796		/// Creates `self` from a rational number. Equal to `n / d`.
797		///
798		/// Returns [`ArithmeticError`] if `d == 0` or `n / d` exceeds accuracy.
799		///
800		/// Similar to [`FixedPointNumber::checked_from_rational()`] but returning an
801		/// [`ArithmeticError`] error.
802		///
803		/// ```
804		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
805		///
806		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
807		///     FixedI64::ensure_from_rational(1, 0)?;
808		///     Ok(())
809		/// }
810		///
811		/// fn underflow() -> Result<(), ArithmeticError> {
812		///     FixedI64::ensure_from_rational(i64::MAX, -1)?;
813		///     Ok(())
814		/// }
815		///
816		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
817		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
818		/// ```
819		fn ensure_from_rational<N: FixedPointOperand, D: FixedPointOperand>(
820			n: N,
821			d: D,
822		) -> Result<Self, ArithmeticError> {
823			<Self as FixedPointNumber>::checked_from_rational(n, d)
824				.ok_or_else(|| error::division(&n, &d))
825		}
826
827		/// Ensure multiplication for integer type `N`. Equal to `self * n`.
828		///
829		/// Returns [`ArithmeticError`] if the result does not fit in `N`.
830		///
831		/// Similar to [`FixedPointNumber::checked_mul_int()`] but returning an [`ArithmeticError`]
832		/// error.
833		///
834		/// ```
835		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
836		///
837		/// fn overflow() -> Result<(), ArithmeticError> {
838		///     FixedI64::from(i64::MAX).ensure_mul_int(2)?;
839		///     Ok(())
840		/// }
841		///
842		/// fn underflow() -> Result<(), ArithmeticError> {
843		///     FixedI64::from(i64::MAX).ensure_mul_int(-2)?;
844		///     Ok(())
845		/// }
846		///
847		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
848		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
849		/// ```
850		fn ensure_mul_int<N: FixedPointOperand>(self, n: N) -> Result<N, ArithmeticError> {
851			self.checked_mul_int(n).ok_or_else(|| error::multiplication(&self, &n))
852		}
853
854		/// Ensure division for integer type `N`. Equal to `self / d`.
855		///
856		/// Returns [`ArithmeticError`] if the result does not fit in `N` or `d == 0`.
857		///
858		/// Similar to [`FixedPointNumber::checked_div_int()`] but returning an [`ArithmeticError`]
859		/// error.
860		///
861		/// ```
862		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
863		///
864		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
865		///     FixedI64::from(1).ensure_div_int(0)?;
866		///     Ok(())
867		/// }
868		///
869		/// fn overflow() -> Result<(), ArithmeticError> {
870		///     FixedI64::from(i64::MIN).ensure_div_int(-1)?;
871		///     Ok(())
872		/// }
873		///
874		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
875		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
876		/// ```
877		fn ensure_div_int<D: FixedPointOperand>(self, d: D) -> Result<D, ArithmeticError> {
878			self.checked_div_int(d).ok_or_else(|| error::division(&self, &d))
879		}
880	}
881
882	impl<T: FixedPointNumber> EnsureFixedPointNumber for T {}
883
884	/// Similar to [`TryFrom`] but returning an [`ArithmeticError`] error.
885	pub trait EnsureFrom<T: PartialOrd + Zero>: TryFrom<T> + PartialOrd + Zero {
886		/// Performs the conversion returning an [`ArithmeticError`] if fails.
887		///
888		/// Similar to [`TryFrom::try_from()`] but returning an [`ArithmeticError`] error.
889		///
890		/// ```
891		/// use sp_arithmetic::{traits::EnsureFrom, ArithmeticError};
892		///
893		/// fn overflow() -> Result<(), ArithmeticError> {
894		///     let byte: u8 = u8::ensure_from(256u16)?;
895		///     Ok(())
896		/// }
897		///
898		/// fn underflow() -> Result<(), ArithmeticError> {
899		///     let byte: i8 = i8::ensure_from(-129i16)?;
900		///     Ok(())
901		/// }
902		///
903		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
904		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
905		/// ```
906		fn ensure_from(other: T) -> Result<Self, ArithmeticError> {
907			let err = error::equivalent(&other);
908			Self::try_from(other).map_err(|_| err)
909		}
910	}
911
912	/// Similar to [`TryInto`] but returning an [`ArithmeticError`] error.
913	pub trait EnsureInto<T: PartialOrd + Zero>: TryInto<T> + PartialOrd + Zero {
914		/// Performs the conversion returning an [`ArithmeticError`] if fails.
915		///
916		/// Similar to [`TryInto::try_into()`] but returning an [`ArithmeticError`] error
917		///
918		/// ```
919		/// use sp_arithmetic::{traits::EnsureInto, ArithmeticError};
920		///
921		/// fn overflow() -> Result<(), ArithmeticError> {
922		///     let byte: u8 = 256u16.ensure_into()?;
923		///     Ok(())
924		/// }
925		///
926		/// fn underflow() -> Result<(), ArithmeticError> {
927		///     let byte: i8 = (-129i16).ensure_into()?;
928		///     Ok(())
929		/// }
930		///
931		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
932		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
933		/// ```
934		fn ensure_into(self) -> Result<T, ArithmeticError> {
935			let err = error::equivalent(&self);
936			self.try_into().map_err(|_| err)
937		}
938	}
939
940	impl<T: TryFrom<S> + PartialOrd + Zero, S: PartialOrd + Zero> EnsureFrom<S> for T {}
941	impl<T: TryInto<S> + PartialOrd + Zero, S: PartialOrd + Zero> EnsureInto<S> for T {}
942
943	mod error {
944		use super::{ArithmeticError, Zero};
945
946		#[derive(PartialEq)]
947		enum Signum {
948			Negative,
949			Positive,
950		}
951
952		impl<T: PartialOrd + Zero> From<&T> for Signum {
953			fn from(value: &T) -> Self {
954				if value < &Zero::zero() {
955					Signum::Negative
956				} else {
957					Signum::Positive
958				}
959			}
960		}
961
962		impl core::ops::Mul for Signum {
963			type Output = Self;
964
965			fn mul(self, rhs: Self) -> Self {
966				if self != rhs {
967					Signum::Negative
968				} else {
969					Signum::Positive
970				}
971			}
972		}
973
974		pub fn equivalent<R: PartialOrd + Zero>(r: &R) -> ArithmeticError {
975			match Signum::from(r) {
976				Signum::Negative => ArithmeticError::Underflow,
977				Signum::Positive => ArithmeticError::Overflow,
978			}
979		}
980
981		pub fn inverse<R: PartialOrd + Zero>(r: &R) -> ArithmeticError {
982			match Signum::from(r) {
983				Signum::Negative => ArithmeticError::Overflow,
984				Signum::Positive => ArithmeticError::Underflow,
985			}
986		}
987
988		pub fn multiplication<L: PartialOrd + Zero, R: PartialOrd + Zero>(
989			l: &L,
990			r: &R,
991		) -> ArithmeticError {
992			match Signum::from(l) * Signum::from(r) {
993				Signum::Negative => ArithmeticError::Underflow,
994				Signum::Positive => ArithmeticError::Overflow,
995			}
996		}
997
998		pub fn division<N: PartialOrd + Zero, D: PartialOrd + Zero>(
999			n: &N,
1000			d: &D,
1001		) -> ArithmeticError {
1002			if d.is_zero() {
1003				ArithmeticError::DivisionByZero
1004			} else {
1005				multiplication(n, d)
1006			}
1007		}
1008	}
1009}
1010
1011#[cfg(test)]
1012mod tests {
1013	use super::*;
1014	use crate::ArithmeticError;
1015	use rand::{seq::SliceRandom, thread_rng, Rng};
1016
1017	#[test]
1018	fn ensure_add_works() {
1019		test_ensure(values(), &EnsureAdd::ensure_add, &CheckedAdd::checked_add);
1020	}
1021
1022	#[test]
1023	fn ensure_sub_works() {
1024		test_ensure(values(), &EnsureSub::ensure_sub, &CheckedSub::checked_sub);
1025	}
1026
1027	#[test]
1028	fn ensure_mul_works() {
1029		test_ensure(values(), &EnsureMul::ensure_mul, &CheckedMul::checked_mul);
1030	}
1031
1032	#[test]
1033	fn ensure_div_works() {
1034		test_ensure(values(), &EnsureDiv::ensure_div, &CheckedDiv::checked_div);
1035	}
1036
1037	#[test]
1038	fn ensure_pow_works() {
1039		test_ensure(
1040			values().into_iter().map(|(base, exp)| (base, exp as usize)).collect(),
1041			ensure_pow,
1042			|&a, &b| checked_pow(a, b),
1043		);
1044	}
1045
1046	#[test]
1047	fn ensure_add_assign_works() {
1048		test_ensure_assign(values(), &EnsureAddAssign::ensure_add_assign, &EnsureAdd::ensure_add);
1049	}
1050
1051	#[test]
1052	fn ensure_sub_assign_works() {
1053		test_ensure_assign(values(), &EnsureSubAssign::ensure_sub_assign, &EnsureSub::ensure_sub);
1054	}
1055
1056	#[test]
1057	fn ensure_mul_assign_works() {
1058		test_ensure_assign(values(), &EnsureMulAssign::ensure_mul_assign, &&EnsureMul::ensure_mul);
1059	}
1060
1061	#[test]
1062	fn ensure_div_assign_works() {
1063		test_ensure_assign(values(), &EnsureDivAssign::ensure_div_assign, &EnsureDiv::ensure_div);
1064	}
1065
1066	/// Test that the ensured function returns the expected un-ensured value.
1067	fn test_ensure<V, W, E, P>(pairs: Vec<(V, W)>, ensured: E, unensured: P)
1068	where
1069		V: Ensure + core::fmt::Debug + Copy,
1070		W: Ensure + core::fmt::Debug + Copy,
1071		E: Fn(V, W) -> Result<V, ArithmeticError>,
1072		P: Fn(&V, &W) -> Option<V>,
1073	{
1074		for (a, b) in pairs.into_iter() {
1075			match ensured(a, b) {
1076				Ok(c) => {
1077					assert_eq!(unensured(&a, &b), Some(c))
1078				},
1079				Err(_) => {
1080					assert!(unensured(&a, &b).is_none());
1081				},
1082			}
1083		}
1084	}
1085
1086	/// Test that the ensured function modifies `self` to the expected un-ensured value.
1087	fn test_ensure_assign<V, W, E, P>(pairs: Vec<(V, W)>, ensured: E, unensured: P)
1088	where
1089		V: Ensure + std::panic::RefUnwindSafe + std::panic::UnwindSafe + core::fmt::Debug + Copy,
1090		W: Ensure + std::panic::RefUnwindSafe + std::panic::UnwindSafe + core::fmt::Debug + Copy,
1091		E: Fn(&mut V, W) -> Result<(), ArithmeticError>,
1092		P: Fn(V, W) -> Result<V, ArithmeticError> + std::panic::RefUnwindSafe,
1093	{
1094		for (mut a, b) in pairs.into_iter() {
1095			let old_a = a;
1096
1097			match ensured(&mut a, b) {
1098				Ok(()) => {
1099					assert_eq!(unensured(old_a, b), Ok(a));
1100				},
1101				Err(err) => {
1102					assert_eq!(a, old_a, "A stays unmodified in the error case");
1103					assert_eq!(unensured(old_a, b), Err(err));
1104				},
1105			}
1106		}
1107	}
1108
1109	/// Generates some good values for testing integer arithmetic.
1110	fn values() -> Vec<(i32, i32)> {
1111		let mut rng = thread_rng();
1112		let mut one_dimension = || {
1113			let mut ret = vec![0i32; 1007];
1114			// Some hard-coded interesting values.
1115			ret[..7].copy_from_slice(&[-1, 0, 1, i32::MIN, i32::MAX, i32::MAX - 1, i32::MIN + 1]);
1116			// … and some random ones.
1117			rng.fill(&mut ret[7..]);
1118			ret.shuffle(&mut rng);
1119			ret
1120		};
1121		one_dimension().into_iter().zip(one_dimension().into_iter()).collect()
1122	}
1123}