fixed/
cast.rs

1// Copyright © 2018–2025 Trevor Spiteri
2
3// This library is free software: you can redistribute it and/or
4// modify it under the terms of either
5//
6//   * the Apache License, Version 2.0 or
7//   * the MIT License
8//
9// at your option.
10//
11// You should have recieved copies of the Apache License and the MIT
12// License along with the library. If not, see
13// <https://www.apache.org/licenses/LICENSE-2.0> and
14// <https://opensource.org/licenses/MIT>.
15
16#![allow(deprecated)]
17
18use crate::types::extra::{LeEqU8, LeEqU16, LeEqU32, LeEqU64, LeEqU128};
19use crate::{
20    F128, F128Bits, FixedI8, FixedI16, FixedI32, FixedI64, FixedI128, FixedU8, FixedU16, FixedU32,
21    FixedU64, FixedU128,
22};
23use az::{Cast, CheckedCast, OverflowingCast, SaturatingCast, UnwrappedCast, WrappingCast};
24use half::{bf16 as half_bf16, f16 as half_f16};
25
26macro_rules! cast {
27    ($Src:ident($LeEqUSrc:ident); $Dst:ident($LeEqUDst:ident)) => {
28        impl<FracSrc: $LeEqUSrc, FracDst: $LeEqUDst> Cast<$Dst<FracDst>> for $Src<FracSrc> {
29            #[inline]
30            fn cast(self) -> $Dst<FracDst> {
31                self.to_num()
32            }
33        }
34
35        impl<FracSrc: $LeEqUSrc, FracDst: $LeEqUDst> CheckedCast<$Dst<FracDst>> for $Src<FracSrc> {
36            #[inline]
37            fn checked_cast(self) -> Option<$Dst<FracDst>> {
38                self.checked_to_num()
39            }
40        }
41
42        impl<FracSrc: $LeEqUSrc, FracDst: $LeEqUDst> SaturatingCast<$Dst<FracDst>>
43            for $Src<FracSrc>
44        {
45            #[inline]
46            fn saturating_cast(self) -> $Dst<FracDst> {
47                self.saturating_to_num()
48            }
49        }
50
51        impl<FracSrc: $LeEqUSrc, FracDst: $LeEqUDst> WrappingCast<$Dst<FracDst>> for $Src<FracSrc> {
52            #[inline]
53            fn wrapping_cast(self) -> $Dst<FracDst> {
54                self.wrapping_to_num()
55            }
56        }
57
58        impl<FracSrc: $LeEqUSrc, FracDst: $LeEqUDst> OverflowingCast<$Dst<FracDst>>
59            for $Src<FracSrc>
60        {
61            #[inline]
62            fn overflowing_cast(self) -> ($Dst<FracDst>, bool) {
63                self.overflowing_to_num()
64            }
65        }
66
67        impl<FracSrc: $LeEqUSrc, FracDst: $LeEqUDst> UnwrappedCast<$Dst<FracDst>>
68            for $Src<FracSrc>
69        {
70            #[inline]
71            #[track_caller]
72            fn unwrapped_cast(self) -> $Dst<FracDst> {
73                self.unwrapped_to_num()
74            }
75        }
76    };
77
78    ($Fixed:ident($LeEqU:ident); $Dst:ident) => {
79        impl<Frac: $LeEqU> Cast<$Dst> for $Fixed<Frac> {
80            #[inline]
81            fn cast(self) -> $Dst {
82                self.to_num()
83            }
84        }
85
86        impl<Frac: $LeEqU> CheckedCast<$Dst> for $Fixed<Frac> {
87            #[inline]
88            fn checked_cast(self) -> Option<$Dst> {
89                self.checked_to_num()
90            }
91        }
92
93        impl<Frac: $LeEqU> SaturatingCast<$Dst> for $Fixed<Frac> {
94            #[inline]
95            fn saturating_cast(self) -> $Dst {
96                self.saturating_to_num()
97            }
98        }
99
100        impl<Frac: $LeEqU> WrappingCast<$Dst> for $Fixed<Frac> {
101            #[inline]
102            fn wrapping_cast(self) -> $Dst {
103                self.wrapping_to_num()
104            }
105        }
106
107        impl<Frac: $LeEqU> OverflowingCast<$Dst> for $Fixed<Frac> {
108            #[inline]
109            fn overflowing_cast(self) -> ($Dst, bool) {
110                self.overflowing_to_num()
111            }
112        }
113
114        impl<Frac: $LeEqU> UnwrappedCast<$Dst> for $Fixed<Frac> {
115            #[inline]
116            #[track_caller]
117            fn unwrapped_cast(self) -> $Dst {
118                self.unwrapped_to_num()
119            }
120        }
121    };
122
123    ($Src:ident; $Fixed:ident($LeEqU:ident)) => {
124        impl<Frac: $LeEqU> Cast<$Fixed<Frac>> for $Src {
125            #[inline]
126            fn cast(self) -> $Fixed<Frac> {
127                <$Fixed<Frac>>::from_num(self)
128            }
129        }
130
131        impl<Frac: $LeEqU> CheckedCast<$Fixed<Frac>> for $Src {
132            #[inline]
133            fn checked_cast(self) -> Option<$Fixed<Frac>> {
134                <$Fixed<Frac>>::checked_from_num(self)
135            }
136        }
137
138        impl<Frac: $LeEqU> SaturatingCast<$Fixed<Frac>> for $Src {
139            #[inline]
140            fn saturating_cast(self) -> $Fixed<Frac> {
141                <$Fixed<Frac>>::saturating_from_num(self)
142            }
143        }
144
145        impl<Frac: $LeEqU> WrappingCast<$Fixed<Frac>> for $Src {
146            #[inline]
147            fn wrapping_cast(self) -> $Fixed<Frac> {
148                <$Fixed<Frac>>::wrapping_from_num(self)
149            }
150        }
151
152        impl<Frac: $LeEqU> OverflowingCast<$Fixed<Frac>> for $Src {
153            #[inline]
154            fn overflowing_cast(self) -> ($Fixed<Frac>, bool) {
155                <$Fixed<Frac>>::overflowing_from_num(self)
156            }
157        }
158
159        impl<Frac: $LeEqU> UnwrappedCast<$Fixed<Frac>> for $Src {
160            #[inline]
161            #[track_caller]
162            fn unwrapped_cast(self) -> $Fixed<Frac> {
163                <$Fixed<Frac>>::unwrapped_from_num(self)
164            }
165        }
166    };
167}
168
169macro_rules! cast_num {
170    ($Src:ident($LeEqUSrc:ident); $($Dst:ident($LeEqUDst:ident),)*) => { $(
171        cast! { $Src($LeEqUSrc); $Dst($LeEqUDst) }
172    )* };
173    ($Fixed:ident($LeEqU:ident); $($Num:ident,)*) => { $(
174        cast! { $Fixed($LeEqU); $Num }
175        cast! { $Num; $Fixed($LeEqU) }
176    )* };
177    ($($Fixed:ident($LeEqU:ident),)*) => { $(
178        cast_num! {
179            $Fixed($LeEqU);
180            FixedI8(LeEqU8), FixedI16(LeEqU16), FixedI32(LeEqU32), FixedI64(LeEqU64),
181            FixedI128(LeEqU128),
182            FixedU8(LeEqU8), FixedU16(LeEqU16), FixedU32(LeEqU32), FixedU64(LeEqU64),
183            FixedU128(LeEqU128),
184        }
185        cast! { bool; $Fixed($LeEqU) }
186        cast_num! {
187            $Fixed($LeEqU);
188            i8, i16, i32, i64, i128, isize,
189            u8, u16, u32, u64, u128, usize,
190            half_f16, half_bf16, f32, f64, F128, F128Bits,
191        }
192        #[cfg(feature = "nightly-float")]
193        cast_num! { $Fixed($LeEqU); f16, f128, }
194    )* };
195}
196
197cast_num! {
198    FixedI8(LeEqU8), FixedI16(LeEqU16), FixedI32(LeEqU32), FixedI64(LeEqU64), FixedI128(LeEqU128),
199    FixedU8(LeEqU8), FixedU16(LeEqU16), FixedU32(LeEqU32), FixedU64(LeEqU64), FixedU128(LeEqU128),
200}