/** 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_HPP #define REXY_MAT_HPP #include //size_t #include //integer_sequence #include //decay_t, is_same, integral_constant #include "detail/math.hpp" namespace math{ template class matrix_base { static_assert(C > 0, "Cannot have 0 columns matrix"); static_assert(R > 0, "Cannot have 0 rows matrix"); public: using value_type = T; using size_type = size_t; using pointer = value_type*; using const_pointer = const value_type*; using reference = value_type&; using const_reference = const value_type&; static constexpr size_type Columns = C; static constexpr size_type Rows = R; protected: value_type m_data[R*C]; protected: template constexpr matrix_base(std::integer_sequence); public: //Default construct as identity when square, zero otherwise constexpr matrix_base(); //Range initializing constructors constexpr explicit matrix_base(detail::zero_initialize_t); constexpr explicit matrix_base(detail::no_initialize_t); //Value initializing constructors constexpr explicit matrix_base(value_type v); template 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); ~matrix_base() = default; constexpr matrix_base& operator=(const matrix_base&) = default; constexpr matrix_base& operator=(matrix_base&&) = default; template constexpr matrix_base& operator=(const matrix_base& m); //Getters/Setters 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; constexpr size_type rows()const; constexpr size_type size()const; constexpr pointer raw(); constexpr const_pointer raw()const; constexpr operator pointer(); constexpr operator const_pointer()const; }; template class matrix : public matrix_base { private: using base = matrix_base; public: using value_type = typename base::value_type; using size_type = typename base::size_type; using pointer = typename base::pointer; using const_pointer = typename base::const_pointer; using reference = typename base::reference; using const_reference = typename base::const_reference; public: using base::base; constexpr matrix(const matrix&) = default; constexpr matrix(matrix&&) = default; ~matrix() = default; //Assignement constexpr matrix& operator=(const matrix&) = default; constexpr matrix& operator=(matrix&&) = default; template constexpr matrix& operator=(const matrix& m); }; template class matrix : public matrix_base { private: using base = matrix_base; public: using value_type = typename base::value_type; using size_type = typename base::size_type; using pointer = typename base::pointer; using const_pointer = typename base::const_pointer; using reference = typename base::reference; using const_reference = typename base::const_reference; public: using base::base; constexpr matrix(const matrix&) = default; constexpr matrix(matrix&&) = default; constexpr explicit matrix(detail::id_initialize_t); ~matrix() = default; //Assignement constexpr matrix& operator=(const matrix&) = default; constexpr matrix& operator=(matrix&&) = default; template constexpr matrix& operator=(const matrix& m); //square matrix arithmetic operations constexpr value_type determinate()const; constexpr value_type trace()const; constexpr matrix transpose()const; constexpr matrix inverse()const; }; template constexpr T determinate(const matrix& m); template constexpr matrix inverse(const matrix& m); template matrix rotation2d_pure(T angle); template constexpr matrix rotation2d_pure(T sin, T cos); template constexpr matrix scale2d(T x, T y); template matrix rotation2d(T angle); template constexpr matrix rotation2d(T sin, T cos); template matrix rotation2d(T x, T y, T z); template matrix fov_projection(T fov, T asp, T near, T far); template matrix fov_asymetric_projection(T fovl, T fovr, T fovb, T fovt, T asp, T near, T far); template matrix ortho_projection(T w, T h, T n, T f); template matrix ortho_asymetric_projection(T l, T r, T b, T t, T n, T f); template constexpr matrix rotation3d(T angle_x, T angle_y, T angle_z); template constexpr matrix translation3d(T x, T y, T z); template constexpr matrix scale3d(T x, T y, T z); namespace detail{ template struct is_matrix_helper { template static std::true_type test(matrix_base*); static std::false_type test(void*); static constexpr bool value = std::is_same*>(nullptr)))>::value; }; } template struct is_matrix { static constexpr bool value = (detail::is_matrix_helper::value && ...); }; namespace detail{ template struct are_same_size_matrix { using l = std::decay_t; using r = std::decay_t; static constexpr bool value = is_matrix::value && l::Columns == r::Columns && l::Rows == r::Rows; }; template using enable_if_matrix = std::enable_if_t::value,int>; template using enable_if_eq_matrix = std::enable_if_t::value,int>; } template constexpr bool operator==(const matrix_base& left, const matrix_base right); template constexpr bool operator!=(const matrix_base& left, const matrix_base right); template constexpr auto operator*(const matrix& left, const matrix& right); template::value,int> = 0> constexpr auto operator*(const matrix& left, U&& right); template::value,int> = 0> constexpr auto operator*(U&& left, const matrix& right); template::value,int> = 0> 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::value,int> = 0> constexpr decltype(auto) operator*=(matrix& left, U&& right); template::value,int> = 0> 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); } #include "mat.tpp" #endif