Skip to content

Commit

Permalink
core: enhance vector constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
PottierLoic committed Mar 26, 2024
1 parent 93a5c55 commit 9882e4c
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 71 deletions.
80 changes: 51 additions & 29 deletions core/maths/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <cmath>
#include <iostream>
#include <cstdint>

namespace SpaceEngine {

Expand All @@ -12,45 +13,58 @@ class Vector {
std::array<T, N> data;

// Constructors
constexpr Vector() noexcept = default;
constexpr explicit Vector(T val) noexcept;
template <typename... Args>
constexpr explicit Vector(Args&&... args) noexcept;
constexpr Vector() = default;
constexpr explicit Vector(T val);
template <typename... Args, typename = std::enable_if_t<sizeof...(Args) == N>>
constexpr explicit Vector(Args&&... args);

// Dimensionality adjustements
constexpr explicit Vector(const Vector<T, N + 1>& vec);
constexpr Vector(const Vector<T, N - 1>& vec, T val);

// Accessors for x, y, z, w.
constexpr const T& x() const noexcept;
constexpr T& x() noexcept;
constexpr const T& y() const noexcept;
constexpr T& y() noexcept;
constexpr const T& z() const noexcept;
constexpr T& z() noexcept;
constexpr const T& w() const noexcept;
constexpr T& w() noexcept;
constexpr const T& x() const;
constexpr T& x();
constexpr const T& y() const;
constexpr T& y();
constexpr const T& z() const;
constexpr T& z();
constexpr const T& w() const;
constexpr T& w();

// Operations.
constexpr Vector operator-() const noexcept;
constexpr Vector operator+(const Vector& vec) const noexcept;
constexpr Vector operator-(const Vector& vec) const noexcept;
constexpr Vector operator*(const Vector& vec) const noexcept;
constexpr Vector operator*(T val) const noexcept;
constexpr Vector operator/(const Vector& vec) const noexcept;
constexpr Vector operator/(T val) const noexcept;
constexpr Vector operator-() const;
constexpr Vector operator+(const Vector& vec) const;
constexpr Vector operator+(T val) const;
constexpr Vector operator-(const Vector& vec) const;
constexpr Vector operator-(T val) const;
constexpr Vector operator*(const Vector& vec) const;
constexpr Vector operator*(T val) const;
constexpr Vector operator/(const Vector& vec) const;
constexpr Vector operator/(T val) const;

// Assignement operations.
constexpr Vector& operator+=(const Vector& vec) noexcept;
constexpr Vector& operator-=(const Vector& vec) noexcept;
constexpr Vector& operator*=(const Vector& vec) noexcept;
constexpr Vector& operator*=(T val) noexcept;
constexpr Vector& operator/=(const Vector& vec) noexcept;
constexpr Vector& operator/=(T val) noexcept;
constexpr Vector& operator+=(const Vector& vec);
constexpr Vector& operator+=(T val);
constexpr Vector& operator-=(const Vector& vec);
constexpr Vector& operator-=(T val);
constexpr Vector& operator*=(const Vector& vec);
constexpr Vector& operator*=(T val);
constexpr Vector& operator/=(const Vector& vec);
constexpr Vector& operator/=(T val);

// Access operators.
constexpr const T& operator[](std::size_t index) const noexcept;
constexpr T& operator[](std::size_t index) noexcept;
constexpr const T& operator[](std::size_t index) const;
constexpr T& operator[](std::size_t index);

// Equality operators.
constexpr bool operator==(const Vector& vec) const noexcept;
constexpr bool operator!=(const Vector& vec) const noexcept;
constexpr bool operator==(const Vector& vec) const;
constexpr bool operator!=(const Vector& vec) const;

// Utils
// TODO : Add following functions
// constexpr float dot(const Vector& vec) const;
// constexpr Vector cross(const Vector& vec) const;
};

// Aliases
Expand All @@ -59,10 +73,18 @@ template <typename T> using Vec2 = Vector<T, 2>;
template <typename T> using Vec3 = Vector<T, 3>;
template <typename T> using Vec4 = Vector<T, 4>;

using Vec2b = Vec2<uint8_t>;
using Vec3b = Vec3<uint8_t>;
using Vec4b = Vec4<uint8_t>;

using Vec2i = Vec2<int>;
using Vec3i = Vec3<int>;
using Vec4i = Vec4<int>;

using Vec2u = Vec2<uint32_t>;
using Vec3u = Vec3<uint32_t>;
using Vec4u = Vec4<uint32_t>;

using Vec2f = Vec2<float>;
using Vec3f = Vec3<float>;
using Vec4f = Vec4<float>;
Expand Down
106 changes: 77 additions & 29 deletions core/maths/vector.inl
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,79 @@
namespace SpaceEngine {

template<typename T, std::size_t N>
constexpr Vector<T, N>::Vector(T val) noexcept {
constexpr Vector<T, N>::Vector(T val) {
data.fill(val);
}

template<typename T, std::size_t N>
template<typename... Args>
constexpr Vector<T, N>::Vector(Args&&... args) noexcept : data{{std::forward<Args>(args)...}} {}
template<typename... Args, typename>
constexpr Vector<T, N>::Vector(Args&&... args) : data{ static_cast<T>(args)... } {}

template<typename T, std::size_t N>
constexpr const T& Vector<T, N>::x() const noexcept {
constexpr Vector<T, N>::Vector(const Vector<T, N + 1>& vec) {
for (std::size_t i = 0; i < N; ++i) {
data[i] = vec.data[i];
}
}

template<typename T, std::size_t N>
constexpr Vector<T, N>::Vector(const Vector<T, N - 1>& vec, T val) {
for (std::size_t i = 0; i < N - 1; ++i) {
data[i] = vec.data[i];
}
data[N - 1] = val;
}

template<typename T, std::size_t N>
constexpr const T& Vector<T, N>::x() const {
static_assert(N >= 1, "Vector does not have an X component.");
return data[0];
}

template<typename T, std::size_t N>
constexpr T& Vector<T, N>::x() noexcept {
constexpr T& Vector<T, N>::x() {
static_assert(N >= 1, "Vector does not have an X component.");
return data[0];
}

template<typename T, std::size_t N>
constexpr const T& Vector<T, N>::y() const noexcept {
constexpr const T& Vector<T, N>::y() const {
static_assert(N >= 2, "Vector does not have a Y component.");
return data[1];
}

template<typename T, std::size_t N>
constexpr T& Vector<T, N>::y() noexcept {
constexpr T& Vector<T, N>::y() {
static_assert(N >= 2, "Vector does not have a Y component.");
return data[1];
}

template<typename T, std::size_t N>
constexpr const T& Vector<T, N>::z() const noexcept {
constexpr const T& Vector<T, N>::z() const {
static_assert(N >= 3, "Vector does not have a Z component.");
return data[2];
}

template<typename T, std::size_t N>
constexpr T& Vector<T, N>::z() noexcept {
constexpr T& Vector<T, N>::z() {
static_assert(N >= 3, "Vector does not have a Z component.");
return data[2];
}

template<typename T, std::size_t N>
constexpr const T& Vector<T, N>::w() const noexcept {
constexpr const T& Vector<T, N>::w() const {
static_assert(N >= 4, "Vector does not have a W component.");
return data[3];
}

template<typename T, std::size_t N>
constexpr T& Vector<T, N>::w() noexcept {
constexpr T& Vector<T, N>::w() {
static_assert(N >= 4, "Vector does not have a W component.");
return data[3];
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator-() const noexcept {
constexpr Vector<T, N> Vector<T, N>::operator-() const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = -data[i];
Expand All @@ -69,7 +84,7 @@ constexpr Vector<T, N> Vector<T, N>::operator-() const noexcept {
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator+(const Vector<T, N>& vec) const noexcept {
constexpr Vector<T, N> Vector<T, N>::operator+(const Vector<T, N>& vec) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] + vec.data[i];
Expand All @@ -78,7 +93,16 @@ constexpr Vector<T, N> Vector<T, N>::operator+(const Vector<T, N>& vec) const no
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator-(const Vector<T, N>& vec) const noexcept {
constexpr Vector<T, N> Vector<T, N>::operator+(T val) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] + val;
}
return result;
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator-(const Vector<T, N>& vec) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] - vec.data[i];
Expand All @@ -87,7 +111,16 @@ constexpr Vector<T, N> Vector<T, N>::operator-(const Vector<T, N>& vec) const no
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator*(T val) const noexcept {
constexpr Vector<T, N> Vector<T, N>::operator-(T val) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] - val;
}
return result;
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator*(T val) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] * val;
Expand All @@ -96,7 +129,7 @@ constexpr Vector<T, N> Vector<T, N>::operator*(T val) const noexcept {
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator*(const Vector<T, N>& vec) const noexcept {
constexpr Vector<T, N> Vector<T, N>::operator*(const Vector<T, N>& vec) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] * vec.data[i];
Expand All @@ -105,7 +138,7 @@ constexpr Vector<T, N> Vector<T, N>::operator*(const Vector<T, N>& vec) const no
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator/(T val) const noexcept {
constexpr Vector<T, N> Vector<T, N>::operator/(T val) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] / val;
Expand All @@ -114,7 +147,7 @@ constexpr Vector<T, N> Vector<T, N>::operator/(T val) const noexcept {
}

template<typename T, std::size_t N>
constexpr Vector<T, N> Vector<T, N>::operator/(const Vector<T, N>& vec) const noexcept {
constexpr Vector<T, N> Vector<T, N>::operator/(const Vector<T, N>& vec) const {
Vector<T, N> result;
for (std::size_t i = 0; i < N; ++i) {
result.data[i] = data[i] / vec.data[i];
Expand All @@ -123,65 +156,81 @@ constexpr Vector<T, N> Vector<T, N>::operator/(const Vector<T, N>& vec) const no
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator+=(const Vector<T, N>& vec) noexcept {
constexpr Vector<T, N>& Vector<T, N>::operator+=(const Vector<T, N>& vec) {
for (std::size_t i = 0; i < N; ++i) {
data[i] += vec.data[i];
}
return *this;
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator-=(const Vector<T, N>& vec) noexcept {
constexpr Vector<T, N>& Vector<T, N>::operator+=(T val) {
for (std::size_t i = 0; i < N; ++i) {
data[i] += val;
}
return *this;
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator-=(const Vector<T, N>& vec) {
for (std::size_t i = 0; i < N; ++i) {
data[i] -= vec.data[i];
}
return *this;
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator*=(T val) noexcept {
constexpr Vector<T, N>& Vector<T, N>::operator-=(T val) {
for (std::size_t i = 0; i < N; ++i) {
data[i] -= val;
}
return *this;
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator*=(T val) {
for (std::size_t i = 0; i < N; ++i) {
data[i] *= val;
}
return *this;
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator*=(const Vector<T, N>& vec) noexcept {
constexpr Vector<T, N>& Vector<T, N>::operator*=(const Vector<T, N>& vec) {
for (std::size_t i = 0; i < N; ++i) {
data[i] *= vec.data[i];
}
return *this;
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator/=(T val) noexcept {
constexpr Vector<T, N>& Vector<T, N>::operator/=(T val) {
for (std::size_t i = 0; i < N; ++i) {
data[i] /= val;
}
return *this;
}

template<typename T, std::size_t N>
constexpr Vector<T, N>& Vector<T, N>::operator/=(const Vector<T, N>& vec) noexcept {
constexpr Vector<T, N>& Vector<T, N>::operator/=(const Vector<T, N>& vec) {
for (std::size_t i = 0; i < N; ++i) {
data[i] /= vec.data[i];
}
return *this;
}

template<typename T, std::size_t N>
constexpr const T& Vector<T, N>::operator[](std::size_t index) const noexcept {
constexpr const T& Vector<T, N>::operator[](std::size_t index) const {
return data[index];
}

template<typename T, std::size_t N>
constexpr T& Vector<T, N>::operator[](std::size_t index) noexcept {
constexpr T& Vector<T, N>::operator[](std::size_t index) {
return data[index];
}

template<typename T, std::size_t N>
constexpr bool Vector<T, N>::operator==(const Vector<T, N>& vec) const noexcept {
constexpr bool Vector<T, N>::operator==(const Vector<T, N>& vec) const {
for (std::size_t i = 0; i < N; ++i) {
if (data[i] != vec.data[i]) {
return false;
Expand All @@ -191,7 +240,7 @@ constexpr bool Vector<T, N>::operator==(const Vector<T, N>& vec) const noexcept
}

template<typename T, std::size_t N>
constexpr bool Vector<T, N>::operator!=(const Vector<T, N>& vec) const noexcept {
constexpr bool Vector<T, N>::operator!=(const Vector<T, N>& vec) const {
return !(*this == vec);
}

Expand All @@ -206,5 +255,4 @@ std::ostream& operator<<(std::ostream& stream, const Vector<T, N>& vec) {
return stream;
}


}
Loading

0 comments on commit 9882e4c

Please sign in to comment.