@@ -14,6 +14,8 @@ use crate::error::DriftResult;
1414
1515pub mod compat {
1616 use bytemuck:: { Pod , Zeroable } ;
17+ use num_traits:: { One , Zero } ;
18+ use std:: cmp:: { Ord , Ordering , PartialOrd } ;
1719 use std:: ops:: { Add , AddAssign , Div , DivAssign , Mul , MulAssign , Sub , SubAssign } ;
1820
1921 /// `u128` with legacy bit layout
@@ -114,6 +116,131 @@ pub mod compat {
114116 }
115117 }
116118
119+ // Comparison traits for u128
120+ impl PartialOrd for u128 {
121+ #[ inline( always) ]
122+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
123+ self . as_u128 ( ) . partial_cmp ( & other. as_u128 ( ) )
124+ }
125+ }
126+
127+ impl Ord for u128 {
128+ #[ inline( always) ]
129+ fn cmp ( & self , other : & Self ) -> Ordering {
130+ self . as_u128 ( ) . cmp ( & other. as_u128 ( ) )
131+ }
132+ }
133+
134+ // Helper methods for u128
135+ impl u128 {
136+ /// Returns the absolute value (no-op for unsigned)
137+ #[ inline( always) ]
138+ pub fn abs ( self ) -> Self {
139+ self
140+ }
141+
142+ /// Returns the signum (1 if > 0, 0 if == 0)
143+ #[ inline( always) ]
144+ pub fn signum ( self ) -> Self {
145+ if self . as_u128 ( ) > 0 {
146+ Self :: ONE
147+ } else {
148+ Self :: ZERO
149+ }
150+ }
151+
152+ /// Returns the minimum of two values
153+ #[ inline( always) ]
154+ pub fn min ( self , other : Self ) -> Self {
155+ if self < other {
156+ self
157+ } else {
158+ other
159+ }
160+ }
161+
162+ /// Returns the maximum of two values
163+ #[ inline( always) ]
164+ pub fn max ( self , other : Self ) -> Self {
165+ if self > other {
166+ self
167+ } else {
168+ other
169+ }
170+ }
171+
172+ /// Saturating addition
173+ #[ inline( always) ]
174+ pub fn saturating_add ( self , other : Self ) -> Self {
175+ Self :: from ( self . as_u128 ( ) . saturating_add ( other. as_u128 ( ) ) )
176+ }
177+
178+ /// Saturating subtraction
179+ #[ inline( always) ]
180+ pub fn saturating_sub ( self , other : Self ) -> Self {
181+ Self :: from ( self . as_u128 ( ) . saturating_sub ( other. as_u128 ( ) ) )
182+ }
183+
184+ /// Saturating multiplication
185+ #[ inline( always) ]
186+ pub fn saturating_mul ( self , other : Self ) -> Self {
187+ Self :: from ( self . as_u128 ( ) . saturating_mul ( other. as_u128 ( ) ) )
188+ }
189+
190+ /// Checked addition
191+ #[ inline( always) ]
192+ pub fn checked_add ( self , other : Self ) -> Option < Self > {
193+ self . as_u128 ( ) . checked_add ( other. as_u128 ( ) ) . map ( Self :: from)
194+ }
195+
196+ /// Checked subtraction
197+ #[ inline( always) ]
198+ pub fn checked_sub ( self , other : Self ) -> Option < Self > {
199+ self . as_u128 ( ) . checked_sub ( other. as_u128 ( ) ) . map ( Self :: from)
200+ }
201+
202+ /// Checked multiplication
203+ #[ inline( always) ]
204+ pub fn checked_mul ( self , other : Self ) -> Option < Self > {
205+ self . as_u128 ( ) . checked_mul ( other. as_u128 ( ) ) . map ( Self :: from)
206+ }
207+
208+ /// Checked division
209+ #[ inline( always) ]
210+ pub fn checked_div ( self , other : Self ) -> Option < Self > {
211+ self . as_u128 ( ) . checked_div ( other. as_u128 ( ) ) . map ( Self :: from)
212+ }
213+
214+ /// Checked remainder
215+ #[ inline( always) ]
216+ pub fn checked_rem ( self , other : Self ) -> Option < Self > {
217+ self . as_u128 ( ) . checked_rem ( other. as_u128 ( ) ) . map ( Self :: from)
218+ }
219+ }
220+
221+ // num_traits implementations for u128
222+ impl Zero for u128 {
223+ fn zero ( ) -> Self {
224+ Self :: ZERO
225+ }
226+
227+ fn is_zero ( & self ) -> bool {
228+ * self == Self :: ZERO
229+ }
230+ }
231+
232+ impl One for u128 {
233+ fn one ( ) -> Self {
234+ Self :: ONE
235+ }
236+ }
237+
238+ impl std:: fmt:: Display for self :: u128 {
239+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
240+ self . as_u128 ( ) . fmt ( f)
241+ }
242+ }
243+
117244 /// `i128` with legacy bit layout
118245 #[ derive( Copy , Clone , PartialEq , Eq , Debug , Default ) ]
119246 #[ repr( transparent) ]
@@ -215,6 +342,133 @@ pub mod compat {
215342 * self = * self / other;
216343 }
217344 }
345+
346+ // Comparison traits for i128
347+ impl PartialOrd for i128 {
348+ #[ inline( always) ]
349+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
350+ self . as_i128 ( ) . partial_cmp ( & other. as_i128 ( ) )
351+ }
352+ }
353+
354+ impl Ord for i128 {
355+ #[ inline( always) ]
356+ fn cmp ( & self , other : & Self ) -> Ordering {
357+ self . as_i128 ( ) . cmp ( & other. as_i128 ( ) )
358+ }
359+ }
360+
361+ // Helper methods for i128
362+ impl i128 {
363+ /// Returns the absolute value
364+ #[ inline( always) ]
365+ pub fn abs ( self ) -> Self {
366+ Self :: from ( self . as_i128 ( ) . abs ( ) )
367+ }
368+
369+ /// Returns the signum (-1, 0, or 1)
370+ #[ inline( always) ]
371+ pub fn signum ( self ) -> Self {
372+ Self :: from ( self . as_i128 ( ) . signum ( ) )
373+ }
374+
375+ /// Returns the absolute value as unsigned
376+ #[ inline( always) ]
377+ pub fn unsigned_abs ( self ) -> u128 {
378+ u128:: from ( self . as_i128 ( ) . unsigned_abs ( ) )
379+ }
380+
381+ /// Returns the minimum of two values
382+ #[ inline( always) ]
383+ pub fn min ( self , other : Self ) -> Self {
384+ if self < other {
385+ self
386+ } else {
387+ other
388+ }
389+ }
390+
391+ /// Returns the maximum of two values
392+ #[ inline( always) ]
393+ pub fn max ( self , other : Self ) -> Self {
394+ if self > other {
395+ self
396+ } else {
397+ other
398+ }
399+ }
400+
401+ /// Saturating addition
402+ #[ inline( always) ]
403+ pub fn saturating_add ( self , other : Self ) -> Self {
404+ Self :: from ( self . as_i128 ( ) . saturating_add ( other. as_i128 ( ) ) )
405+ }
406+
407+ /// Saturating subtraction
408+ #[ inline( always) ]
409+ pub fn saturating_sub ( self , other : Self ) -> Self {
410+ Self :: from ( self . as_i128 ( ) . saturating_sub ( other. as_i128 ( ) ) )
411+ }
412+
413+ /// Saturating multiplication
414+ #[ inline( always) ]
415+ pub fn saturating_mul ( self , other : Self ) -> Self {
416+ Self :: from ( self . as_i128 ( ) . saturating_mul ( other. as_i128 ( ) ) )
417+ }
418+
419+ /// Checked addition
420+ #[ inline( always) ]
421+ pub fn checked_add ( self , other : Self ) -> Option < Self > {
422+ self . as_i128 ( ) . checked_add ( other. as_i128 ( ) ) . map ( Self :: from)
423+ }
424+
425+ /// Checked subtraction
426+ #[ inline( always) ]
427+ pub fn checked_sub ( self , other : Self ) -> Option < Self > {
428+ self . as_i128 ( ) . checked_sub ( other. as_i128 ( ) ) . map ( Self :: from)
429+ }
430+
431+ /// Checked multiplication
432+ #[ inline( always) ]
433+ pub fn checked_mul ( self , other : Self ) -> Option < Self > {
434+ self . as_i128 ( ) . checked_mul ( other. as_i128 ( ) ) . map ( Self :: from)
435+ }
436+
437+ /// Checked division
438+ #[ inline( always) ]
439+ pub fn checked_div ( self , other : Self ) -> Option < Self > {
440+ self . as_i128 ( ) . checked_div ( other. as_i128 ( ) ) . map ( Self :: from)
441+ }
442+
443+ /// Checked remainder
444+ #[ inline( always) ]
445+ pub fn checked_rem ( self , other : Self ) -> Option < Self > {
446+ self . as_i128 ( ) . checked_rem ( other. as_i128 ( ) ) . map ( Self :: from)
447+ }
448+ }
449+
450+ // num_traits implementations for i128
451+ impl Zero for i128 {
452+ fn zero ( ) -> Self {
453+ Self :: ZERO
454+ }
455+
456+ fn is_zero ( & self ) -> bool {
457+ * self == Self :: ZERO
458+ }
459+ }
460+
461+ impl One for i128 {
462+ fn one ( ) -> Self {
463+ Self :: ONE
464+ }
465+ }
466+
467+ impl std:: fmt:: Display for self :: i128 {
468+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
469+ self . as_i128 ( ) . fmt ( f)
470+ }
471+ }
218472}
219473
220474construct_uint ! {
0 commit comments