Clean up some of the concept jank
This commit is contained in:
parent
3a2e1c27a4
commit
106c7009b5
@ -21,8 +21,7 @@
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <utility> //integer_sequence
|
||||
|
||||
#include "../scalar.hpp"
|
||||
#include "../fwd_declare.hpp"
|
||||
|
||||
namespace math::detail{
|
||||
|
||||
|
||||
@ -21,11 +21,44 @@
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <type_traits>
|
||||
#include "scalar.hpp"
|
||||
#include <concepts>
|
||||
|
||||
//Provide aliases for common matrix, vector, and quaternion types
|
||||
|
||||
namespace math{
|
||||
template<class... Ms>
|
||||
struct is_vector;
|
||||
template<class... Qs>
|
||||
struct is_quaternion;
|
||||
template<class... Ms>
|
||||
struct is_matrix;
|
||||
|
||||
template<class T>
|
||||
concept Quaternion = is_quaternion<T>::value;
|
||||
template<class T>
|
||||
concept Matrix = is_matrix<T>::value;
|
||||
template<class T>
|
||||
concept Vector = is_vector<T>::value;
|
||||
|
||||
template<class T>
|
||||
concept Scalar = !Matrix<T> && !Vector<T> && !Quaternion<T> && requires(std::decay_t<T> t){
|
||||
{t += t} -> std::convertible_to<T>;
|
||||
{t -= t} -> std::convertible_to<T>;
|
||||
{t /= t} -> std::convertible_to<T>;
|
||||
{t *= t} -> std::convertible_to<T>;
|
||||
{t + t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t - t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t / t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t * t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{-t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t > t} -> std::convertible_to<bool>;
|
||||
{t < t} -> std::convertible_to<bool>;
|
||||
{t >= t} -> std::convertible_to<bool>;
|
||||
{t <= t} -> std::convertible_to<bool>;
|
||||
{t == t} -> std::convertible_to<bool>;
|
||||
{t != t} -> std::convertible_to<bool>;
|
||||
};
|
||||
|
||||
template<Scalar T, size_t R, size_t C>
|
||||
class matrix_base;
|
||||
|
||||
@ -144,18 +177,6 @@ namespace math{
|
||||
static constexpr bool value = (detail::is_matrix_helper<Ms>::value && ...);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
concept Quaternion = is_quaternion<T>::value;
|
||||
template<class T>
|
||||
concept Matrix = is_matrix<T>::value;
|
||||
template<class T>
|
||||
concept Vector = is_vector<T>::value;
|
||||
|
||||
template<class T>
|
||||
concept NonQuat = !Matrix<T> && !Quaternion<T> && Scalar<T>;
|
||||
template<class T>
|
||||
concept NonMatrix = !Matrix<T> && !Quaternion<T> && Scalar<T>;
|
||||
|
||||
template<class T, class U>
|
||||
concept Compatible_Scalar = requires(T&& t, U&& u){
|
||||
requires !is_matrix<T>::value;
|
||||
|
||||
@ -200,11 +200,11 @@ namespace math{
|
||||
//Arithmetic operators
|
||||
template<Scalar T, Scalar U, size_t R1, size_t C1, size_t R2>
|
||||
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,R2>& right);
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr auto operator*(const matrix<T,R,C>& left, U&& right);
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr auto operator*(U&& left, const matrix<T,R,C>& right);
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr auto operator/(const matrix<T,R,C>& left, U&& right);
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
|
||||
@ -223,9 +223,9 @@ namespace math{
|
||||
//Arithmetic assignment operators
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right);
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right);
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right);
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
|
||||
|
||||
@ -309,7 +309,7 @@ namespace math{
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr auto operator*(const matrix<T,R,C>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
||||
matrix<res_t,R,C> res(no_initialize);
|
||||
@ -318,7 +318,7 @@ namespace math{
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr auto operator*(U&& left, const matrix<T,R,C>& right){
|
||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
||||
matrix<res_t,R,C> res(no_initialize);
|
||||
@ -327,7 +327,7 @@ namespace math{
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr auto operator/(const matrix<T,R,C>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() / std::declval<U>());
|
||||
matrix<res_t,R,C> res(no_initialize);
|
||||
@ -390,14 +390,14 @@ namespace math{
|
||||
//cannot be expression templatized, TODO
|
||||
return (left = (left * right));
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right){
|
||||
for(size_t i = 0; i < left.size(); ++i){
|
||||
left.get(i) = left.get(i) * std::forward<U>(right);
|
||||
}
|
||||
return left;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t C, size_t R>
|
||||
template<Scalar T, Scalar U, size_t C, size_t R>
|
||||
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right){
|
||||
for(size_t i = 0; i < left.size(); ++i){
|
||||
left.get(i) = left.get(i) / std::forward<U>(right);
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
#ifndef REXY_DETAIL_MATH_HPP
|
||||
#define REXY_DETAIL_MATH_HPP
|
||||
|
||||
#include "scalar.hpp"
|
||||
#include "fwd_declare.hpp"
|
||||
|
||||
namespace math{
|
||||
|
||||
|
||||
@ -125,9 +125,9 @@ namespace math{
|
||||
auto operator*(const quaternion<T>& left, const quaternion<U>& right);
|
||||
template<Scalar T, Scalar U>
|
||||
auto operator*(const quaternion<T>& left, const vec3<U>& right);
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
auto operator*(const quaternion<T>& left, U&& right);
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
auto operator/(const quaternion<T>& left, U&& right);
|
||||
|
||||
template<Scalar T, Scalar U>
|
||||
@ -136,9 +136,9 @@ namespace math{
|
||||
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right);
|
||||
template<Scalar T, Scalar U>
|
||||
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right);
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
decltype(auto) operator*=(quaternion<T>& left, U&& right);
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
decltype(auto) operator/=(quaternion<T>& left, U&& right);
|
||||
|
||||
}
|
||||
|
||||
@ -383,12 +383,12 @@ namespace math{
|
||||
auto operator*(const quaternion<T>& left, const vec3<U>& right){
|
||||
return left.to_mat3() * right;
|
||||
}
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
auto operator*(const quaternion<T>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
||||
return quaternion<res_t>(manual_initialize, left.w() * right, left.x() * right, left.y() * right, left.z() * right);
|
||||
}
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
auto operator/(const quaternion<T>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() / std::declval<U>());
|
||||
return quaternion<res_t>(manual_initialize, left.w() / right, left.x() / right, left.y() / right, left.z() / right);
|
||||
@ -415,7 +415,7 @@ namespace math{
|
||||
return left;
|
||||
}
|
||||
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
decltype(auto) operator*=(quaternion<T>& left, U&& right){
|
||||
left.w() *= right;
|
||||
left.x() *= right;
|
||||
@ -423,7 +423,7 @@ namespace math{
|
||||
left.z() *= right;
|
||||
return left;
|
||||
}
|
||||
template<Scalar T, NonQuat U>
|
||||
template<Scalar T, Scalar U>
|
||||
decltype(auto) operator/=(quaternion<T>& left, U&& right){
|
||||
left.w() /= right;
|
||||
left.x() /= right;
|
||||
|
||||
@ -1,69 +0,0 @@
|
||||
/**
|
||||
This file is a part of our_dick
|
||||
Copyright (C) 2022 rexy712
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_MATH_SCALAR_HPP
|
||||
#define REXY_MATH_SCALAR_HPP
|
||||
|
||||
#include <type_traits> //is_convertible
|
||||
#include <concepts> //convertible_to
|
||||
|
||||
namespace math{
|
||||
|
||||
template<class T>
|
||||
concept ConvertibleToIntegral =
|
||||
std::is_convertible_v<T,bool> ||
|
||||
std::is_convertible_v<T,char> ||
|
||||
std::is_convertible_v<T,char8_t> ||
|
||||
std::is_convertible_v<T,char16_t> ||
|
||||
std::is_convertible_v<T,char32_t> ||
|
||||
std::is_convertible_v<T,wchar_t> ||
|
||||
std::is_convertible_v<T,short> ||
|
||||
std::is_convertible_v<T,int> ||
|
||||
std::is_convertible_v<T,long> ||
|
||||
std::is_convertible_v<T,long long>;
|
||||
template<class T>
|
||||
concept ConvertibleToFloatingPoint =
|
||||
std::is_convertible_v<T,float> ||
|
||||
std::is_convertible_v<T,double> ||
|
||||
std::is_convertible_v<T,long double>;
|
||||
|
||||
template<class T>
|
||||
concept ConvertibleToArithmetic = ConvertibleToIntegral<T> || ConvertibleToFloatingPoint<T>;
|
||||
|
||||
|
||||
template<class T>
|
||||
concept Scalar = ConvertibleToArithmetic<T> && requires(std::decay_t<T> t){
|
||||
{t += t} -> std::convertible_to<T>;
|
||||
{t -= t} -> std::convertible_to<T>;
|
||||
{t /= t} -> std::convertible_to<T>;
|
||||
{t *= t} -> std::convertible_to<T>;
|
||||
{t + t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t - t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t / t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t * t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{-t} -> std::convertible_to<std::decay_t<T>>;
|
||||
{t > t} -> std::convertible_to<bool>;
|
||||
{t < t} -> std::convertible_to<bool>;
|
||||
{t >= t} -> std::convertible_to<bool>;
|
||||
{t <= t} -> std::convertible_to<bool>;
|
||||
{t == t} -> std::convertible_to<bool>;
|
||||
{t != t} -> std::convertible_to<bool>;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -42,7 +42,7 @@ namespace math{
|
||||
public:
|
||||
using base::base;
|
||||
|
||||
template<size_t TR,NonMatrix... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int> = 0>
|
||||
template<size_t TR,Scalar... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int> = 0>
|
||||
constexpr vector(const vector<T,TR>& other, Args&&... args);
|
||||
template<Scalar U>
|
||||
constexpr vector(const vector<U,R>& other);
|
||||
@ -77,7 +77,7 @@ namespace math{
|
||||
value_type magnitude(void)const;
|
||||
vector normalize(void);
|
||||
protected:
|
||||
template<NonMatrix U, NonMatrix... Args>
|
||||
template<Scalar U, Scalar... Args>
|
||||
constexpr void assign_(size_type offset, U&& u, Args&&... args);
|
||||
};
|
||||
|
||||
@ -95,11 +95,11 @@ namespace math{
|
||||
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right);
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator*(const vector<T,R>& left, const vector<U,R>& right);
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator*(const vector<T,R>& left, U&& right);
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator*(U&& left, const vector<T,R>& right);
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator/(const vector<T,R>& left, U&& right);
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator+(const vector<T,R>& left, const vector<U,R>& right);
|
||||
@ -108,9 +108,9 @@ namespace math{
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator-(const vector<T,R>& left);
|
||||
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right);
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right);
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right);
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
namespace math{
|
||||
|
||||
template<Scalar T, size_t R>
|
||||
template<size_t TR,NonMatrix... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int>>
|
||||
template<size_t TR,Scalar... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int>>
|
||||
constexpr vector<T,R>::vector(const vector<T,TR>& other, Args&&... args){
|
||||
static_assert(sizeof...(args) + TR <= R);
|
||||
size_type i = 0;
|
||||
@ -43,7 +43,7 @@ namespace math{
|
||||
}
|
||||
}
|
||||
template<Scalar T, size_t R>
|
||||
template<NonMatrix U, NonMatrix... Args>
|
||||
template<Scalar U, Scalar... Args>
|
||||
constexpr void vector<T,R>::assign_(size_type offset, U&& u, Args&&... args){
|
||||
this->m_data[offset] = std::forward<U>(u);
|
||||
if constexpr(sizeof...(args) > 0){
|
||||
@ -165,7 +165,7 @@ namespace math{
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator*(const vector<T,R>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() * std::declval<U>());
|
||||
vector<res_t,R> res(zero_initialize);
|
||||
@ -174,7 +174,7 @@ namespace math{
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator*(U&& left, const vector<T,R>& right){
|
||||
using res_t = decltype(std::declval<U>() * std::declval<T>());
|
||||
vector<res_t,R> res(zero_initialize);
|
||||
@ -183,7 +183,7 @@ namespace math{
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr auto operator/(const vector<T,R>& left, U&& right){
|
||||
using res_t = decltype(std::declval<T>() / std::declval<U>());
|
||||
vector<res_t,R> res(zero_initialize);
|
||||
@ -220,14 +220,14 @@ namespace math{
|
||||
return res;
|
||||
}
|
||||
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right){
|
||||
for(size_t i = 0; i < R; ++i){
|
||||
left[i] *= right;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
template<Scalar T, NonMatrix U, size_t R>
|
||||
template<Scalar T, Scalar U, size_t R>
|
||||
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right){
|
||||
for(size_t i = 0; i < R; ++i){
|
||||
left[i] /= right;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user