diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh index 8df3fafe..3f3b212d 100644 --- a/src/OpenMesh/Core/Geometry/Vector11T.hh +++ b/src/OpenMesh/Core/Geometry/Vector11T.hh @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -203,11 +204,10 @@ class VectorT { /// component-wise self-multiplication with scalar template - typename std::enable_if() * std::declval()), - Scalar>::value, - VectorT&>::type - operator*=(const OtherScalar& _s) { + auto operator*=(const OtherScalar& _s) -> + typename std::enable_ifvalues_[0] * _s), Scalar>::value, + VectorT&>::type { std::transform(values_.begin(), values_.end(), values_.begin(), [&_s](const Scalar & c) { return c * _s; }); return *this; @@ -216,23 +216,16 @@ class VectorT { /** component-wise self-division by scalar \attention v *= (1/_s) is much faster than this */ template - typename std::enable_if() / std::declval()), - Scalar>::value, - VectorT&>::type - operator/=(const OtherScalar& _s) { + auto operator/=(const OtherScalar& _s) -> + typename std::enable_ifvalues_[0] / _s), Scalar>::value, + VectorT&>::type { std::transform(values_.begin(), values_.end(), values_.begin(), [&_s](const Scalar & c) { return c / _s; }); return *this; } /// component-wise multiplication with scalar - //template() * - // std::declval())> - //VectorT operator*(const OtherScalar& _s) const { - // return vector_type(*this) *= _s; - //} template typename std::enable_if() * std::declval()), @@ -255,10 +248,12 @@ class VectorT { //---------------------------------------------------------- vector operators /// component-wise self-multiplication - template() * - std::declval())> - vector_type& operator*=(const VectorT& _rhs) { + template + auto operator*=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0, + vector_type&>::type { + std::transform(data(), data() + DIM, _rhs.data(), data(), [](const Scalar &l, const OtherScalar &r) { return l * r; }); @@ -266,10 +261,11 @@ class VectorT { } /// component-wise self-division - template() / - std::declval())> - vector_type& operator/=(const VectorT& _rhs) { + template + auto operator/=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0, + vector_type&>::type { std::transform(data(), data() + DIM, _rhs.data(), data(), [](const Scalar &l, const OtherScalar &r) { return l / r; }); @@ -277,10 +273,11 @@ class VectorT { } /// vector difference from this - template() - - std::declval())> - vector_type& operator-=(const VectorT& _rhs) { + template + auto operator-=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0, + vector_type&>::type { std::transform(data(), data() + DIM, _rhs.data(), data(), [](const Scalar &l, const OtherScalar &r) { return l - r; }); @@ -288,10 +285,11 @@ class VectorT { } /// vector self-addition - template() + - std::declval())> - vector_type& operator+=(const VectorT& _rhs) { + template + auto operator+=(const VectorT& _rhs) -> + typename std::enable_if< + sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0, + vector_type&>::type { std::transform(data(), data() + DIM, _rhs.data(), data(), [](const Scalar &l, const OtherScalar &r) { return l + r; }); @@ -299,66 +297,71 @@ class VectorT { } /// component-wise vector multiplication - template() *= - std::declval&>())> - vector_type operator*(const VectorT& _rhs) const { + template + auto operator*(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] * *_rhs.data())) >= 0, + vector_type>::type { return vector_type(*this) *= _rhs; } /// component-wise vector division - template() /= - std::declval&>())> - vector_type operator/(const VectorT& _rhs) const { + template + auto operator/(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] / *_rhs.data())) >= 0, + vector_type>::type { return vector_type(*this) /= _rhs; } /// component-wise vector addition - template() += - std::declval&>())> - vector_type operator+(const VectorT& _rhs) const { + template + auto operator+(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] + *_rhs.data())) >= 0, + vector_type>::type { return vector_type(*this) += _rhs; } /// component-wise vector difference - template() -= - std::declval&>())> - vector_type operator-(const VectorT& _rhs) const { + template + auto operator-(const VectorT& _rhs) const -> + typename std::enable_if< + sizeof(decltype(this->values_[0] - *_rhs.data())) >= 0, + vector_type>::type { return vector_type(*this) -= _rhs; } /// unary minus vector_type operator-(void) const { vector_type v; - std::transform(v.values_.begin(), v.values_.end(), v.values_.begin(), + std::transform(values_.begin(), values_.end(), v.values_.begin(), [](const Scalar &s) { return -s; }); return v; } /// cross product: only defined for Vec3* as specialization /// \see OpenMesh::cross - template() * std::declval() - - std::declval() * std::declval())> - typename std::enable_if>::type - operator% (const VectorT &_rhs) const { - return VectorT( - values_[1] * _rhs.values_[2] - values_[2] * _rhs.values_[1], - values_[2] * _rhs.values_[0] - values_[0] * _rhs.values_[2], - values_[0] * _rhs.values_[1] - values_[1] * _rhs.values_[0]); + template + auto operator% (const VectorT &_rhs) const -> + typename std::enable_ifvalues_[0] * _rhs[0] - + this->values_[0] * _rhs[0]), + DIM>>::type { + return { + values_[1] * _rhs[2] - values_[2] * _rhs[1], + values_[2] * _rhs[0] - values_[0] * _rhs[2], + values_[0] * _rhs[1] - values_[1] * _rhs[0] + }; } /// compute scalar product /// \see OpenMesh::dot - template() * std::declval())> - ResultScalar operator|(const VectorT& _rhs) const { - ResultScalar p = values_[0] * _rhs[0]; + template + auto operator|(const VectorT& _rhs) const -> + decltype(this->values_[0] * _rhs[0]) { + + auto p = values_[0] * _rhs[0]; for (int i = 1; i < DIM; ++i) { p += values_[i] * _rhs[i]; } @@ -379,11 +382,11 @@ class VectorT { } /// compute euclidean norm - decltype(std::sqrt(std::declval().sqrnorm())) norm() const { + auto norm() const -> decltype(std::sqrt(this->sqrnorm())) { return std::sqrt(sqrnorm()); } - decltype(std::declval().norm()) length() const { + auto length() const -> decltype(this->norm()) { return norm(); } @@ -396,8 +399,7 @@ class VectorT { /** return normalized vector */ - decltype(std::declval() / std::declval().norm()) - normalized() const { + auto normalized() const -> decltype((*this) / this->norm()) { return *this / norm(); } @@ -575,23 +577,22 @@ class VectorT { values_.begin(), values_.end(), _rhs.values_.begin(), _rhs.values_.end()); } - - public: - /// Component wise multiplication from the left - template - friend - decltype(std::declval().operator*(std::declval())) - operator*(const OtherScalar& _s, const vector_type &rhs) { - return rhs * _s; - } }; +/// Component wise multiplication from the left +template +auto operator*(const OtherScalar& _s, const VectorT &rhs) -> + decltype(rhs.operator*(_s)) { + + return rhs * _s; +} + /// output a vector by printing its space-separated compontens template -typename std::enable_if() << - std::declval())) >= 0, std::ostream&>::type -operator<<(std::ostream& os, const VectorT &_vec) { +auto operator<<(std::ostream& os, const VectorT &_vec) -> + typename std::enable_if< + sizeof(decltype(os << _vec[0])) >= 0, std::ostream&>::type { + os << _vec[0]; for (int i = 1; i < DIM; ++i) { os << " " << _vec[i]; @@ -601,10 +602,9 @@ operator<<(std::ostream& os, const VectorT &_vec) { /// read the space-separated components of a vector from a stream template -typename std::enable_if() >> - std::declval())) >= 0, std::istream&>::type -operator>> (std::istream& is, VectorT &_vec) { +auto operator>> (std::istream& is, VectorT &_vec) -> + typename std::enable_if< + sizeof(decltype(is >> _vec[0])) >= 0, std::istream &>::type { for (int i = 0; i < DIM; ++i) is >> _vec[i]; return is; @@ -613,8 +613,7 @@ operator>> (std::istream& is, VectorT &_vec) { /// \relates OpenMesh::VectorT /// symmetric version of the dot product template -Scalar -dot(const VectorT& _v1, const VectorT& _v2) { +Scalar dot(const VectorT& _v1, const VectorT& _v2) { return (_v1 | _v2); } @@ -622,9 +621,9 @@ dot(const VectorT& _v1, const VectorT& _v2) { /// \relates OpenMesh::VectorT /// symmetric version of the cross product template -decltype(std::declval&>() % - std::declval&>()) -cross(const VectorT& _v1, const VectorT& _v2) { +auto +cross(const VectorT& _v1, const VectorT& _v2) -> + decltype(_v1 % _v2) { return (_v1 % _v2); }