12#ifndef GDAL_VECTORX_H_INCLUDED
13#define GDAL_VECTORX_H_INCLUDED
33template <
typename T, std::
size_t N>
class VectorX
37 using size_type = std::size_t;
38 using self_type = VectorX<T, N>;
41 static constexpr size_type size() noexcept
51 template <
typename... Args> VectorX(Args... args) : _values({args...})
53 static_assert(N ==
sizeof...(Args),
54 "Invalid number of constructor params");
58 const std::array<T, N> &array()
const
63 T &operator[](
const size_type &pos)
68 const T &operator[](
const size_type &pos)
const
75 static_assert(N >= 1,
"Invalid template size for x()");
81 static_assert(N >= 2,
"Invalid template size for y()");
87 static_assert(N >= 3,
"Invalid template size for z()");
93 static_assert(N >= 1,
"Invalid template size for x()");
99 static_assert(N >= 2,
"Invalid template size for y()");
105 static_assert(N >= 3,
"Invalid template size for z()");
112 self_type &fill(T arg)
114 for (
size_t i = 0; i < N; i++)
124 template <
class UnaryOp> self_type apply(UnaryOp op)
const
127 for (
size_t i = 0; i < N; i++)
128 res[i] = op(_values[i]);
132 self_type floor()
const
134 return apply([](
const value_type &v) {
return std::floor(v); });
137 self_type ceil()
const
139 return apply([](
const value_type &v) {
return std::ceil(v); });
143 T scalarProd(
const self_type &arg)
const
146 for (
size_t i = 0; i < N; i++)
147 accum += _values[i] * arg[i];
154 return scalarProd(*
this);
163 template <
typename U> VectorX<U, N> cast()
const
166 for (
size_t i = 0; i < N; i++)
167 res[i] =
static_cast<U
>(_values[i]);
171 self_type operator+(T arg)
const
173 return operatorImpl<std::plus<T>>(arg);
176 self_type &operator+=(T arg)
178 return operatorEqImpl<std::plus<T>>(arg);
181 self_type operator-(T arg)
const
183 return operatorImpl<std::minus<T>>(arg);
186 self_type &operator-=(T arg)
188 return operatorEqImpl<std::minus<T>>(arg);
191 self_type operator-()
const
193 return apply([](
const value_type &v) {
return -v; });
196 template <
typename U> self_type operator*(U arg)
const
199 for (
size_t i = 0; i < N; i++)
200 res[i] = T(_values[i] * arg);
204 self_type operator*(T arg)
const
206 return operatorImpl<std::multiplies<T>>(arg);
209 template <
typename U> self_type operator/(U arg)
const
212 for (
size_t i = 0; i < N; i++)
213 res[i] = T(_values[i] / arg);
217 self_type operator/(T arg)
const
219 return operatorImpl<std::divides<T>>(arg);
222 self_type operator+(
const self_type &arg)
const
224 return operatorImpl<std::plus<T>>(arg);
227 self_type operator-(
const self_type &arg)
const
229 return operatorImpl<std::minus<T>>(arg);
232 friend VectorX<T, N> operator+(T t,
const VectorX<T, N> &arg)
235 for (
size_t i = 0; i < N; i++)
236 res._values[i] = t + arg._values[i];
240 friend VectorX<T, N> operator-(T t,
const VectorX<T, N> &arg)
243 for (
size_t i = 0; i < N; i++)
244 res._values[i] = t - arg._values[i];
249 std::array<T, N> _values{};
251 template <
class Op> self_type operatorImpl(T arg)
const
255 for (
size_t i = 0; i < N; i++)
256 res[i] = op(_values[i], arg);
260 template <
class Op> self_type &operatorEqImpl(T arg)
263 for (
size_t i = 0; i < N; i++)
264 _values[i] = op(_values[i], arg);
268 template <
class Op> self_type operatorImpl(
const self_type &arg)
const
272 for (
size_t i = 0; i < N; i++)
273 res[i] = op(_values[i], arg[i]);
277 template <
class Op> self_type &operatorEqImpl(
const self_type &arg)
280 for (
size_t i = 0; i < N; i++)
281 _values[i] = op(_values[i], arg[i]);
286using Vector2d = VectorX<double, 2>;
287using Vector2i = VectorX<int, 2>;
288using Vector3d = VectorX<double, 3>;
289using Vector3i = VectorX<int, 3>;