diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2019-02-11 18:42:08 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-02-11 20:21:35 +0100 |
commit | 9e748ac687e905f55f7ee013bc5499b31c8a030d (patch) | |
tree | 24d723d5d66a2cd1f9b88b94711ca682f25bbf23 /compat | |
parent | 24f8f904f3975832b77e18957dc41d2372deebc5 (diff) |
compat/simple-mat: more constexpr
Diffstat (limited to 'compat')
-rw-r--r-- | compat/simple-mat.hpp | 78 |
1 files changed, 32 insertions, 46 deletions
diff --git a/compat/simple-mat.hpp b/compat/simple-mat.hpp index d42a2fe8..43d136f9 100644 --- a/compat/simple-mat.hpp +++ b/compat/simple-mat.hpp @@ -8,13 +8,11 @@ #pragma once -#include "export.hpp" - #include <type_traits> #include <utility> #include <cmath> -namespace simple_mat_detail { +namespace simple_mat { // last param to fool SFINAE into overloading template<int i, int j, int> struct equals @@ -67,17 +65,17 @@ public: // parameters w_ and h_ are rebound so that SFINAE occurs // removing them causes a compile-time error -sh 20150811 - template<int Q = w_> std::enable_if_t<equals<Q, 1, 0>::value, num> - constexpr inline operator()(unsigned i) const& { return data[i][0]; } + template<typename t, int Q = w_> std::enable_if_t<equals<Q, 1, 0>::value, num> + constexpr inline operator()(t i) const& { return data[(unsigned)i][0]; } - template<int P = h_> std::enable_if_t<equals<P, 1, 1>::value, num> - constexpr inline operator()(unsigned i) const& { return data[0][i]; } + template<typename t, int P = h_> std::enable_if_t<equals<P, 1, 1>::value, num> + constexpr inline operator()(t i) const& { return data[0][(unsigned)i]; } - template<int Q = w_> std::enable_if_t<equals<Q, 1, 2>::value, num&> - constexpr inline operator()(unsigned i) & { return data[i][0]; } + template<typename t, int Q = w_> std::enable_if_t<equals<Q, 1, 2>::value, num&> + constexpr inline operator()(t i) & { return data[(unsigned)i][0]; } - template<int P = h_> std::enable_if_t<equals<P, 1, 3>::value, num&> - constexpr inline operator()(unsigned i) & { return data[0][i]; } + template<typename t, int P = h_> std::enable_if_t<equals<P, 1, 3>::value, num&> + constexpr inline operator()(t i) & { return data[0][(unsigned)i]; } #define OTR_MAT_ASSERT_SWIZZLE static_assert(P == h_ && Q == w_) @@ -105,35 +103,25 @@ public: constexpr inline z() & { OTR_MAT_ASSERT_SWIZZLE; return operator()(2); } template<int P = h_, int Q = w_> std::enable_if_t<maybe_add_swizzle<P, Q, 4, 4>::value, num&> - - template<int h_pos, int w_pos> - constexpr Mat<num, h_ - h_pos, w_ - w_pos> slice() const - { - return (const double*)*this; - } - - template<int off> std::enable_if_t<equals<h_, 1, 0>::value, Mat<num, 1, w_ - off>> - slice() const { return ((double const*)*this) + off; } - - template<int off> std::enable_if_t<!equals<h_, 1, 2>::value && equals<w_, 1, 1>::value, - Mat<num, h_ - off, 1>> - slice() const { return ((double const*)*this) + off; } constexpr inline w() & { OTR_MAT_ASSERT_SWIZZLE; return operator()(3); } template<int P = h_, int Q = w_> - std::enable_if_t<is_vector<P, Q>::value, num> - norm() const + constexpr auto norm_squared() const -> std::enable_if_t<is_vector<P, Q>::value, num> { static_assert(P == h_ && Q == w_); const num val = dot(*this); + constexpr num eps = num(1e-4); - if (val < num(1e-4)) + if (val < eps) return num(0); else - return std::sqrt(val); + return val; } + template<int P = h_, int Q = w_> + inline auto norm() const { return num(std::sqrt(norm_squared())); } + template<int R, int S, int P = h_, int Q = w_> std::enable_if_t<is_vector_pair<R, S, P, Q>::value, num> constexpr dot(const Mat<num, R, S>& p2) const @@ -152,7 +140,7 @@ public: constexpr cross(const Mat<num, R, S>& b) const { static_assert(P == h_ && Q == w_); - auto& a = *this; + const auto& a = *this; return Mat<num, R, S>(a.y()*b.z() - a.z()*b.y(), a.z()*b.x() - a.x()*b.z(), @@ -221,15 +209,10 @@ public: } template<typename t, typename u> - constexpr inline num operator()(t j, u i) const& { return data[(int) j][(int) i]; } + constexpr inline num operator()(t j, u i) const& { return data[(unsigned)j][(unsigned)i]; } template<typename t, typename u> - constexpr inline num& operator()(t j, u i) & { return data[(int) j][(int) i]; } - -#ifdef __GNUG__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmissing-braces" -#endif + constexpr inline num& operator()(t j, u i) & { return data[(unsigned)j][(unsigned)i]; } template<typename... ts, int h__ = h_, int w__ = w_, typename = std::enable_if_t<is_arglist_correct<num, h__, w__, ts...>::value>> @@ -238,10 +221,6 @@ public: static_assert(h__ == h_ && w__ == w_); } -#ifdef __GNUG__ -# pragma GCC diagnostic pop -#endif - constexpr Mat() { for (int j = 0; j < h_; j++) @@ -256,8 +235,8 @@ public: data[j][i] = mem[i*h_+j]; } - operator num*() { return reinterpret_cast<num*>(data); } - operator const num*() const { return reinterpret_cast<const num*>(data); } + constexpr operator num*() & { return (num*)data; } + constexpr operator const num*() const& { return (const num*)data; } // XXX add more operators as needed, third-party dependencies mostly // not needed merely for matrix algebra -sh 20141030 @@ -288,6 +267,15 @@ public: return ret; } + + constexpr Mat<num, w_, h_>& operator=(const Mat<num, w_, h_>& rhs) + { + for (unsigned j = 0; j < h_; j++) + for (unsigned i = 0; i < w_; i++) + data[j][i] = rhs(j, i); + + return *this; + } }; template<typename num, int h, int w> @@ -318,9 +306,7 @@ OTR_GENERIC_EXPORT inline void test() } #endif -} // ns simple_mat_detail +} // ns detail template<typename num, int h, int w> -using Mat = simple_mat_detail::Mat<num, h, w>; - - +using Mat = simple_mat::Mat<num, h, w>; |