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