From 415be69ba8ffc645fe4247b599d8ba478c89b8e1 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Wed, 7 Aug 2024 12:03:25 -0700
Subject: [PATCH] zeroes: use arrayvec for our stack allocated variable length
 array with a fixed capacity

---
 Cargo.lock    |  7 +++++
 Cargo.toml    |  1 +
 src/zeroes.rs | 73 +++++++++------------------------------------------
 3 files changed, 20 insertions(+), 61 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9e6f1d1..c6d8d3b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,12 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "arrayvec"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
+
 [[package]]
 name = "bitflags"
 version = "2.6.0"
@@ -47,6 +53,7 @@ dependencies = [
 name = "strafesnet_common"
 version = "0.2.3"
 dependencies = [
+ "arrayvec",
  "bitflags",
  "glam",
  "id",
diff --git a/Cargo.toml b/Cargo.toml
index 79f8ecf..1fdc1f2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,6 +10,7 @@ authors = ["Rhys Lloyd <krakow20@gmail.com>"]
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+arrayvec = "0.7.4"
 bitflags = "2.6.0"
 glam = "0.28.0"
 id = { version = "0.1.0", registry = "strafesnet" }
diff --git a/src/zeroes.rs b/src/zeroes.rs
index 8414ab9..8ace8dc 100644
--- a/src/zeroes.rs
+++ b/src/zeroes.rs
@@ -1,64 +1,15 @@
 //find roots of polynomials
+use arrayvec::ArrayVec;
 use crate::integer::Planar64;
 
-pub enum Zeroes{
-	Two([Planar64;2]),
-	One([Planar64;1]),
-	Zero,
-}
-impl Zeroes{
-	pub fn len(&self)->usize{
-		match self{
-			Zeroes::Two(z)=>z.len(),
-			Zeroes::One(z)=>z.len(),
-			Zeroes::Zero=>0,
-		}
-	}
-}
-impl From<[Planar64;0]> for Zeroes{
-	fn from(_value:[Planar64;0])->Self{
-		Zeroes::Zero
-	}
-}
-impl From<[Planar64;1]> for Zeroes{
-	fn from(value:[Planar64;1])->Self{
-		Zeroes::One(value)
-	}
-}
-impl From<[Planar64;2]> for Zeroes{
-	fn from(value:[Planar64;2])->Self{
-		Zeroes::Two(value)
-	}
-}
-pub struct ZeroesIter{
-	zeroes:Zeroes,
-	index:usize,
-}
-impl Iterator for ZeroesIter{
-	type Item=Planar64;
-	fn next(&mut self)->Option<Self::Item>{
-		let ret=match self.zeroes{
-			Zeroes::Two(z)=>z.get(self.index).copied(),
-			Zeroes::One(z)=>z.get(self.index).copied(),
-			Zeroes::Zero=>None,
-		};
-		self.index+=1;
-		ret
-	}
-}
-impl IntoIterator for Zeroes{
-	type Item=Planar64;
-	type IntoIter=ZeroesIter;
-	fn into_iter(self)->Self::IntoIter{
-		ZeroesIter{
-			zeroes:self,
-			index:0,
-		}
-	}
+fn one(z0:Planar64)->ArrayVec<Planar64,2>{
+	let mut zeroes=ArrayVec::new();
+	unsafe{zeroes.push_unchecked(z0)}
+	zeroes
 }
 
 #[inline]
-pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64)->Zeroes{
+pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64)->ArrayVec<Planar64,2>{
 	if a2==Planar64::ZERO{
 		return zeroes1(a0,a1);
 	}
@@ -76,21 +27,21 @@ pub fn zeroes2(a0:Planar64,a1:Planar64,a2:Planar64)->Zeroes{
 			(false,false)=>[(-a1+planar_radicand)/(a2*2),(a0*2)/(-a1+planar_radicand)].into(),
 		}
 	}else if radicand==0{
-		return [a1/(a2*-2)].into();
+		return one(a1/(a2*-2));
 	}else{
-		return [].into();
+		return ArrayVec::new_const();
 	}
 }
 #[inline]
-pub fn zeroes1(a0:Planar64,a1:Planar64)->Zeroes{
+pub fn zeroes1(a0:Planar64,a1:Planar64)->ArrayVec<Planar64,2>{
 	if a1==Planar64::ZERO{
-		return [].into();
+		return ArrayVec::new_const();
 	}else{
 		let q=((-a0.get() as i128)<<32)/(a1.get() as i128);
 		if i64::MIN as i128<=q&&q<=i64::MAX as i128{
-			return [Planar64::raw(q as i64)].into();
+			return one(Planar64::raw(q as i64));
 		}else{
-			return [].into();
+			return ArrayVec::new_const();
 		}
 	}
 }