Clean up some of the concept jank

This commit is contained in:
rexy712 2022-02-18 17:46:17 -08:00
parent 3a2e1c27a4
commit 106c7009b5
10 changed files with 68 additions and 117 deletions

View File

@ -21,8 +21,7 @@
#include <cstdlib> //size_t
#include <utility> //integer_sequence
#include "../scalar.hpp"
#include "../fwd_declare.hpp"
namespace math::detail{

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -19,7 +19,7 @@
#ifndef REXY_DETAIL_MATH_HPP
#define REXY_DETAIL_MATH_HPP
#include "scalar.hpp"
#include "fwd_declare.hpp"
namespace math{

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;