From 0efe16a2043ef67dea95c9469f53a4e45f50af9a Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sat, 15 Aug 2020 14:20:58 -0700 Subject: [PATCH] Separate implementation from declaration as stated in the coding standard --- include/detail/matrix.hpp | 104 +++++++------------------ include/detail/matrix.tpp | 147 +++++++++++++++++++++++++++++++++++ include/mat.hpp | 155 ++++++++----------------------------- include/mat.tpp | 157 ++++++++++++++++++++++++++++++++++++++ src/main.cpp | 1 + 5 files changed, 364 insertions(+), 200 deletions(-) create mode 100644 include/detail/matrix.tpp create mode 100644 include/mat.tpp diff --git a/include/detail/matrix.hpp b/include/detail/matrix.hpp index f4c471c..b42a73b 100644 --- a/include/detail/matrix.hpp +++ b/include/detail/matrix.hpp @@ -75,15 +75,9 @@ namespace math::detail{ protected: T* m_data = nullptr; public: - constexpr mat_ref_obj(T* d, size_type i): - m_data(d+i){} - - constexpr T& operator[](size_type i){ - return m_data[i*R]; - } - constexpr const T& operator[](size_type i)const{ - return m_data[i*R]; - } + constexpr mat_ref_obj(T* d, size_type i); + constexpr T& operator[](size_type i); + constexpr const T& operator[](size_type i)const; }; template @@ -107,102 +101,58 @@ namespace math::detail{ protected: template - constexpr matrix_base(std::integer_sequence): - m_data{Ss...}{} + constexpr matrix_base(std::integer_sequence); public: //Default construct as identity when square, zero otherwise - constexpr matrix_base(): - matrix_base(typename detail::default_initialization_matrix::tuple{}){} + constexpr matrix_base(); //Range initializing constructors - constexpr explicit matrix_base(zero_initialize_t): - m_data{}{} - constexpr explicit matrix_base(no_initialize_t){} + constexpr explicit matrix_base(detail::zero_initialize_t); + constexpr explicit matrix_base(detail::no_initialize_t); template - constexpr explicit matrix_base(id_initialize_t): - matrix_base() - { - static_assert(Columns == Rows, "Identity initialization only supported on square matrices"); - } + constexpr explicit matrix_base(detail::id_initialize_t); //Value initializing constructors - constexpr explicit matrix_base(value_type v){ - for(size_type i = 0;i < Columns*Rows;++i) - m_data[i] = v; - } + constexpr explicit matrix_base(value_type v); template - constexpr explicit matrix_base(Args&&... args): - m_data{std::forward(args)...}{} + constexpr explicit matrix_base(Args&&... args); //Copying constructors constexpr matrix_base(const matrix_base&) = default; constexpr matrix_base(matrix_base&&) = default; template - constexpr matrix_base(const matrix_base& m){ - using mat = decltype(m); - for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) - m_data[i] = m.get(i); - } + constexpr matrix_base(const matrix_base& m); ~matrix_base() = default; //Assignement template - constexpr matrix_base& operator=(const matrix_base& m){ - using mat = decltype(m); - for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) - m_data[i] = m.get(i); - return *this; - } + constexpr matrix_base& operator=(const matrix_base& m); constexpr matrix_base& operator=(const matrix_base&) = default; constexpr matrix_base& operator=(matrix_base&&) = default; //Getters/Setters - constexpr auto operator[](size_type x){ - return detail::mat_ref_obj{m_data, x}; - } - constexpr auto operator[](size_type x)const{ - return detail::mat_ref_obj{m_data, x}; - } - constexpr reference get(size_type x, size_type y){ - return m_data[x+(y*Rows)]; - } - constexpr const_reference get(size_type x, size_type y)const{ - return m_data[x+(y*Rows)]; - } - constexpr reference get(size_type i){ - return m_data[i]; - } - constexpr const_reference get(size_type i)const{ - return m_data[i]; - } + constexpr auto operator[](size_type x); + constexpr auto operator[](size_type x)const; + constexpr reference get(size_type x, size_type y); + constexpr const_reference get(size_type x, size_type y)const; + constexpr reference get(size_type i); + constexpr const_reference get(size_type i)const; - constexpr size_type columns()const{ - return Columns; - } - constexpr size_type rows()const{ - return Rows; - } - constexpr size_type size()const{ - return Columns*Rows; - } + constexpr size_type columns()const; + constexpr size_type rows()const; + constexpr size_type size()const; - constexpr pointer raw(){ - return m_data; - } - constexpr const_pointer raw()const{ - return m_data; - } - constexpr operator pointer(){ - return m_data; - } - constexpr operator const_pointer()const{ - return m_data; - } + constexpr pointer raw(); + constexpr const_pointer raw()const; + constexpr operator pointer(); + constexpr operator const_pointer()const; }; } +#include "matrix.tpp" + #endif diff --git a/include/detail/matrix.tpp b/include/detail/matrix.tpp new file mode 100644 index 0000000..37f8725 --- /dev/null +++ b/include/detail/matrix.tpp @@ -0,0 +1,147 @@ +/** + This file is a part of the rexy/r0nk/atlas project + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_DETAIL_MATRIX_TPP +#define REXY_DETAIL_MATRIX_TPP + +#include //size_t +#include //integer_sequence + +namespace math::detail{ + + template + constexpr mat_ref_obj::mat_ref_obj(T* d, size_type i): + m_data(d+i){} + + template + constexpr T& mat_ref_obj::operator[](size_type i){ + return m_data[i*R]; + } + template + constexpr const T& mat_ref_obj::operator[](size_type i)const{ + return m_data[i*R]; + } + + template + template::size_type... Ss> + constexpr matrix_base::matrix_base(std::integer_sequence): + m_data{Ss...}{} + + template + constexpr matrix_base::matrix_base(): + matrix_base(typename detail::default_initialization_matrix::tuple{}){} + + template + constexpr matrix_base::matrix_base(detail::zero_initialize_t): + m_data{}{} + template + constexpr matrix_base::matrix_base(detail::no_initialize_t){} + template + template + constexpr matrix_base::matrix_base(detail::id_initialize_t): + matrix_base() + { + static_assert(Columns == Rows, "Identity initialization only supported on square matrices"); + } + + template + constexpr matrix_base::matrix_base(value_type v){ + for(size_type i = 0;i < Columns*Rows;++i) + m_data[i] = v; + } + template + template + constexpr matrix_base::matrix_base(Args&&... args): + m_data{std::forward(args)...}{} + + template + template + constexpr matrix_base::matrix_base(const matrix_base& m){ + using mat = decltype(m); + for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) + m_data[i] = m.get(i); + } + + template + template + constexpr matrix_base& matrix_base::operator=(const matrix_base& m){ + using mat = decltype(m); + for(typename mat::size_type i = 0;i < mat::Columns*mat::Rows;++i) + m_data[i] = m.get(i); + return *this; + } + + + template + constexpr auto matrix_base::operator[](size_type x){ + return detail::mat_ref_obj{m_data, x}; + } + template + constexpr auto matrix_base::operator[](size_type x)const{ + return detail::mat_ref_obj{m_data, x}; + } + template + constexpr auto matrix_base::get(size_type x, size_type y) -> reference{ + return m_data[x+(y*Rows)]; + } + template + constexpr auto matrix_base::get(size_type x, size_type y)const -> const_reference{ + return m_data[x+(y*Rows)]; + } + template + constexpr auto matrix_base::get(size_type i) -> reference{ + return m_data[i]; + } + template + constexpr auto matrix_base::get(size_type i)const -> const_reference{ + return m_data[i]; + } + + template + constexpr auto matrix_base::columns()const -> size_type{ + return Columns; + } + template + constexpr auto matrix_base::rows()const -> size_type{ + return Rows; + } + template + constexpr auto matrix_base::size()const -> size_type{ + return Columns*Rows; + } + + template + constexpr auto matrix_base::raw() -> pointer{ + return m_data; + } + template + constexpr auto matrix_base::raw()const -> const_pointer{ + return m_data; + } + template + constexpr matrix_base::operator pointer(){ + return m_data; + } + template + constexpr matrix_base::operator const_pointer()const{ + return m_data; + } + +} + +#endif diff --git a/include/mat.hpp b/include/mat.hpp index ccc97aa..3d18724 100644 --- a/include/mat.hpp +++ b/include/mat.hpp @@ -21,8 +21,7 @@ #include //size_t #include //integer_sequence -#include //decay_t -#include //sin, cos +#include //decay_t, is_same, integral_constant #include "detail/math.hpp" #include "detail/matrix.hpp" @@ -61,21 +60,9 @@ namespace math{ using detail::matrix_base::matrix_base; using detail::matrix_base::operator=; - template - static constexpr matrix rotation(value_type angle){ - value_type c = std::cos(angle); - value_type s = std::sin(angle); - return rotation(s, c); - } - template - static constexpr matrix rotation(value_type sin, value_type cos){ - return matrix(cos, -sin, 0, - sin, cos, 0, - 0, 0, 1); - } - static constexpr matrix rotation(value_type angle_x, value_type angle_y, value_type angle_z){ - //TODO - } + static matrix rotation(value_type angle); + static constexpr matrix rotation(value_type sin, value_type cos); + static constexpr matrix rotation(value_type angle_x, value_type angle_y, value_type angle_z); }; namespace detail{ @@ -110,118 +97,40 @@ namespace math{ template using enable_if_eq_matrix = std::enable_if_t::value,int>; - } - template - constexpr bool operator==(const matrix& left, const matrix right){ - for(size_t i = 0;i < left.size();++i){ - if(left.get(i) != right.get(i)) - return false; - } - return true; - } - template - constexpr bool operator!=(const matrix& left, const matrix right){ - return !(left == right); - } + template + constexpr bool operator==(const matrix& left, const matrix right); + template + constexpr bool operator!=(const matrix& left, const matrix right); - template - constexpr auto operator*(const matrix& left, const matrix& right){ - using res_t = decltype(std::declval() * std::declval()); - matrix res(no_initialize); - size_t index = 0; - for(size_t i = 0;i < right.rows();++i){ - for(size_t j = 0;j < left.rows();++j){ - for(size_t k = 0;k < left.columns();++k){ - res.get(index) += left[j][k] * right[i][k]; - } - ++index; - } - } - return res; - } - template - constexpr auto operator*(const matrix& left, U&& right){ - using res_t = decltype(std::declval() * std::declval()); - matrix res(no_initialize); - for(size_t i = 0;i < left.size();++i){ - res.get(i) = left.get(i) * std::forward(right); - } - return res; - } - template - constexpr auto operator/(const matrix& left, U&& right){ - using res_t = decltype(std::declval() / std::declval()); - matrix res(no_initialize); - for(size_t i = 0;i < left.size();++i){ - res.get(i) = left.get(i) / std::forward(right); - } - return res; - } - template - constexpr auto operator+(const matrix& left, const matrix& right){ - using res_t = decltype(std::declval() + std::declval()); - matrix res(no_initialize); - for(size_t i = 0;i < left.size();++i){ - res.get(i) = left.get(i) + right.get(i); - } - return res; - } - template - constexpr auto operator-(const matrix& left, const matrix& right){ - using res_t = decltype(std::declval() - std::declval()); - matrix res(no_initialize); - for(size_t i = 0;i < left.size();++i){ - res.get(i) = left.get(i) - right.get(i); - } - return res; - } - template - constexpr auto operator-(const matrix& left){ - using res_t = decltype(std::declval() - std::declval()); - matrix res(no_initialize); - for(size_t i = 0;i < left.size();++i){ - res.get(i) = -left.get(i); - } - return res; - } + template + constexpr auto operator*(const matrix& left, const matrix& right); + template + constexpr auto operator*(const matrix& left, U&& right); + template + constexpr auto operator/(const matrix& left, U&& right); + template + constexpr auto operator+(const matrix& left, const matrix& right); + template + constexpr auto operator-(const matrix& left, const matrix& right); + template + constexpr auto operator-(const matrix& left); + template + constexpr decltype(auto) operator*=(matrix& left, const matrix& right); + template + constexpr decltype(auto) operator*=(matrix& left, U&& right); + template + constexpr decltype(auto) operator/=(matrix& left, U&& right); + template + constexpr decltype(auto) operator+=(matrix& left, const matrix& right); + template + constexpr decltype(auto) operator-=(matrix& left, const matrix& right); - template - constexpr decltype(auto) operator*=(matrix& left, const matrix& right){ - //have to evaluate entire expression first since matrix multiplication depends on reusing many elements - //cannot be expression templatized, TODO - return (left = (left * right)); - } - template - constexpr decltype(auto) operator*=(matrix& left, U&& right){ - for(size_t i = 0;i < left.size();++i){ - left.get(i) = left.get(i) * std::forward(right); - } - return left; - } - template - constexpr decltype(auto) operator/=(matrix& left, U&& right){ - for(size_t i = 0;i < left.size();++i){ - left.get(i) = left.get(i) / std::forward(right); - } - return left; - } - template - constexpr decltype(auto) operator+=(matrix& left, const matrix& right){ - for(size_t i = 0;i < left.size();++i){ - left.get(i) = left.get(i) + right.get(i); - } - return left; - } - template - constexpr decltype(auto) operator-=(matrix& left, const matrix& right){ - for(size_t i = 0;i < left.size();++i){ - left.get(i) = left.get(i) - right.get(i); - } - return left; } } +#include "mat.tpp" + #endif diff --git a/include/mat.tpp b/include/mat.tpp new file mode 100644 index 0000000..afed470 --- /dev/null +++ b/include/mat.tpp @@ -0,0 +1,157 @@ +/** + This file is a part of the rexy/r0nk/atlas project + Copyright (C) 2020 rexy712 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef REXY_MAT_TPP +#define REXY_MAT_TPP + +#include //size_t +#include //sin, cos +#include //decay_t, declval + +namespace math{ + + template + matrix matrix::rotation(value_type angle){ + value_type c = std::cos(angle); + value_type s = std::sin(angle); + return rotation(s, c); + } + template + constexpr matrix matrix::rotation(value_type sin, value_type cos){ + return matrix(cos, -sin, 0, + sin, cos, 0, + 0, 0, 1); + } + template + constexpr matrix matrix::rotation(value_type angle_x, value_type angle_y, value_type angle_z){ + //TODO + } + + template + constexpr bool operator==(const matrix& left, const matrix right){ + for(size_t i = 0;i < left.size();++i){ + if(left.get(i) != right.get(i)) + return false; + } + return true; + } + template + constexpr bool operator!=(const matrix& left, const matrix right){ + return !(left == right); + } + + template + constexpr auto operator*(const matrix& left, const matrix& right){ + using res_t = decltype(std::declval() * std::declval()); + matrix res(no_initialize); + size_t index = 0; + for(size_t i = 0;i < right.rows();++i){ + for(size_t j = 0;j < left.rows();++j){ + for(size_t k = 0;k < left.columns();++k){ + res.get(index) += left[j][k] * right[i][k]; + } + ++index; + } + } + return res; + } + template + constexpr auto operator*(const matrix& left, U&& right){ + using res_t = decltype(std::declval() * std::declval()); + matrix res(no_initialize); + for(size_t i = 0;i < left.size();++i){ + res.get(i) = left.get(i) * std::forward(right); + } + return res; + } + template + constexpr auto operator/(const matrix& left, U&& right){ + using res_t = decltype(std::declval() / std::declval()); + matrix res(no_initialize); + for(size_t i = 0;i < left.size();++i){ + res.get(i) = left.get(i) / std::forward(right); + } + return res; + } + template + constexpr auto operator+(const matrix& left, const matrix& right){ + using res_t = decltype(std::declval() + std::declval()); + matrix res(no_initialize); + for(size_t i = 0;i < left.size();++i){ + res.get(i) = left.get(i) + right.get(i); + } + return res; + } + template + constexpr auto operator-(const matrix& left, const matrix& right){ + using res_t = decltype(std::declval() - std::declval()); + matrix res(no_initialize); + for(size_t i = 0;i < left.size();++i){ + res.get(i) = left.get(i) - right.get(i); + } + return res; + } + template + constexpr auto operator-(const matrix& left){ + using res_t = decltype(std::declval() - std::declval()); + matrix res(no_initialize); + for(size_t i = 0;i < left.size();++i){ + res.get(i) = -left.get(i); + } + return res; + } + + + template + constexpr decltype(auto) operator*=(matrix& left, const matrix& right){ + //have to evaluate entire expression first since matrix multiplication depends on reusing many elements + //cannot be expression templatized, TODO + return (left = (left * right)); + } + template + constexpr decltype(auto) operator*=(matrix& left, U&& right){ + for(size_t i = 0;i < left.size();++i){ + left.get(i) = left.get(i) * std::forward(right); + } + return left; + } + template + constexpr decltype(auto) operator/=(matrix& left, U&& right){ + for(size_t i = 0;i < left.size();++i){ + left.get(i) = left.get(i) / std::forward(right); + } + return left; + } + template + constexpr decltype(auto) operator+=(matrix& left, const matrix& right){ + for(size_t i = 0;i < left.size();++i){ + left.get(i) = left.get(i) + right.get(i); + } + return left; + } + template + constexpr decltype(auto) operator-=(matrix& left, const matrix& right){ + for(size_t i = 0;i < left.size();++i){ + left.get(i) = left.get(i) - right.get(i); + } + return left; + } + +} + +#endif diff --git a/src/main.cpp b/src/main.cpp index c127171..6aecbc4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include "render.hpp" #include "game_state.hpp" +#include "mat.hpp" // 0 | 1 | 2 // ---------