23 [[nodiscard]]
constexpr std::array<T, Field::size() * 2> getNeighbors()
const noexcept {
24 std::array<T, Field::size() * 2> res;
26 Field::forEachComponent([&]<
typename axis_type,
size_t axis> {
27 ll::meta::unroll<2>([&]<
size_t iter> {
28 T tmp = *(
static_cast<T const*
>(
this));
29 tmp.template get<axis_type, axis>() +=
static_cast<axis_type
>(iter * 2 - 1);
37 constexpr T& operator*=(T
const& b)
noexcept {
38 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
39 static_cast<T*
>(
this)->
template get<axis_type, iter>() *= b.template get<axis_type, iter>();
41 return static_cast<T&
>(*(
static_cast<T*
>(
this)));
44 constexpr T& operator/=(T
const& b)
noexcept {
45 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
46 static_cast<T*
>(
this)->
template get<axis_type, iter>() /= b.template get<axis_type, iter>();
48 return static_cast<T&
>(*(
static_cast<T*
>(
this)));
51 [[nodiscard]]
constexpr T operator*(T
const& b)
const noexcept {
52 T tmp = *(
static_cast<T const*
>(
this));
57 [[nodiscard]]
constexpr T operator/(T
const& b)
const noexcept {
58 T tmp = *(
static_cast<T const*
>(
this));
63 template <std::convertible_to<first_type> V>
64 constexpr T& operator*=(V
const& b)
noexcept {
65 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
66 static_cast<T*
>(
this)->
template get<first_type, iter>() *=
static_cast<first_type
>(b);
68 return static_cast<T&
>(*(
static_cast<T*
>(
this)));
71 template <std::convertible_to<first_type> V>
72 constexpr T& operator/=(V
const& b)
noexcept {
73 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
74 static_cast<T*
>(
this)->
template get<first_type, iter>() /=
static_cast<first_type
>(b);
76 return static_cast<T&
>(*(
static_cast<T*
>(
this)));
79 template <std::convertible_to<first_type> V>
80 [[nodiscard]]
constexpr T operator*(V
const& b)
const noexcept {
81 T tmp = *(
static_cast<T const*
>(
this));
82 tmp *=
static_cast<first_type
>(b);
86 template <std::convertible_to<first_type> V>
87 [[nodiscard]]
constexpr T operator/(V
const& b)
const noexcept {
88 T tmp = *(
static_cast<T const*
>(
this));
89 tmp /=
static_cast<first_type
>(b);
93 [[nodiscard]]
constexpr T mul(T
const& b)
const noexcept {
return *(
static_cast<T const*
>(
this)) * b; }
95 [[nodiscard]]
constexpr T div(T
const& b)
const noexcept {
return *(
static_cast<T const*
>(
this)) / b; }
97 template <std::convertible_to<first_type> V>
98 [[nodiscard]]
constexpr T mul(V
const& b)
const noexcept {
99 return *(
static_cast<T const*
>(
this)) *
static_cast<first_type
>(b);
102 template <std::convertible_to<first_type> V>
103 [[nodiscard]]
constexpr T div(V
const& b)
const noexcept {
104 return *(
static_cast<T const*
>(
this)) /
static_cast<first_type
>(b);
107 [[nodiscard]]
constexpr double dot(T
const& b)
const noexcept {
109 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
110 res += (double)(
static_cast<T const*
>(
this)->
template get<axis_type, iter>())
111 * b.template get<axis_type, iter>();
116 template <std::convertible_to<first_type> V>
117 [[nodiscard]]
constexpr double dot(V
const& b)
const noexcept {
119 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
120 res += (double)(
static_cast<T const*
>(
this)->
template get<axis_type, iter>()) *
static_cast<first_type
>(b);
125 [[nodiscard]]
constexpr double lengthSqr()
const noexcept {
return dot(*(
static_cast<T const*
>(
this))); }
127 [[nodiscard]]
constexpr double length()
const noexcept {
return sqrt(
static_cast<double>(lengthSqr())); }
129 [[nodiscard]]
constexpr double distanceTo(T
const& b)
const noexcept {
130 return (*(
static_cast<T const*
>(
this)) - b).length();
133 [[nodiscard]]
constexpr double distanceToSqr(T
const& b)
const noexcept {
134 return (*(
static_cast<T const*
>(
this)) - b).lengthSqr();
137 [[nodiscard]]
constexpr bool operator<(T
const& b)
const noexcept {
return lengthSqr() < b.lengthSqr(); }
139 [[nodiscard]]
constexpr bool operator>(T
const& b)
const noexcept {
return lengthSqr() > b.lengthSqr(); }
141 [[nodiscard]]
constexpr bool operator<=(T
const& b)
const noexcept {
return lengthSqr() <= b.lengthSqr(); }
143 [[nodiscard]]
constexpr bool operator>=(T
const& b)
const noexcept {
return lengthSqr() >= b.lengthSqr(); }
145 [[nodiscard]]
constexpr class boolN<sizeof...(Components)> lt(T const& b)
const noexcept
146 requires(
sizeof...(Components) >= 2 &&
sizeof...(Components) <= 4)
148 boolN<
sizeof...(Components)> res =
true;
149 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
150 res.template get<bool, iter>() =
151 (
static_cast<T const*
>(
this)->template get<axis_type, iter>() < b.template get<axis_type, iter>());
156 [[nodiscard]]
constexpr class boolN<sizeof...(Components)> le(T const& b)
const noexcept
157 requires(
sizeof...(Components) >= 2 &&
sizeof...(Components) <= 4)
159 boolN<
sizeof...(Components)> res =
true;
160 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
161 res.template get<bool, iter>() =
162 (
static_cast<T const*
>(
this)->template get<axis_type, iter>() <= b.template get<axis_type, iter>());
167 [[nodiscard]]
constexpr class boolN<sizeof...(Components)> gt(T const& b)
const noexcept
168 requires(
sizeof...(Components) >= 2 &&
sizeof...(Components) <= 4)
170 boolN<
sizeof...(Components)> res =
true;
171 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
172 res.template get<bool, iter>() =
173 (
static_cast<T const*
>(
this)->template get<axis_type, iter>() > b.template get<axis_type, iter>());
178 [[nodiscard]]
constexpr class boolN<sizeof...(Components)> ge(T const& b)
const noexcept
179 requires(
sizeof...(Components) >= 2 &&
sizeof...(Components) <= 4)
181 boolN<
sizeof...(Components)> res =
true;
182 Field::forEachComponent([&]<
typename axis_type,
size_t iter> {
183 res.template get<bool, iter>() =
184 (
static_cast<T const*
>(
this)->template get<axis_type, iter>() >= b.template get<axis_type, iter>());