simplevectors  0.3.9
Simple vector implementations in C++
vector.hpp
Go to the documentation of this file.
1 
10 #ifndef INCLUDE_SVECTOR_BASEVECTOR_HPP_
11 #define INCLUDE_SVECTOR_BASEVECTOR_HPP_
12 
13 #include <algorithm> // std::min
14 #include <array> // std::array
15 #include <cmath> // std::atan2, std::sqrt
16 #include <cstddef> // std::size_t
17 #include <cstdint> // std::int8_t
18 #include <initializer_list> // std::initializer_list
19 #include <string> // std::string, std::to_string
20 #include <type_traits> // std::is_arithmetic
21 
22 namespace svector {
23 // COMBINER_PY_START
34 template <std::size_t D, typename T = double> class Vector {
35 public:
36  // makes sure that type is numeric
37  static_assert(std::is_arithmetic<T>::value, "Vector type must be numeric");
38 
39 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
40  template <std::size_t D1, std::size_t D2, typename T1, typename T2>
41  friend bool operator<(const Vector<D1, T1> &, const Vector<D2, T2> &);
42 
43  template <std::size_t D1, std::size_t D2, typename T1, typename T2>
44  friend bool operator<=(const Vector<D1, T1> &, const Vector<D2, T2> &);
45 
46  template <std::size_t D1, std::size_t D2, typename T1, typename T2>
47  friend bool operator>(const Vector<D1, T1> &, const Vector<D2, T2> &);
48 
49  template <std::size_t D1, std::size_t D2, typename T1, typename T2>
50  friend bool operator>=(const Vector<D1, T1> &, const Vector<D2, T2> &);
51 #endif
52 
53  typedef
54  typename std::array<T, D>::iterator iterator;
55  typedef typename std::array<T, D>::const_iterator
57  typedef typename std::array<T, D>::reverse_iterator
59  typedef typename std::array<T, D>::const_reverse_iterator
61 
67  Vector() { this->m_components.fill(0); }
68 
81  Vector(const std::initializer_list<T> args) {
82  // in case length of args < dimensions
83  this->m_components.fill(0);
84 
85  std::size_t counter = 0;
86  for (const auto &num : args) {
87  if (counter >= D) {
88  break;
89  }
90 
91  this->m_components[counter] = num;
92  counter++;
93  }
94  }
95 
101  Vector(const Vector<D, T> &other) {
102  for (std::size_t i = 0; i < D; i++) {
103  this->m_components[i] = other[i];
104  }
105  }
106 
112  Vector(Vector<D, T> &&) noexcept = default;
113 
119  Vector<D, T> &operator=(const Vector<D, T> &other) {
120  // check if assigning to self
121  if (this == &other) {
122  return *this;
123  }
124 
125  for (std::size_t i = 0; i < D; i++) {
126  this->m_components[i] = other[i];
127  }
128 
129  return *this;
130  }
131 
137  Vector<D, T> &operator=(Vector<D, T> &&) noexcept = default;
138 
144  virtual ~Vector() = default;
145 
153  virtual std::string toString() const {
154  std::string str = "<";
155  for (std::size_t i = 0; i < D - 1; i++) {
156  str += std::to_string(this->m_components[i]);
157  str += ", ";
158  }
159 
160  str += std::to_string(this->m_components[D - 1]);
161  str += ">";
162 
163  return str;
164  }
165 
166 #ifdef SVECTOR_USE_CLASS_OPERATORS
183  Vector<D, T> operator+(const Vector<D, T> &other) const {
184  Vector<D, T> tmp;
185  for (std::size_t i = 0; i < D; i++) {
186  tmp[i] = this->m_components[i] + other[i];
187  }
188 
189  return tmp;
190  }
191 
208  Vector<D, T> operator-(const Vector<D, T> &other) const {
209  Vector<D, T> tmp;
210  for (std::size_t i = 0; i < D; i++) {
211  tmp[i] = this->m_components[i] - other[i];
212  }
213 
214  return tmp;
215  }
216 
230  Vector<D, T> operator*(const T other) const {
231  Vector<D, T> tmp;
232  for (std::size_t i = 0; i < D; i++) {
233  tmp[i] = this->m_components[i] * other;
234  }
235 
236  return tmp;
237  }
238 
252  Vector<D, T> operator/(const T other) const {
253  Vector<D, T> tmp;
254  for (std::size_t i = 0; i < D; i++) {
255  tmp[i] = this->m_components[i] / other;
256  }
257 
258  return tmp;
259  }
260 
274  bool operator==(const Vector<D, T> &other) const {
275  for (std::size_t i = 0; i < D; i++) {
276  if (this->m_components[i] != other[i]) {
277  return false;
278  }
279  }
280 
281  return true;
282  }
283 
297  bool operator!=(const Vector<D, T> &other) const {
298  return !((*this) == other);
299  }
300 #endif
301 
312  Vector<D, T> tmp;
313  for (std::size_t i = 0; i < D; i++) {
314  tmp[i] = -this->m_components[i];
315  }
316 
317  return tmp;
318  }
319 
329  Vector<D, T> tmp;
330  for (std::size_t i = 0; i < D; i++) {
331  tmp[i] = +this->m_components[i];
332  }
333 
334  return tmp;
335  }
336 
345  for (std::size_t i = 0; i < D; i++) {
346  this->m_components[i] += other[i];
347  }
348 
349  return *this;
350  }
351 
360  for (std::size_t i = 0; i < D; i++) {
361  this->m_components[i] -= other[i];
362  }
363 
364  return *this;
365  }
366 
374  Vector<D, T> &operator*=(const T other) {
375  for (std::size_t i = 0; i < D; i++) {
376  this->m_components[i] *= other;
377  }
378 
379  return *this;
380  }
381 
389  Vector<D, T> &operator/=(const T other) {
390  for (std::size_t i = 0; i < D; i++) {
391  this->m_components[i] /= other;
392  }
393 
394  return *this;
395  }
396 
409  T dot(const Vector<D, T> &other) const {
410  T result = 0;
411 
412  for (std::size_t i = 0; i < D; i++) {
413  result += this->m_components[i] * other[i];
414  }
415 
416  return result;
417  }
418 
426  T magn() const {
427  T sum_of_squares = 0;
428 
429  for (const auto &i : this->m_components) {
430  sum_of_squares += i * i;
431  }
432 
433  return std::sqrt(sum_of_squares);
434  };
435 
446  Vector<D, T> normalize() const { return (*this) / this->magn(); }
447 
453  constexpr std::size_t numDimensions() const { return D; }
454 
460  bool isZero() const { return this->magn() == 0; }
461 
472  const T &operator[](const std::size_t index) const {
473  return this->m_components[index];
474  }
475 
483  T &operator[](const std::size_t index) { return this->m_components[index]; }
484 
497  const T &at(const std::size_t index) const {
498  return this->m_components.at(index);
499  }
500 
510  T &at(const std::size_t index) { return this->m_components.at(index); }
511 
522  iterator begin() noexcept { return iterator{this->m_components.begin()}; }
523 
532  const_iterator begin() const noexcept {
533  return const_iterator{this->m_components.begin()};
534  }
535 
549  iterator end() noexcept { return iterator{this->m_components.end()}; }
550 
562  const_iterator end() const noexcept {
563  return const_iterator{this->m_components.end()};
564  }
565 
578  return reverse_iterator{this->m_components.rbegin()};
579  }
580 
590  const_reverse_iterator rbegin() const noexcept {
591  return const_reverse_iterator{this->m_components.rbegin()};
592  }
593 
608  reverse_iterator rend() noexcept {
609  return reverse_iterator{this->m_components.rend()};
610  }
611 
625  const_reverse_iterator rend() const noexcept {
626  return const_reverse_iterator{this->m_components.rend()};
627  }
628 
629 protected:
630  std::array<T, D> m_components;
631 
632 #ifdef SVECTOR_EXPERIMENTAL_COMPARE
633 private:
654  template <std::size_t D2, typename T2>
655  std::int8_t compare(const Vector<D2, T2> &other) const noexcept {
656  std::size_t min_dim = std::min(D, D2);
657  std::size_t counter = 0;
658 
659 // to suppress MSVC warning
660 #ifdef _MSC_VER
661  if constexpr (D != D2) {
662 #else
663  if (D != D2) {
664 #endif
665  // check dimensions first
666  return D < D2 ? -1 : 1;
667  }
668 
669  // compare one by one
670  for (std::size_t i = 0; i < min_dim; i++) {
671  if (this->m_components[i] == other[i]) {
672  counter++;
673  } else if (this->m_components[i] < other[i]) {
674  return -1;
675  } else {
676  return 1;
677  }
678  }
679 
680  if (counter != D || counter != D2) {
681  return -1;
682  }
683 
684  // means two vectors are equal
685  return 0;
686  }
687 #endif
688 };
689 // COMBINER_PY_END
690 } // namespace svector
691 
692 #endif
bool operator==(const EmbVec2D &lhs, const EmbVec2D &rhs)
Compares equality of two vectors.
Definition: embed.h:470
bool operator!=(const EmbVec2D &lhs, const EmbVec2D &rhs)
Compares inequality of two vectors.
Definition: embed.h:482
EmbVec2D operator/(const EmbVec2D &lhs, const float rhs)
Scalar division.
Definition: embed.h:458
EmbVec2D operator*(const EmbVec2D &lhs, const float rhs)
Scalar multiplication.
Definition: embed.h:443
A base vector representation.
Definition: vector.hpp:34
std::array< T, D >::const_reverse_iterator const_reverse_iterator
An std::array::const_reverse_iterator.
Definition: vector.hpp:60
const T & at(const std::size_t index) const
Value of a certain component of a vector.
Definition: vector.hpp:497
Vector()
No-argument constructor.
Definition: vector.hpp:67
std::array< T, D >::const_iterator const_iterator
An std::array::const_iterator.
Definition: vector.hpp:56
Vector< D, T > operator+() const
Positive of a vector.
Definition: vector.hpp:328
reverse_iterator rend() noexcept
Reverse iterator to first element - 1.
Definition: vector.hpp:608
Vector(Vector< D, T > &&) noexcept=default
Move constructor.
reverse_iterator rbegin() noexcept
Reverse iterator to last element.
Definition: vector.hpp:577
T magn() const
Magnitude.
Definition: vector.hpp:426
Vector< D, T > & operator+=(const Vector< D, T > &other)
In-place addition.
Definition: vector.hpp:344
const_reverse_iterator rbegin() const noexcept
Const reverse iterator to last element.
Definition: vector.hpp:590
iterator begin() noexcept
Iterator of first element.
Definition: vector.hpp:522
std::array< T, D >::iterator iterator
An std::array::iterator.
Definition: vector.hpp:37
const_iterator end() const noexcept
Const interator of last element + 1.
Definition: vector.hpp:562
Vector< D, T > normalize() const
Normalizes a vector.
Definition: vector.hpp:446
Vector< D, T > & operator-=(const Vector< D, T > &other)
In-place subtraction.
Definition: vector.hpp:359
const_reverse_iterator rend() const noexcept
Const reverse iterator to first element - 1.
Definition: vector.hpp:625
virtual std::string toString() const
Returns string form of vector.
Definition: vector.hpp:153
Vector< D, T > operator-() const
Negative of a vector.
Definition: vector.hpp:311
Vector(const std::initializer_list< T > args)
Initializes a vector given initializer list.
Definition: vector.hpp:81
Vector< D, T > & operator=(Vector< D, T > &&) noexcept=default
Move assignment operator.
iterator end() noexcept
Interator of last element + 1.
Definition: vector.hpp:549
Vector(const Vector< D, T > &other)
Copy constructor.
Definition: vector.hpp:101
std::array< T, D > m_components
An array of components for the vector.
Definition: vector.hpp:630
T dot(const Vector< D, T > &other) const
Dot product.
Definition: vector.hpp:409
Vector< D, T > & operator/=(const T other)
In-place scalar division.
Definition: vector.hpp:389
Vector< D, T > & operator*=(const T other)
In-place scalar multiplication.
Definition: vector.hpp:374
std::array< T, D >::reverse_iterator reverse_iterator
An std::array::reverse_iterator.
Definition: vector.hpp:58
T & operator[](const std::size_t index)
Sets value of a certain component.
Definition: vector.hpp:483
bool isZero() const
Determines whether the current vector is a zero vector.
Definition: vector.hpp:460
const_iterator begin() const noexcept
Const interator of first element.
Definition: vector.hpp:532
T & at(const std::size_t index)
Sets value of a certain component.
Definition: vector.hpp:510
constexpr std::size_t numDimensions() const
Gets the number of dimensions.
Definition: vector.hpp:453
const T & operator[](const std::size_t index) const
Value of a certain component of a vector.
Definition: vector.hpp:472