diff --git a/coord/ops.hpp b/coord/ops.hpp index ff6561f6..01ae3efe 100644 --- a/coord/ops.hpp +++ b/coord/ops.hpp @@ -95,35 +95,37 @@ namespace util { /////////////////////////////////////////////////////////////////////////// // scalar operators -#define SCALAR_OP(OP) \ - template < \ - size_t S, \ - typename T, \ - typename U, \ - template class K \ - > \ - typename std::enable_if::value, K>::type \ - operator OP (U u, K k) \ - { \ - K out; \ - for (size_t i = 0; i < S; ++i) \ - out[i] = u OP k[i]; \ - return out; \ - } \ - \ - template < \ - size_t S, \ - typename T, \ - typename U, \ - template class K \ - > \ - typename std::enable_if::value, K>::type \ - operator OP (K k, U u) \ - { \ - K out; \ - for (size_t i = 0; i < S; ++i) \ - out[i] = k[i] OP u; \ - return out; \ +#define SCALAR_OP(OP) \ + template < \ + size_t S, \ + typename T, \ + typename U, \ + template class K \ + > \ + K::type> \ + operator OP (U u, K k) \ + { \ + using out_t = typename std::common_type::type; \ + K out; \ + for (size_t i = 0; i < S; ++i) \ + out[i] = u OP k[i]; \ + return out; \ + } \ + \ + template < \ + size_t S, \ + typename T, \ + typename U, \ + template class K \ + > \ + K::type> \ + operator OP (K k, U u) \ + { \ + using out_t = typename std::common_type::type; \ + K out; \ + for (size_t i = 0; i < S; ++i) \ + out[i] = k[i] OP u; \ + return out; \ } SCALAR_OP(+) @@ -136,18 +138,28 @@ namespace util { //------------------------------------------------------------------------- -#define SCALAR_OP(OP) \ - template < \ - size_t S, \ - typename T, \ - template class K \ - > \ - K& \ - operator OP (K &k, T t) \ - { \ - for (size_t i = 0; i < S; ++i) \ - k[i] OP t; \ - return k; \ + // scalar assignment operators. + // + // we must check the operands/results do not need casting to store in the + // destination type to avoid silent errors accumulating. +#define SCALAR_OP(OP) \ + template < \ + size_t S, \ + typename T, \ + typename U, \ + template class K \ + > \ + typename std::enable_if< \ + std::is_same< \ + T, \ + typename std::common_type::type>::value, \ + K \ + >::type& \ + operator OP (K &k, U u) \ + { \ + for (size_t i = 0; i < S; ++i) \ + k[i] OP u; \ + return k; \ } SCALAR_OP(+=)