From 56e9f634d5dd4122278a8f1c5f8e9fe39ed3652e Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 5 Jul 2016 05:50:58 +0200 Subject: api/simple-mat: cleanups --- opentrack/simple-mat.hpp | 115 ++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 50 deletions(-) (limited to 'opentrack') diff --git a/opentrack/simple-mat.hpp b/opentrack/simple-mat.hpp index 8dc03014..c8e7d903 100644 --- a/opentrack/simple-mat.hpp +++ b/opentrack/simple-mat.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, Stanislaw Halik +/* Copyright (c) 2014-2016, Stanislaw Halik * Permission to use, copy, modify, and/or distribute this * software for any purpose with or without fee is hereby granted, @@ -7,13 +7,17 @@ */ #pragma once + +#include "export.hpp" + #include #include #include +#include namespace { // last param to fool SFINAE into overloading - template + template struct equals { enum { value = i == j }; @@ -49,19 +53,12 @@ namespace { } template -class Mat +class OPENTRACK_API_EXPORT Mat { - num data[h_][w_]; - static_assert(h_ > 0 && w_ > 0, "must have positive mat dimensions"); - - Mat(std::initializer_list&& xs) = delete; + num data[h_][w_]; public: - - // parameters w_ and h_ are rebound so that SFINAE occurs - // removing them causes a compile-time error -sh 20150811 - template typename std::enable_if::value, num>::type inline operator()(int i) const { return data[i][0]; } @@ -74,33 +71,40 @@ public: template typename std::enable_if::value, num&>::type inline operator()(int i) { return data[0][i]; } +#define OPENTRACK_ASSERT_SWIZZLE static_assert(P == h_ && Q == w_, "") + template typename std::enable_if::value, num>::type - inline x() const { return operator()(0); } + x() const { OPENTRACK_ASSERT_SWIZZLE; return operator()(0); } template typename std::enable_if::value, num>::type - inline y() const { return operator()(1); } + y() const { OPENTRACK_ASSERT_SWIZZLE; return operator()(1); } template typename std::enable_if::value, num>::type - inline z() const { return operator()(2); } + z() const { OPENTRACK_ASSERT_SWIZZLE; return operator()(2); } template typename std::enable_if::value, num>::type - inline w() const { return operator()(3); } + w() const { OPENTRACK_ASSERT_SWIZZLE; return operator()(3); } template typename std::enable_if::value, num&>::type - inline x() { return operator()(0); } + x() { OPENTRACK_ASSERT_SWIZZLE; return operator()(0); } template typename std::enable_if::value, num&>::type - inline y() { return operator()(1); } + y() { OPENTRACK_ASSERT_SWIZZLE; return operator()(1); } template typename std::enable_if::value, num&>::type - inline z() { return operator()(2); } + z() { OPENTRACK_ASSERT_SWIZZLE; return operator()(2); } template typename std::enable_if::value, num&>::type - inline w() { return operator()(3); } + w() { OPENTRACK_ASSERT_SWIZZLE; return operator()(3); } + // parameters w_ and h_ are rebound so that SFINAE occurs + // removing them causes a compile-time error -sh 20150811 template typename std::enable_if::value, num>::type - dot(const Mat& p2) const { + dot(const Mat& p2) const + { + static_assert(P == h_ && Q == w_, ""); + num ret = 0; constexpr int len = vector_len::value; for (int i = 0; i < len; i++) @@ -112,9 +116,12 @@ public: typename std::enable_if::value, Mat::P, is_dim3::Q>>::type cross(const Mat& p2) const { - return Mat(y() * p2.z() - p2.y() * z(), - p2.x() * z() - x() * p2.z(), - x() * p2.y() - y() * p2.x()); + static_assert(P == h_ && Q == w_, ""); + decltype(*this)& p1 = *this; + + return Mat(p1.y() * p2.z() - p2.y() * p1.z(), + p2.x() * p1.z() - p1.x() * p2.z(), + p1.x() * p2.y() - p1.y() * p2.x()); } Mat operator+(const Mat& other) const @@ -153,15 +160,6 @@ public: return ret; } - Mat operator*(const num other) const - { - Mat ret; - for (int j = 0; j < h_; j++) - for (int i = 0; i < w_; i++) - ret(j, i) = data[j][i] * other; - return ret; - } - template Mat operator*(const Mat& other) const { @@ -183,11 +181,11 @@ public: typename = typename std::enable_if::value>::type> Mat(const ts... xs) { - const std::initializer_list init = { static_cast(xs)... }; - auto iter = init.begin(); - for (int j = 0; j < h_; j++) - for (int i = 0; i < w_; i++) - data[j][i] = *iter++; + static_assert(h__ == h_ && w__ == w_, ""); + + std::initializer_list init = { static_cast(xs)... }; + + *this = Mat(std::move(init)); } Mat() @@ -204,16 +202,25 @@ public: data[j][i] = mem[i*h_+j]; } - Mat(num* mem) : Mat(const_cast(mem)) {} + Mat(std::initializer_list&& init) + { + auto iter = init.begin(); + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) + data[j][i] = *iter++; + } - operator num*() { return reinterpret_cast(data); } - operator const num*() const { return reinterpret_cast(data); } + operator num*() { return reinterpret_cast(data); } + operator const num*() const { return reinterpret_cast(data); } // XXX add more operators as needed, third-party dependencies mostly // not needed merely for matrix algebra -sh 20141030 - static Mat eye() + template + static typename std::enable_if>::type eye() { + static_assert(h_ == h__, ""); + Mat ret; for (int j = 0; j < h_; j++) for (int i = 0; i < w_; i++) @@ -237,7 +244,23 @@ public: } }; -#include "export.hpp" +template using dmat = Mat; + +template +Mat operator*(num scalar, const Mat& mat) +{ + return mat * scalar; +} + +template +Mat operator*(const Mat& self, num other) +{ + Mat ret; + for (int j = 0; j < h_; j++) + for (int i = 0; i < w_; i++) + ret(j, i) = self(j, i) * other; + return ret; +} namespace euler { @@ -251,11 +274,3 @@ rmat OPENTRACK_API_EXPORT euler_to_rmat(const double* input); euler_t OPENTRACK_API_EXPORT rmat_to_euler(const dmat<3, 3>& R); } // end ns euler - -template using dmat = Mat; - -template -inline Mat operator*(num scalar, const Mat& mat) -{ - return mat * scalar; -} -- cgit v1.2.3