libpnicore
array_arithmetic.hpp
1 //
2 // (c) Copyright 2013 DESY, Eugen Wintersberger <eugen.wintersberger@desy.de>
3 //
4 // This file is part of libpnicore.
5 //
6 // libpnicore is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // libpnicore is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libpnicore. If not, see <http://www.gnu.org/licenses/>.
18 //
19 // ============================================================================
20 //
21 // Created on: Dec 2, 2013
22 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
23 //
24 #pragma once
25 
26 #include "mdarray.hpp"
27 #include "index_map/index_maps.hpp"
28 #include "../types/complex_utils.hpp"
29 #include "scalar.hpp"
30 #include "../algorithms.hpp"
31 #include "../utilities/sfinae_macros.hpp"
32 
33 namespace pni{
34 namespace core{
35 
42  template<typename T> struct is_array
43  {
48  };
49 
50  template<typename T>
51  using map_type = typename T::map_type;
52 
53  template<typename T>
54  using ipa_type = typename T::inplace_arithmetic;
55 
56 
57  //======================binary addition operator===========================
78  template<
79  typename LHS,
80  typename RHS,
82  >
83  mdarray<add_op<LHS,RHS>,map_type<LHS>,ipa_type<LHS>>
84  operator+(const LHS &a,const RHS &b)
85  {
86  typedef add_op<LHS,RHS> operator_type;
87  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> return_type;
88 
89  return return_type(a.map(),operator_type(a,b));
90  }
91 
92  //-------------------------------------------------------------------------
112  template<
113  typename LHS,
114  typename T,
115  typename = enable_if<and_t<
116  is_array<LHS>,not_t<is_array<T>>
117  >>
118  >
119  mdarray<add_op<LHS,scalar<T>>,map_type<LHS>,ipa_type<LHS>>
120  operator+(const LHS &a, const T& b)
121  {
122  typedef add_op<LHS,scalar<T>> operator_type;
123  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> return_type;
124 
125  return return_type(a.map(),operator_type(a,b));
126  }
127 
128  //-------------------------------------------------------------------------
148  template<
149  typename T,
150  typename RHS,
151  typename = enable_if<and_t<
152  not_t<is_array<T>>,is_array<RHS>
153  >>
154  >
155  mdarray<add_op<scalar<T>,RHS>,map_type<RHS>,ipa_type<RHS>>
156  operator+(const T& a, const RHS &b)
157  {
158  typedef add_op<scalar<T>,RHS> operator_type;
159  typedef mdarray<operator_type,map_type<RHS>,ipa_type<RHS>> result_type;
160  typedef scalar<T> scalar_type;
161 
162  return result_type(b.map(),operator_type(scalar_type(a),b));
163  }
164 
165  //======================binary subtraction operator========================
186  template<
187  typename LHS,
188  typename RHS,
189  typename = enable_if<and_t<is_array<LHS>,is_array<RHS>>>
190  >
191  mdarray<sub_op<LHS,RHS >,map_type<LHS>,ipa_type<LHS>>
192  operator-(const LHS &a, const RHS &b)
193  {
194  typedef sub_op<LHS,RHS> operator_type;
195  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> result_type;
196 
197  return result_type(a.map(),operator_type(a,b));
198  }
199 
200  //-------------------------------------------------------------------------
220  template<
221  typename LHS,
222  typename T,
223  typename = enable_if<and_t<
224  is_array<LHS>,not_t<is_array<T>>
225  >>
226  >
227  mdarray<sub_op<LHS,scalar<T> >,map_type<LHS>,ipa_type<LHS>>
228  operator-(const LHS &a, const T& b)
229  {
230  typedef sub_op<LHS,scalar<T>> operator_type;
231  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> result_type;
232 
233  return result_type(a.map(),operator_type(a,b));
234  }
235 
236  //-------------------------------------------------------------------------
256  template<
257  typename T,
258  typename RHS,
259  typename = enable_if<and_t<
260  not_t<is_array<T>>,is_array<RHS>
261  >>
262  >
263  mdarray<sub_op<scalar<T>,RHS>,map_type<RHS>,ipa_type<RHS>>
264  operator-(const T &a, const RHS &b)
265  {
266  typedef sub_op<scalar<T>,RHS> operator_type;
267  typedef mdarray<operator_type,map_type<RHS>,ipa_type<RHS>> result_type;
268 
269  return result_type(b.map(),operator_type(a,b));
270  }
271 
272  //=================binary division operator================================
292  template<
293  typename LHS,
294  typename RHS,
295  typename = enable_if<and_t<is_array<LHS>,is_array<RHS>>>
296  >
297  mdarray<div_op<LHS,RHS>,map_type<LHS>,ipa_type<LHS>>
298  operator/(const LHS &a, const RHS &b)
299  {
300  typedef div_op<LHS,RHS> operator_type;
301  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> result_type;
302 
303  return result_type(a.map(),operator_type(a,b));
304  }
305 
306  //-------------------------------------------------------------------------
326  template<
327  typename LHS,
328  typename T,
329  typename = enable_if<and_t<
330  is_array<LHS>,not_t<is_array<T>>
331  >>
332  >
333  mdarray<div_op<LHS,scalar<T>>,map_type<LHS>,ipa_type<LHS>>
334  operator/(const LHS &a, const T &b)
335  {
336  typedef div_op<LHS,scalar<T>> operator_type;
337  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> result_type;
338 
339  return result_type(a.map(),operator_type(a,b));
340  }
341 
342  //-------------------------------------------------------------------------
362  template<
363  typename T,
364  typename RHS,
365  typename = enable_if<and_t<
366  not_t<is_array<T>>,is_array<RHS>
367  >>
368  >
369  mdarray<div_op<scalar<T>,RHS>,map_type<RHS>,ipa_type<RHS>>
370  operator/(const T &a, const RHS &b)
371  {
372  typedef div_op<scalar<T>,RHS> operator_type;
373  typedef mdarray<operator_type,map_type<RHS>,ipa_type<RHS>> result_type;
374 
375  return result_type(b.map(),operator_type(a,b));
376  }
377 
378  //===================Multiplication operator================================
397  template<
398  typename LHS,
399  typename RHS,
400  typename = enable_if<and_t<is_array<LHS>,is_array<RHS> >>
401  >
402  mdarray<mult_op<LHS,RHS>,map_type<LHS>,ipa_type<LHS>>
403  operator*(const LHS &a, const RHS &b)
404  {
405  typedef mult_op<LHS,RHS> operator_type;
406  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> result_type;
407 
408  return result_type(a.map(),operator_type(a,b));
409  }
410 
411  //-------------------------------------------------------------------------
431  template<
432  typename LHS,
433  typename T,
434  typename = enable_if<and_t<
435  is_array<LHS>,not_t<is_array<T>>
436  >>
437  >
438  mdarray<mult_op<LHS,scalar<T>>,map_type<LHS>,ipa_type<LHS>>
439  operator*(const LHS &a, const T &b)
440  {
441  typedef mult_op<LHS,scalar<T>> operator_type;
442  typedef mdarray<operator_type,map_type<LHS>,ipa_type<LHS>> result_type;
443 
444  return result_type(a.map(),operator_type(a,b));
445  }
446 
447  //-------------------------------------------------------------------------
467  template<
468  typename T,
469  typename RHS,
470  typename = enable_if<and_t<
471  not_t<is_array<T>>,is_array<RHS>
472  >>
473  >
474  mdarray<mult_op<scalar<T>,RHS>,map_type<RHS>,ipa_type<RHS>>
475  operator*(const T &a, const RHS &b)
476  {
477  typedef mult_op<scalar<T>,RHS> operator_type;
478  typedef mdarray<operator_type,map_type<RHS>,ipa_type<RHS>> result_type;
479 
480  return result_type(b.map(),operator_type(a,b));
481  }
482 
483 //end of namespace
484 }
485 }
container trait
Definition: container_trait.hpp:57
Definition: add_op.hpp:29
struct identifying a type as an array type
Definition: array_arithmetic.hpp:42
invoke< std::enable_if< C::value >> enable_if
shortcut for std::enable_if
Definition: sfinae_macros.hpp:108
scalar_iterator< ITERABLE > operator+(const scalar_iterator< ITERABLE > &a, ssize_t b)
add scalar to iterator
Definition: scalar_iterator.hpp:272
template for a multi-dimensional array class
Definition: mdarray.hpp:66
type erasure for POD data
Definition: value.hpp:46
addition expression template
Definition: add_op.hpp:46
scalar_iterator< ITERABLE > operator-(const scalar_iterator< ITERABLE > &a, ssize_t b)
subtract offset from iterator
Definition: scalar_iterator.hpp:312