vec_x/
vec_x.rs

1use std::cmp::Ordering;
2use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
3
4use num::Num;
5use num::traits::AsPrimitive;
6
7/// A structure representing a fixed-length array of arbitrary elements and arbitrary length.
8/// Since it was created primarily to represent mathematical vectors and colors, it supports four arithmetic operations.
9///
10/// 任意の要素、任意の長さの固定長配列を表す構造体です。
11/// 主に数学的なベクトルや色を表すために作成したため、四則演算をサポートしています。
12///
13/// ```
14/// use vec_x::{VecX};
15///
16/// let vec1 = VecX::new([1, 2, 3]);
17/// let vec2 = VecX::new([4, 5, 6]);
18///
19/// // Add
20/// assert_eq!(vec1 + vec2, VecX::new([5, 7, 9]));
21/// // Sub
22/// assert_eq!(vec1 - vec2, VecX::new([-3, -3, -3]));
23/// // Mul
24/// assert_eq!(vec1 * vec2, VecX::new([4, 10, 18]));
25/// // Div
26/// assert_eq!(vec1 / vec2, VecX::new([0, 0, 0]));
27/// // Rem
28/// assert_eq!(vec1 % vec2, VecX::new([1, 2, 3]));
29///
30/// // AddAssign
31/// let mut vec = VecX::new([1, 2, 3]);
32/// vec += VecX::new([4, 5, 6]);
33/// assert_eq!(vec, VecX::new([5, 7, 9]));
34/// // SubAssign
35/// let mut vec = VecX::new([1, 2, 3]);
36/// vec -= VecX::new([4, 5, 6]);
37/// assert_eq!(vec, VecX::new([-3, -3, -3]));
38/// // MulAssign
39/// let mut vec = VecX::new([1, 2, 3]);
40/// vec *= VecX::new([4, 5, 6]);
41/// assert_eq!(vec, VecX::new([4, 10, 18]));
42/// // DivAssign
43/// let mut vec = VecX::new([1, 2, 3]);
44/// vec /= VecX::new([4, 5, 6]);
45/// assert_eq!(vec, VecX::new([0, 0, 0]));
46/// // RemAssign
47/// let mut vec = VecX::new([1, 2, 3]);
48/// vec %= VecX::new([4, 5, 6]);
49/// assert_eq!(vec, VecX::new([1, 2, 3]));
50/// ```
51///
52/// You can also perform arithmetic operations with numeric values.
53///
54/// 数値型の値との演算も可能です。
55///
56/// ```
57/// use vec_x::{VecX};
58///
59/// let vec = VecX::new([1, 2, 3]);
60///
61/// // Add
62/// assert_eq!(vec + 1, VecX::new([2, 3, 4]));
63///
64/// // Sub
65/// assert_eq!(vec - 1, VecX::new([0, 1, 2]));
66///
67/// // Mul
68/// assert_eq!(vec * 2, VecX::new([2, 4, 6]));
69///
70/// // Div
71/// assert_eq!(vec / 2, VecX::new([0, 1, 1]));
72///
73/// // Rem
74/// assert_eq!(vec % 2, VecX::new([1, 0, 1]));
75///
76/// // AddAssign
77/// let mut vec = VecX::new([1, 2, 3]);
78/// vec += 1;
79/// assert_eq!(vec, VecX::new([2, 3, 4]));
80///
81/// // SubAssign
82/// let mut vec = VecX::new([1, 2, 3]);
83/// vec -= 1;
84/// assert_eq!(vec, VecX::new([0, 1, 2]));
85///
86/// // MulAssign
87/// let mut vec = VecX::new([1, 2, 3]);
88/// vec *= 2;
89/// assert_eq!(vec, VecX::new([2, 4, 6]));
90///
91/// // DivAssign
92/// let mut vec = VecX::new([1, 2, 3]);
93/// vec /= 2;
94/// assert_eq!(vec, VecX::new([0, 1, 1]));
95///
96/// // RemAssign
97/// let mut vec = VecX::new([1, 2, 3]);
98/// vec %= 2;
99/// assert_eq!(vec, VecX::new([1, 0, 1]));
100/// ```
101///
102/// In operations, arrays that implement From/Into traits are implicitly converted to the left-hand side type.
103///
104/// 演算において、From/Intoトレイトが実装されている配列同士は暗黙的に左辺の型に変換されます。
105///
106/// ```
107/// use vec_x::{VecX};
108/// use std::ops::Add;
109///
110/// let vec1:VecX<f32,3> = VecX::new([1., 2., 3.]);
111/// let vec2:VecX<u8,3> = VecX::new([4, 5, 6]);
112///
113/// let vec3 = vec1 + vec2;
114/// ```
115/// Arrays that do not implement From/Into trait will fail to compile together.
116/// Thus, there is no loss of precision due to implicit type conversion.
117///
118/// From/Intoトレイトが実装されていない配列同士はコンパイルエラーになります。
119/// よって、暗黙的な型変換によって精度が失われることはありません。
120///
121/// ```compile_fail
122/// use vec_x::{VecX};
123/// use std::ops::Add;
124///
125/// let vec1:VecX<f32,3> = VecX::new([1., 2., 3.]);
126/// let vec2:VecX<u8,3> = VecX::new([4, 5, 6]);
127///
128/// let vec3 = vec2 + vec1; // compile error! Cannot add `VecX<f32, 3>` to `VecX<u8, 3>`[E0369]
129/// ```
130///
131/// Element casts are also supported.
132///
133/// 要素のキャストにも対応しています。
134///
135/// ```
136/// use vec_x::{VecX};
137///
138/// let vec = VecX::new([1, 2, 3]);
139///
140/// let vec_f64:VecX<f64,3> = vec.as_();
141/// ```
142///
143///
144/// Non-numeric elements can also be array elements.
145///
146/// 数値以外を配列要素にすることもできます。
147///
148/// ```
149/// use vec_x::{VecX};
150///
151/// let vec1 = VecX::new(["a", "b", "c"]);
152/// ```
153///
154/// ```compile_fail
155/// use vec_x::{VecX};
156///
157///
158/// let vec1 = VecX::new(["a", "b", "c"]);
159/// let vec2 = VecX::new(["d", "e", "f"]);
160///
161/// vec1 + vec2; // compile error!
162/// ```
163///
164/// Using type aliases, as shown below, improves code readability.
165///
166/// 以下のように型エイリアスを使用することで、コードの可読性が向上します。
167///
168/// ```
169/// use vec_x::{VecX};
170///
171/// type XYZ = VecX<f64, 3>;
172/// type RGBA = VecX<u8, 4>;
173///
174/// struct Point {
175///    position: XYZ,
176///    color: RGBA,
177/// }
178///
179/// let point = Point {
180///    position: XYZ::new([1.0, 2.0, 3.0]),
181///    color: RGBA::new([255, 0, 0, 255]),
182/// };
183/// ```
184#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
185pub struct VecX<T, const N: usize>
186where
187    T: Sized + Send,
188{
189    pub data: [T; N],
190}
191
192impl<T, const N: usize> Default for VecX<T, N>
193where
194    T: Default + Copy + Sized + Send,
195{
196    fn default() -> Self {
197        Self { data: [T::default(); N] }
198    }
199}
200
201impl<T, const N: usize> VecX<T, N>
202where
203    T: Default + Copy + Sized + Send,
204{
205    /// Generate a new `VecX`.
206    ///
207    /// 新しい `VecX` を生成する。
208    ///
209    /// # Examples
210    ///
211    /// ```
212    /// use vec_x::{VecX};
213    ///
214    /// let vec = VecX::new([1, 2, 3]);
215    /// ```
216    pub fn new(data: [T; N]) -> Self {
217        Self { data }
218    }
219
220    /// Generate a `VecX` initialized with a single value.
221    ///
222    /// 単一の値で初期化された `VecX` を生成する。
223    ///
224    /// # Deprecated
225    ///
226    /// This method is deprecated. Use `VecX::from()` instead.
227    ///
228    /// 互換性のために残されていますが、`VecX::from()`を使用してください。
229    ///
230    /// # Examples
231    ///
232    /// ```
233    /// use vec_x::{VecX};
234    ///
235    /// let vec = VecX::new_with(1);
236    ///
237    /// assert_eq!(vec, VecX::new([1, 1, 1]));
238    /// ```
239    #[deprecated]
240    pub fn new_with(value: T) -> Self
241    where
242        T: Copy,
243    {
244        Self { data: [value; N] }
245    }
246
247
248    /// Convert `VecX<T, N>` to `VecX<U, N>`.
249    ///
250    /// `VecX<T, N>`を`VecX<U, N>`に変換する。
251    ///
252    /// # Examples
253    ///
254    /// ```
255    /// use vec_x::{VecX};
256    ///
257    /// let vec:VecX<u8,3> = VecX::new([1, 2, 3]);
258    /// let vec_f64:VecX<f64,3> = vec.into();
259    /// ```
260    pub fn into<U>(self) -> VecX<U, N>
261    where
262        T: Into<U>,
263        U: Sized + Send,
264    {
265        let data: [U; N] = self.data.map(|v| v.into());
266        VecX { data }
267    }
268
269
270    /// Cast `VecX<T, N>` to `VecX<U, N>`.
271    /// Array elements are cast in the same way as numeric types.
272    ///
273    /// `VecX<T, N>`を`VecX<U, N>`にキャストする。
274    /// 配列の要素は数値型と同じ方法でキャストされる。
275    ///
276    /// # Examples
277    ///
278    /// ```
279    /// use vec_x::{VecX};
280    ///
281    /// let vec = VecX::new([1, 2, 3]);
282    ///
283    /// let vec_f64:VecX<f64,3> = vec.as_();
284    /// ```
285    pub fn as_<U>(&self) -> VecX<U, N>
286    where
287        U: AsPrimitive<T> + Sized + Send,
288        T: AsPrimitive<U>,
289    {
290        let data: [U; N] = self.data.map(|v| v.as_());
291        VecX { data }
292    }
293
294    /// Match the number of elements in `VecX<T, N>` to M.
295    /// If `M > T`, empty elements are filled with the value of `T::default()`.
296    ///
297    /// `VecX<T, N>`の要素数をMに合わせる。
298    /// `M > T`である場合、空の要素は`T::default()`の値で満たされる。
299    ///
300    /// # Examples
301    ///
302    /// ```
303    /// use vec_x::{VecX};
304    ///
305    /// let vec = VecX::new([1, 2, 3]);
306    /// assert_eq!(vec.fit::<2>(), VecX::new([1, 2]));
307    ///
308    /// let vec = VecX::new([1, 2, 3]);
309    /// assert_eq!(vec.fit::<5>(), VecX::new([1, 2, 3, 0, 0]));
310    /// ```
311    pub fn fit<const M: usize>(&self) -> VecX<T, M>
312    where
313        T: Default + Copy,
314    {
315        let mut data = [T::default(); M];
316
317        (0..N.min(M)).for_each(|i| data[i] = self.data[i]);
318
319        VecX { data }
320    }
321
322    /// Apply a function to each element of `VecX<T, N>`.
323    ///
324    /// `VecX<T, N>`の各要素に関数を適用する。
325    ///
326    /// # Examples
327    ///
328    /// ```
329    /// use vec_x::{VecX};
330    ///
331    /// let do_something = |v:u32| v.abs_diff(1);
332    ///
333    /// let vec = VecX::new([1, 2, 3]);
334    ///
335    /// assert_eq!(vec.batch(do_something), VecX::new([0, 1, 2]));
336    /// ```
337    pub fn batch<U, F>(self, callback: F) -> VecX<U, N>
338    where
339        U: Sized + Send,
340        F: Fn(T) -> U,
341    {
342        let data = self.data.map(callback);
343        VecX { data }
344    }
345
346    /// Apply a function to each element of `VecX<T, N>` and `VecX<U, N>`.
347    ///
348    /// `VecX<T, N>`と`VecX<U, N>`の各要素に関数を適用する。
349    ///
350    /// # Examples
351    ///
352    /// ```
353    /// use vec_x::{VecX};
354    ///
355    /// let vec1 = VecX::new([1, 5, 3]);
356    /// let vec2 = VecX::new([4, 2, 6]);
357    ///
358    /// assert_eq!(vec1.batch_with(vec2, |a, b| a.min(b)), VecX::new([1, 2, 3]));
359    /// ```
360
361    pub fn batch_with<U, V, F>(self, other: VecX<U, N>, callback: F) -> VecX<V, N>
362    where
363        T: Copy,
364        U: Copy + Sized + Send,
365        V: Default + Copy + Sized + Send,
366        F: Fn(T, U) -> V,
367
368    {
369        let mut data = [V::default(); N];
370
371        (0..N).for_each(|i| data[i] = callback(self.data[i], other.data[i]));
372
373        VecX { data }
374    }
375}
376
377/// # Examples
378///
379/// ```
380/// use vec_x::{VecX};
381///
382/// let vec:VecX<u32,3> = VecX::from(1);
383///
384/// assert_eq!(vec, VecX::new([1, 1, 1]));
385///
386/// ```
387impl<T, const N: usize> From<T> for VecX<T, N>
388where
389    T: Sized + Send + Copy,
390{
391    fn from(value: T) -> Self {
392        Self { data: [value; N] }
393    }
394}
395
396/// Convert `VecX<T, N>` from `VecX<U, N>`.
397///
398/// `VecX<U, N>`から`VecX<T, N>`に変換する。
399///
400/// # Examples
401///
402/// ```
403/// use vec_x::{VecX};
404///
405/// let vec = VecX::new([1, 2, 3]);
406/// let vec_i32:VecX<i32,3> = VecX::from(vec);
407/// ```
408impl<T, const N: usize> From<[T; N]> for VecX<T, N>
409where
410    T: Sized + Send + Copy,
411{
412    fn from(data: [T; N]) -> Self {
413        Self { data }
414    }
415}
416
417impl<T, const N: usize> Index<usize> for VecX<T, N>
418where
419    T: Sized + Send,
420{
421    type Output = T;
422    fn index(&self, index: usize) -> &Self::Output {
423        &self.data[index]
424    }
425}
426
427impl<T, const N: usize> IndexMut<usize> for VecX<T, N>
428where
429    T: Sized + Send,
430{
431    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
432        &mut self.data[index]
433    }
434}
435
436impl<T, U, const N: usize> Add<VecX<U, N>> for VecX<T, N>
437where
438    T: Num + Copy + Sized + Send,
439    U: Num + Copy + Into<T> + Sized + Send,
440{
441    type Output = Self;
442
443    fn add(mut self, rhs: VecX<U, N>) -> Self::Output {
444        (0..N).for_each(|i| self.data[i] = self.data[i] + rhs.data[i].into());
445
446        self
447    }
448}
449
450impl<T, U, const N: usize> Add<U> for VecX<T, N>
451where
452    T: Num + Copy + Sized + Send,
453    U: Num + Copy + Into<T> + Sized + Send,
454{
455    type Output = Self;
456
457    fn add(mut self, rhs: U) -> Self::Output {
458        (0..N).for_each(|i| self.data[i] = self.data[i] + rhs.into());
459
460        self
461    }
462}
463
464impl<T, U, const N: usize> Sub<VecX<U, N>> for VecX<T, N>
465where
466    T: Num + Copy + Sized + Send,
467    U: Num + Copy + Into<T> + Sized + Send,
468{
469    type Output = Self;
470
471    fn sub(mut self, rhs: VecX<U, N>) -> Self::Output {
472        (0..N).for_each(|i| self.data[i] = self.data[i] - rhs.data[i].into());
473
474        self
475    }
476}
477
478impl<T, U, const N: usize> Sub<U> for VecX<T, N>
479where
480    T: Num + Copy + Sized + Send,
481    U: Num + Copy + Into<T> + Sized + Send,
482{
483    type Output = Self;
484
485    fn sub(mut self, rhs: U) -> Self::Output {
486        (0..N).for_each(|i| self.data[i] = self.data[i] - rhs.into());
487
488        self
489    }
490}
491
492impl<T, U, const N: usize> Mul<VecX<U, N>> for VecX<T, N>
493where
494    T: Num + Copy + Sized + Send,
495    U: Num + Copy + Into<T> + Sized + Send,
496{
497    type Output = Self;
498
499    fn mul(mut self, rhs: VecX<U, N>) -> Self::Output {
500        (0..N).for_each(|i| self.data[i] = self.data[i] * rhs.data[i].into());
501
502        self
503    }
504}
505
506impl<T, U, const N: usize> Mul<U> for VecX<T, N>
507where
508    T: Num + Copy + Sized + Send,
509    U: Num + Copy + Into<T> + Sized + Send,
510{
511    type Output = Self;
512
513    fn mul(mut self, rhs: U) -> Self::Output {
514        (0..N).for_each(|i| self.data[i] = self.data[i] * rhs.into());
515
516        self
517    }
518}
519
520impl<T, U, const N: usize> Div<VecX<U, N>> for VecX<T, N>
521where
522    T: Num + Copy + Sized + Send,
523    U: Num + Copy + Into<T> + Sized + Send,
524{
525    type Output = Self;
526
527    fn div(mut self, rhs: VecX<U, N>) -> Self::Output {
528        (0..N).for_each(|i| self.data[i] = self.data[i] / rhs.data[i].into());
529
530        self
531    }
532}
533
534impl<T, U, const N: usize> Div<U> for VecX<T, N>
535where
536    T: Num + Copy + Sized + Send,
537    U: Num + Copy + Into<T> + Sized + Send,
538{
539    type Output = Self;
540
541    fn div(mut self, rhs: U) -> Self::Output {
542        (0..N).for_each(|i| self.data[i] = self.data[i] / rhs.into());
543
544        self
545    }
546}
547
548impl<T, U, const N: usize> Rem<VecX<U, N>> for VecX<T, N>
549where
550    T: Num + Copy + Sized + Send,
551    U: Num + Copy + Into<T> + Sized + Send,
552{
553    type Output = Self;
554
555    fn rem(mut self, rhs: VecX<U, N>) -> Self::Output {
556        (0..N).for_each(|i| self.data[i] = self.data[i] % rhs.data[i].into());
557
558        self
559    }
560}
561
562impl<T, U, const N: usize> Rem<U> for VecX<T, N>
563where
564    T: Num + Copy + Sized + Send,
565    U: Num + Copy + Into<T> + Sized + Send,
566{
567    type Output = Self;
568
569    fn rem(mut self, rhs: U) -> Self::Output {
570        (0..N).for_each(|i| self.data[i] = self.data[i] % rhs.into());
571
572        self
573    }
574}
575
576impl<T, U, const N: usize> AddAssign<VecX<U, N>> for VecX<T, N>
577where
578    T: Num + AddAssign + Copy + Sized + Send,
579    U: Num + AddAssign + Copy + Into<T> + Sized + Send,
580{
581    fn add_assign(&mut self, rhs: VecX<U, N>) {
582        (0..N).for_each(|i| self.data[i] += rhs.data[i].into());
583    }
584}
585
586impl<T, U, const N: usize> AddAssign<U> for VecX<T, N>
587where
588    T: Num + AddAssign + Copy + Sized + Send,
589    U: Num + AddAssign + Copy + Into<T> + Sized + Send,
590{
591    fn add_assign(&mut self, rhs: U) {
592        (0..N).for_each(|i| self.data[i] += rhs.into());
593    }
594}
595
596impl<T, U, const N: usize> SubAssign<VecX<U, N>> for VecX<T, N>
597where
598    T: Num + SubAssign + Copy + Sized + Send,
599    U: Num + SubAssign + Copy + Into<T> + Sized + Send,
600{
601    fn sub_assign(&mut self, rhs: VecX<U, N>) {
602        (0..N).for_each(|i| self.data[i] -= rhs.data[i].into());
603    }
604}
605
606impl<T, U, const N: usize> SubAssign<U> for VecX<T, N>
607where
608    T: Num + SubAssign + Copy + Sized + Send,
609    U: Num + SubAssign + Copy + Into<T> + Sized + Send,
610{
611    fn sub_assign(&mut self, rhs: U) {
612        (0..N).for_each(|i| self.data[i] -= rhs.into());
613    }
614}
615
616impl<T, U, const N: usize> MulAssign<VecX<U, N>> for VecX<T, N>
617where
618    T: Num + MulAssign + Copy + Sized + Send,
619    U: Num + MulAssign + Copy + Into<T> + Sized + Send,
620{
621    fn mul_assign(&mut self, rhs: VecX<U, N>) {
622        (0..N).for_each(|i| self.data[i] *= rhs.data[i].into());
623    }
624}
625
626impl<T, U, const N: usize> MulAssign<U> for VecX<T, N>
627where
628    T: Num + MulAssign + Copy + Sized + Send,
629    U: Num + MulAssign + Copy + Into<T> + Sized + Send,
630{
631    fn mul_assign(&mut self, rhs: U) {
632        (0..N).for_each(|i| self.data[i] *= rhs.into());
633    }
634}
635
636impl<T, U, const N: usize> DivAssign<VecX<U, N>> for VecX<T, N>
637where
638    T: Num + DivAssign + Copy + Sized + Send,
639    U: Num + DivAssign + Copy + Into<T> + Sized + Send,
640{
641    fn div_assign(&mut self, rhs: VecX<U, N>) {
642        (0..N).for_each(|i| self.data[i] /= rhs.data[i].into());
643    }
644}
645
646impl<T, U, const N: usize> DivAssign<U> for VecX<T, N>
647where
648    T: Num + DivAssign + Copy + Sized + Send,
649    U: Num + DivAssign + Copy + Into<T> + Sized + Send,
650{
651    fn div_assign(&mut self, rhs: U) {
652        (0..N).for_each(|i| self.data[i] /= rhs.into());
653    }
654}
655
656impl<T, U, const N: usize> RemAssign<VecX<U, N>> for VecX<T, N>
657where
658    T: Num + RemAssign + Copy + Sized + Send,
659    U: Num + RemAssign + Copy + Into<T> + Sized + Send,
660{
661    fn rem_assign(&mut self, rhs: VecX<U, N>) {
662        (0..N).for_each(|i| self.data[i] %= rhs.data[i].into());
663    }
664}
665
666impl<T, U, const N: usize> RemAssign<U> for VecX<T, N>
667where
668    T: Num + RemAssign + Copy + Sized + Send,
669    U: Num + RemAssign + Copy + Into<T> + Sized + Send,
670{
671    fn rem_assign(&mut self, rhs: U) {
672        (0..N).for_each(|i| self.data[i] %= rhs.into());
673    }
674}
675
676/// Compare all elements.
677///
678/// 全ての要素を比較する。
679///
680/// # Examples
681///
682/// ```
683/// use vec_x::{VecX};
684///
685/// let vec1 = VecX::new([1, 2, 3]);
686/// let vec2 = VecX::new([1, 2, 3]);
687/// assert_eq!(vec1, vec2);
688/// assert!(vec1 <= vec2);
689/// assert!(vec1 >= vec2);
690///
691/// let vec1 = VecX::new([1, 2, 3]);
692/// let vec2 = VecX::new([4, 5, 6]);
693/// assert!(vec1 < vec2);
694///
695/// let vec1 = VecX::new([1, 2, 3]);
696/// let vec2 = VecX::new([1, 2, 2]);
697/// assert_ne!(vec1, vec2);
698/// assert!(vec1 > vec2);
699/// ```
700///
701/// ```should_panic
702/// use vec_x::{VecX};
703///
704/// let vec1 = VecX::new([1, 2, 3]);
705/// let vec2 = VecX::new([4, 5, 6]);
706///
707/// assert!(vec1 > vec2); // panic!
708/// ```
709///
710/// ```should_panic
711/// use vec_x::{VecX};
712///
713/// let vec1 = VecX::new([1, 2, 1]);
714/// let vec2 = VecX::new([2, 1, 2]);
715///
716/// assert!(vec1 < vec2|| vec1 == vec2 || vec1 > vec2); // panic!
717/// ```
718impl<T, const N: usize> PartialOrd for VecX<T, N>
719where
720    T: Num + PartialOrd + Copy + Sized + Send,
721{
722    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
723        if self == other {
724            Some(Ordering::Equal)
725        } else {
726            if self.data.iter().zip(other.data).all(|(a, b)| { *a >= b }) {
727                return Some(Ordering::Greater);
728            }
729            if self.data.iter().zip(other.data).all(|(a, b)| { *a <= b }) {
730                return Some(Ordering::Less);
731            }
732            None
733        }
734    }
735}