From 60f16cdc4ad53d05ef9f8b8e691ac39a8d6dfc58 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 19 Oct 2015 17:06:19 +1100 Subject: [PATCH] WIP coord: clean up operation templates --- coord/ops.hpp | 167 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 112 insertions(+), 55 deletions(-) diff --git a/coord/ops.hpp b/coord/ops.hpp index 14d5257b..ac2686f0 100644 --- a/coord/ops.hpp +++ b/coord/ops.hpp @@ -35,22 +35,19 @@ namespace util { // operation traits namespace coord { template < - size_t S, - typename T, - typename U, template class A, template class B > struct traits { }; //------------------------------------------------------------------------- - template struct traits { typedef colour::type> result; }; - template struct traits { typedef extent::type> result; }; - template struct traits { typedef extent::type> result; }; - template struct traits { typedef point ::type> result; }; - template struct traits { typedef point ::type> result; }; - template struct traits { typedef point ::type> result; }; - template struct traits { typedef vector::type> result; }; + template <> struct traits { template using result = colour; }; + template <> struct traits { template using result = extent; }; + template <> struct traits { template using result = extent; }; + template <> struct traits { template using result = point ; }; + template <> struct traits { template using result = point ; }; + template <> struct traits { template using result = point ; }; + template <> struct traits { template using result = vector; }; } /////////////////////////////////////////////////////////////////////////// @@ -63,10 +60,12 @@ namespace util { template class A, \ template class B \ > \ - typename coord::traits::result \ + auto \ operator OP (A a, B b) \ { \ - typename coord::traits::result out; \ + typename coord::traits::template result< \ + S,typename std::common_type::type \ + > out; \ for (size_t i = 0; i < S; ++i) \ out[i] = a[i] OP b[i]; \ return out; \ @@ -75,11 +74,18 @@ namespace util { template < \ size_t S, \ typename T, \ + typename U, \ template class A, \ template class B \ > \ - typename coord::traits::result& \ - operator PASTE(OP,=) (A& a, B b) \ + typename std::enable_if< \ + std::is_same< \ + typename std::common_type::type, \ + T \ + >::value, \ + A \ + >::type& \ + operator PASTE(OP,=) (A& a, B b) \ { \ for (size_t i = 0; i < S; ++i) \ a[i] PASTE(OP,=) b[i]; \ @@ -95,37 +101,35 @@ namespace util { /////////////////////////////////////////////////////////////////////////// // scalar operators -#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; \ +#define SCALAR_OP(OP) \ + template < \ + size_t S, \ + typename T, \ + typename U, \ + template class K \ + > \ + auto \ + operator OP (U u, K k) \ + { \ + K::type> 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 \ + > \ + auto \ + operator OP (K k, U u) \ + { \ + K::type> out; \ + for (size_t i = 0; i < S; ++i) \ + out[i] = k[i] OP u; \ + return out; \ } SCALAR_OP(+) @@ -188,6 +192,32 @@ namespace util { } + /////////////////////////////////////////////////////////////////////////// + // unary operators + +#define UNARY_OP(OP) \ + template < \ + size_t S, \ + typename T, \ + template class K \ + > \ + auto \ + operator OP (K k) \ + { \ + K ())> out; \ + \ + for (size_t i = 0; i < S; ++i) \ + out[i] = OP k[i]; \ + \ + return k; \ + } + + UNARY_OP(!) + UNARY_OP(~) + +#undef UNARY_OP + + /////////////////////////////////////////////////////////////////////////// // logic operators @@ -336,31 +366,58 @@ namespace util { ///------------------------------------------------------------------------ - /// return the minimum element of the coordinate type template class K> T min (K k) { return *std::min_element (k.begin (), k.end ()); } - ///------------------------------------------------------------------------ - /// return the maximum element of the coordinate type template class K> T max (K k) { return *std::max_element (k.begin (), k.end ()); } - template class K> - bool - operator>= (K k, T t) - { return min (k) >= t; } + //------------------------------------------------------------------------- +#define SCALAR_OP(OP) \ + template < \ + size_t S, \ + typename T, \ + typename U, \ + template class K \ + > \ + K \ + operator OP (const K k, const U u) \ + { \ + K out; \ + for (size_t i = 0; i < S; ++i) \ + out[i] = k[i] OP u; \ + return out; \ + } + + SCALAR_OP(<) + SCALAR_OP(>) + SCALAR_OP(<=) + SCALAR_OP(>=) + +#undef SCALAR_OP - template class K> + //------------------------------------------------------------------------- + template class K> bool - operator<= (K k, T t) - { return max (k) <= t; } + any (const K k) + { + return std::any_of (k.begin (), k.end (), identity); + } + + //------------------------------------------------------------------------- + template class K> + bool + all (const K k) + { + return std::all_of (k.begin (), k.end (), identity); + } ///////////////////////////////////////////////////////////////////////////