1// Copyright 2020 Yevhenii Reizner
2//
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5
6#[cfg(all(not(feature = "std"), feature = "no-std-float"))]
7use crate::NoStdFloat;
8
9// Right now, there are no visible benefits of using SIMD for f32x2. So we don't.
10/// A pair of f32 numbers.
11///
12/// Mainly for internal use. Do not rely on it!
13#[allow(non_camel_case_types)]
14#[derive(Copy, Clone, Default, PartialEq, Debug)]
15pub struct f32x2(pub [f32; 2]);
16
17impl f32x2 {
18 /// Creates a new pair.
19 pub fn new(a: f32, b: f32) -> f32x2 {
20 f32x2([a, b])
21 }
22
23 /// Creates a new pair from a single value.
24 pub fn splat(x: f32) -> f32x2 {
25 f32x2([x, x])
26 }
27
28 /// Returns an absolute value.
29 pub fn abs(self) -> f32x2 {
30 f32x2([self.x().abs(), self.y().abs()])
31 }
32
33 /// Returns a minimum value.
34 pub fn min(self, other: f32x2) -> f32x2 {
35 f32x2([pmin(self.x(), other.x()), pmin(self.y(), other.y())])
36 }
37
38 /// Returns a maximum value.
39 pub fn max(self, other: f32x2) -> f32x2 {
40 f32x2([pmax(self.x(), other.x()), pmax(self.y(), other.y())])
41 }
42
43 /// Returns a maximum of both values.
44 pub fn max_component(self) -> f32 {
45 pmax(self.x(), self.y())
46 }
47
48 /// Returns the first value.
49 pub fn x(&self) -> f32 {
50 self.0[0]
51 }
52
53 /// Returns the second value.
54 pub fn y(&self) -> f32 {
55 self.0[1]
56 }
57}
58
59impl core::ops::Add<f32x2> for f32x2 {
60 type Output = f32x2;
61
62 fn add(self, other: f32x2) -> f32x2 {
63 f32x2([self.x() + other.x(), self.y() + other.y()])
64 }
65}
66
67impl core::ops::Sub<f32x2> for f32x2 {
68 type Output = f32x2;
69
70 fn sub(self, other: f32x2) -> f32x2 {
71 f32x2([self.x() - other.x(), self.y() - other.y()])
72 }
73}
74
75impl core::ops::Mul<f32x2> for f32x2 {
76 type Output = f32x2;
77
78 fn mul(self, other: f32x2) -> f32x2 {
79 f32x2([self.x() * other.x(), self.y() * other.y()])
80 }
81}
82
83impl core::ops::Div<f32x2> for f32x2 {
84 type Output = f32x2;
85
86 fn div(self, other: f32x2) -> f32x2 {
87 f32x2([self.x() / other.x(), self.y() / other.y()])
88 }
89}
90
91// A faster and more forgiving f32 min/max implementation.
92//
93// Unlike std one, we do not care about NaN.
94
95fn pmax(a: f32, b: f32) -> f32 {
96 if a < b {
97 b
98 } else {
99 a
100 }
101}
102
103fn pmin(a: f32, b: f32) -> f32 {
104 if b < a {
105 b
106 } else {
107 a
108 }
109}
110