/* * This file is part of libgim. * * libgim is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * libgim is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with libgim. If not, see . * * Copyright 2012-2015 Danny Robson */ #ifndef __UTIL_COORDS_OPS #define __UTIL_COORDS_OPS #include "preprocessor.hpp" #include namespace util { // forward declerations for traits template class point; template class extent; template class vector; /////////////////////////////////////////////////////////////////////// // operation traits namespace coord { template < size_t S, typename T, template class A, template class B > struct traits { }; //------------------------------------------------------------------------- template struct traits { typedef extent result; }; template struct traits { typedef extent result; }; template struct traits { typedef point result; }; template struct traits { typedef point result; }; template struct traits { typedef vector result; }; } /////////////////////////////////////////////////////////////////////////// // vector operators #define ELEMENT_OP(OP) \ template < \ size_t S, \ typename T, \ template class A, \ template class B \ > \ typename coord::traits::result \ operator OP (A a, B b) \ { \ typename coord::traits::result out; \ for (size_t i = 0; i < S; ++i) \ out[i] = a[i] OP b[i]; \ return out; \ } \ \ template < \ size_t S, \ typename T, \ template class A, \ template class B \ > \ typename coord::traits::result& \ operator PASTE(OP,=) (A& a, B b) \ { \ for (size_t i = 0; i < S; ++i) \ a[i] PASTE(OP,=) b[i]; \ return a; \ } ELEMENT_OP(+) ELEMENT_OP(-) ELEMENT_OP(*) ELEMENT_OP(/) #undef ELEMENT_OP /////////////////////////////////////////////////////////////////////////// // scalar operators #define SCALAR_OP(OP) \ template < \ size_t S, \ typename T, \ template class K \ > \ K \ operator OP (T t, K k) \ { \ K out; \ for (size_t i = 0; i < S; ++i) \ out[i] = t OP k[i]; \ return out; \ } \ \ template < \ size_t S, \ typename T, \ template class K \ > \ K \ operator OP (K k, T t) \ { \ K out; \ for (size_t i = 0; i < S; ++i) \ out[i] = t OP k[i]; \ return out; \ } SCALAR_OP(+) SCALAR_OP(-) SCALAR_OP(*) SCALAR_OP(/) #undef SCALAR_OP #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_OP(+=) SCALAR_OP(-=) SCALAR_OP(*=) SCALAR_OP(/=) #undef SCALAR_OP /////////////////////////////////////////////////////////////////////////// // logic operators template < size_t S, typename T, template class K > bool operator== (K a, K b) { return std::equal (std::begin (a), std::end (a), std::begin (b)); } //------------------------------------------------------------------------- template < size_t S, typename T, template class K > bool operator!= (K a, K b) { return !(a == b); } /////////////////////////////////////////////////////////////////////////// // special operators template < size_t S, typename T > vector operator- (point a, point b) { vector out; for (size_t i = 0; i < S; ++i) out[i] = a[i] - b[i]; return out; } //------------------------------------------------------------------------- template < size_t S, typename T, template class A, template class B > T dot (A a, B b) { T sum { 0 }; for (size_t i = 0; i < S; ++i) sum += a[i] * b[i]; return sum; } } #endif