mirror of
				https://gitlab.com/artofrev/smallint.git
				synced 2025-10-31 15:01:11 -04:00 
			
		
		
		
	refactor logic.rs and optimize ...Assign impls (&* instead of clone)
This commit is contained in:
		
							parent
							
								
									1fe105f58c
								
							
						
					
					
						commit
						45a3975d31
					
				
							
								
								
									
										272
									
								
								src/logic.rs
									
									
									
									
									
								
							
							
						
						
									
										272
									
								
								src/logic.rs
									
									
									
									
									
								
							| @ -40,201 +40,123 @@ macro_rules! basic_op { | |||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn bitand(a: &SmallUint, b: &SmallUint) -> SmallUint { | macro_rules! logic_op { | ||||||
|     match (&a.0, &b.0) { |     ( | ||||||
|         (&SmallUintType::Inline(i), &SmallUintType::Inline(j)) => { |         $imp:ident, $imp_assign:ident, $typ:ident, $typ_inner:ident, $fun:ident, $fun_assign:ident; | ||||||
|             SmallUint(SmallUintType::Inline(i & j)) |         $i:ident, $j:ident, $r:ident, $s:ident, $slice:ident, $slice1:ident, $slice2:ident, $res:ident; | ||||||
|         } |         $inline_heap:tt, $heap_heap:tt | ||||||
| 
 |     ) => { | ||||||
|         (&SmallUintType::Inline(i), &SmallUintType::Heap((r, s))) |         fn $fun(a: &$typ, b: &$typ) -> $typ { | ||||||
|         | (&SmallUintType::Heap((r, s)), &SmallUintType::Inline(i)) => { |             match (&a.0, &b.0) { | ||||||
|             let slice = unsafe { core::slice::from_raw_parts(r, s) }; |                 (&$typ_inner::Inline($i), &$typ_inner::Inline($j)) => { | ||||||
|             let mut j = 0u128; |                     $typ($typ_inner::Inline($i.$fun($j))) | ||||||
|             for i in 0..4 { |  | ||||||
|                 j <<= 32; |  | ||||||
| 
 |  | ||||||
|                 j |= slice[3 - i] as u128; |  | ||||||
|             } |  | ||||||
|             SmallUint(SmallUintType::Inline(i & j)) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         (&SmallUintType::Heap((r, s)), &SmallUintType::Heap((i, j))) => { |  | ||||||
|             let slice1 = unsafe { core::slice::from_raw_parts(r, s) }; |  | ||||||
|             let slice2 = unsafe { core::slice::from_raw_parts(i, j) }; |  | ||||||
| 
 |  | ||||||
|             let min = std::cmp::min(slice1.len(), slice2.len()); |  | ||||||
| 
 |  | ||||||
|             let mut res = Vec::with_capacity(min); |  | ||||||
| 
 |  | ||||||
|             for l in 0..min { |  | ||||||
|                 res.push(slice1[l] & slice2[l]); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             while res.len() != 1 && res[res.len() - 1] == 0 { |  | ||||||
|                 res.pop(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if res.len() <= 4 { |  | ||||||
|                 let mut r = 0u128; |  | ||||||
|                 for t in 0..res.len() { |  | ||||||
|                     r <<= 32; |  | ||||||
|                     r |= res[res.len() - 1 - t] as u128; |  | ||||||
|                 } |                 } | ||||||
|                 SmallUint(SmallUintType::Inline(r)) | 
 | ||||||
|             } else { |                 (&$typ_inner::Inline($i), &$typ_inner::Heap(($r, $s))) | ||||||
|                 let mut slice = ManuallyDrop::new(res.into_boxed_slice()); |                 | (&$typ_inner::Heap(($r, $s)), &$typ_inner::Inline($i)) => { | ||||||
|                 SmallUint(SmallUintType::Heap((slice.as_mut_ptr(), slice.len()))) |                     let $slice = unsafe { core::slice::from_raw_parts($r, $s) }; | ||||||
|  | 
 | ||||||
|  |                     $inline_heap | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 (&$typ_inner::Heap(($r, $s)), &$typ_inner::Heap(($i, $j))) => { | ||||||
|  |                     let $slice1 = unsafe { core::slice::from_raw_parts($r, $s) }; | ||||||
|  |                     let $slice2 = unsafe { core::slice::from_raw_parts($i, $j) }; | ||||||
|  | 
 | ||||||
|  |                     let min = std::cmp::min($slice1.len(), $slice2.len()); | ||||||
|  | 
 | ||||||
|  |                     let mut $res = Vec::with_capacity(min); | ||||||
|  | 
 | ||||||
|  |                     for l in 0..min { | ||||||
|  |                         $res.push($slice1[l] & $slice2[l]); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     $heap_heap | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         basic_op!($imp, $typ, $fun); | ||||||
|  | 
 | ||||||
|  |         impl<'a> $imp_assign<&'a SmallUint> for $typ { | ||||||
|  |             fn $fun_assign(&mut self, rhs: &'a $typ) { | ||||||
|  |                 *self = (&*self).$fun(rhs); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         impl $imp_assign<$typ> for $typ { | ||||||
|  |             fn $fun_assign(&mut self, rhs: $typ) { | ||||||
|  |                 *self = (&*self).$fun(rhs); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| basic_op!(BitAnd, SmallUint, bitand); | macro_rules! inline_heap_to_heap { | ||||||
|  |     ($op_assign:tt, $i:ident, $slice:ident) => { | ||||||
|  |         let mut retvec = $slice.to_vec(); | ||||||
| 
 | 
 | ||||||
| impl<'a> BitAndAssign<&'a SmallUint> for SmallUint { |         let mut v = $i; | ||||||
|     fn bitand_assign(&mut self, rhs: &'a SmallUint) { |         #[allow(clippy::needless_range_loop)] | ||||||
|         *self = self.clone() & rhs; |         for r in 0..4 { | ||||||
|  |             retvec[r] $op_assign v as u32; | ||||||
|  | 
 | ||||||
|  |             v >>= 32; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let mut retslice = ManuallyDrop::new(retvec.into_boxed_slice()); | ||||||
|  | 
 | ||||||
|  |         SmallUint(SmallUintType::Heap((retslice.as_mut_ptr(), retslice.len()))) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl BitAndAssign<SmallUint> for SmallUint { | macro_rules! heap_heap_to_any { | ||||||
|     fn bitand_assign(&mut self, rhs: SmallUint) { |     ($res:ident) => { | ||||||
|         *self = self.clone() & rhs; |         while $res.len() != 1 && $res[$res.len() - 1] == 0 { | ||||||
|     } |             $res.pop(); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn bitor(a: &SmallUint, b: &SmallUint) -> SmallUint { |  | ||||||
|     match (&a.0, &b.0) { |  | ||||||
|         (&SmallUintType::Inline(i), &SmallUintType::Inline(j)) => { |  | ||||||
|             SmallUint(SmallUintType::Inline(i | j)) |  | ||||||
|         } |  | ||||||
|         (&SmallUintType::Inline(i), &SmallUintType::Heap((r, s))) |  | ||||||
|         | (&SmallUintType::Heap((r, s)), &SmallUintType::Inline(i)) => { |  | ||||||
|             let slice = unsafe { core::slice::from_raw_parts(r, s) }; |  | ||||||
| 
 |  | ||||||
|             let mut retvec = slice.to_vec(); |  | ||||||
| 
 |  | ||||||
|             let mut v = i; |  | ||||||
|             #[allow(clippy::needless_range_loop)] |  | ||||||
|             for r in 0..4 { |  | ||||||
|                 retvec[r] |= v as u32; |  | ||||||
| 
 |  | ||||||
|                 v >>= 32; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             let mut retslice = ManuallyDrop::new(retvec.into_boxed_slice()); |  | ||||||
| 
 |  | ||||||
|             SmallUint(SmallUintType::Heap((retslice.as_mut_ptr(), retslice.len()))) |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         (&SmallUintType::Heap((r, s)), &SmallUintType::Heap((i, j))) => { |         if $res.len() <= 4 { | ||||||
|             let slice1 = unsafe { core::slice::from_raw_parts(r, s) }; |             let mut r = 0u128; | ||||||
|             let slice2 = unsafe { core::slice::from_raw_parts(i, j) }; |             for t in 0..$res.len() { | ||||||
| 
 |                 r <<= 32; | ||||||
|             let m = std::cmp::min(slice1.len(), slice2.len()); |                 r |= $res[$res.len() - 1 - t] as u128; | ||||||
| 
 |  | ||||||
|             let mut retvec; |  | ||||||
|             if slice1.len() > slice2.len() { |  | ||||||
|                 retvec = slice1.to_vec(); |  | ||||||
|             } else { |  | ||||||
|                 retvec = slice2.to_vec(); |  | ||||||
|             } |             } | ||||||
| 
 |             SmallUint(SmallUintType::Inline(r)) | ||||||
|             for t in 0..m { |         } else { | ||||||
|                 retvec[t] = slice1[t] | slice2[t]; |             let mut slice = ManuallyDrop::new($res.into_boxed_slice()); | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             let mut slice = ManuallyDrop::new(retvec.into_boxed_slice()); |  | ||||||
| 
 |  | ||||||
|             SmallUint(SmallUintType::Heap((slice.as_mut_ptr(), slice.len()))) |             SmallUint(SmallUintType::Heap((slice.as_mut_ptr(), slice.len()))) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| basic_op!(BitOr, SmallUint, bitor); | logic_op! { | ||||||
|  |     BitAnd, BitAndAssign, SmallUint, SmallUintType, bitand, bitand_assign; | ||||||
|  |     i, j, r, s, slice, slice1, slice2, res; | ||||||
|  |     { | ||||||
|  |         let mut j = 0u128; | ||||||
|  |             for i in 0..4 { | ||||||
|  |                 j <<= 32; | ||||||
|  |                 j |= slice[3 - i] as u128; | ||||||
|  |             } | ||||||
|  |             SmallUint(SmallUintType::Inline(i & j)) | ||||||
|  |     }, | ||||||
|  |     { heap_heap_to_any! { res } } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| impl<'a> BitOrAssign<&'a SmallUint> for SmallUint { | logic_op! { | ||||||
|     fn bitor_assign(&mut self, rhs: &'a SmallUint) { |     BitOr, BitOrAssign, SmallUint, SmallUintType, bitor, bitor_assign; | ||||||
|         *self = self.clone() | rhs; |     i, j, r, s, slice, slice1, slice2, res; | ||||||
|  |     { inline_heap_to_heap! { |=, i, slice } }, | ||||||
|  |     { | ||||||
|  |         let mut slice = ManuallyDrop::new(res.into_boxed_slice()); | ||||||
|  |         SmallUint(SmallUintType::Heap((slice.as_mut_ptr(), slice.len()))) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl BitOrAssign<SmallUint> for SmallUint { | logic_op! { | ||||||
|     fn bitor_assign(&mut self, rhs: SmallUint) { |     BitXor, BitXorAssign, SmallUint, SmallUintType, bitxor, bitxor_assign; | ||||||
|         *self = self.clone() | rhs; |     i, j, r, s, slice, slice1, slice2, res; | ||||||
|     } |     { inline_heap_to_heap! { |=, i, slice } }, | ||||||
| } |     { heap_heap_to_any! { res } } | ||||||
| 
 |  | ||||||
| fn bitxor(a: &SmallUint, b: &SmallUint) -> SmallUint { |  | ||||||
|     match (&a.0, &b.0) { |  | ||||||
|         (&SmallUintType::Inline(i), &SmallUintType::Inline(j)) => { |  | ||||||
|             SmallUint(SmallUintType::Inline(i ^ j)) |  | ||||||
|         } |  | ||||||
|         (&SmallUintType::Inline(i), &SmallUintType::Heap((r, s))) |  | ||||||
|         | (&SmallUintType::Heap((r, s)), &SmallUintType::Inline(i)) => { |  | ||||||
|             let slice = unsafe { core::slice::from_raw_parts(r, s) }; |  | ||||||
| 
 |  | ||||||
|             let mut retvec = slice.to_vec(); |  | ||||||
| 
 |  | ||||||
|             let mut v = i; |  | ||||||
|             #[allow(clippy::needless_range_loop)] |  | ||||||
|             for r in 0..4 { |  | ||||||
|                 retvec[r] ^= v as u32; |  | ||||||
| 
 |  | ||||||
|                 v >>= 32; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             let mut retslice = ManuallyDrop::new(retvec.into_boxed_slice()); |  | ||||||
| 
 |  | ||||||
|             SmallUint(SmallUintType::Heap((retslice.as_mut_ptr(), retslice.len()))) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         (&SmallUintType::Heap((r, s)), &SmallUintType::Heap((i, j))) => { |  | ||||||
|             let slice1 = unsafe { core::slice::from_raw_parts(r, s) }; |  | ||||||
|             let slice2 = unsafe { core::slice::from_raw_parts(i, j) }; |  | ||||||
| 
 |  | ||||||
|             let m = std::cmp::min(slice1.len(), slice2.len()); |  | ||||||
| 
 |  | ||||||
|             let mut res; |  | ||||||
|             if slice1.len() > slice2.len() { |  | ||||||
|                 res = slice1.to_vec(); |  | ||||||
|             } else { |  | ||||||
|                 res = slice2.to_vec(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             for t in 0..m { |  | ||||||
|                 res[t] = slice1[t] ^ slice2[t]; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             while res.len() != 1 && res[res.len() - 1] == 0 { |  | ||||||
|                 res.pop(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if res.len() <= 4 { |  | ||||||
|                 let mut r = 0u128; |  | ||||||
|                 for t in 0..res.len() { |  | ||||||
|                     r <<= 32; |  | ||||||
|                     r |= res[res.len() - 1 - t] as u128; |  | ||||||
|                 } |  | ||||||
|                 SmallUint(SmallUintType::Inline(r)) |  | ||||||
|             } else { |  | ||||||
|                 let mut slice = ManuallyDrop::new(res.into_boxed_slice()); |  | ||||||
|                 SmallUint(SmallUintType::Heap((slice.as_mut_ptr(), slice.len()))) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| basic_op!(BitXor, SmallUint, bitxor); |  | ||||||
| 
 |  | ||||||
| impl<'a> BitXorAssign<&'a SmallUint> for SmallUint { |  | ||||||
|     fn bitxor_assign(&mut self, rhs: &'a SmallUint) { |  | ||||||
|         *self = self.clone() ^ rhs; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl BitXorAssign<SmallUint> for SmallUint { |  | ||||||
|     fn bitxor_assign(&mut self, rhs: SmallUint) { |  | ||||||
|         *self = self.clone() ^ rhs; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user