libpnicore
array_view.hpp
1 //
2 // (c) Copyright 2011 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: May 14, 2012
22 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
23 //
24 
25 
26 #pragma once
27 
28 #include <memory>
29 #include <functional>
30 #include "index_map/index_maps.hpp"
31 #include "../utilities.hpp"
32 #include "array_selection.hpp"
33 #include "array_view_utils.hpp"
34 #include "../algorithms.hpp"
35 
36 namespace pni{
37 namespace core{
38 
46 
61  template<typename ATYPE>
63  class array_view
64  {
65  public:
66  //====================public types=================================
68  typedef ATYPE storage_type;
70  typedef typename ATYPE::value_type value_type;
74  typedef std::shared_ptr<array_type> shared_ptr;
76  typedef std::unique_ptr<array_type> unique_ptr;
84  typedef std::vector<size_t> index_type;
86  typedef typename ATYPE::inplace_arithmetic inplace_arithmetic;
89  //========================public members===========================
92  private:
94  std::reference_wrapper<ATYPE> _parray;
98  //view not the original array.
99  map_type _imap;
101  mutable index_type _index;
104 
107 
108  public:
109  //-----------------------------------------------------------------
118  array_view(storage_type &a,const array_selection &s):
119  _parray(std::ref(a)),
120  _selection(s),
121  _imap(map_utils<map_type>::create(_selection.shape<index_type>())),
122  _index(a.rank()),
123  _is_contiguous(pni::core::is_contiguous(a.map(),_selection)),
124  _start_offset(start_offset(a.map(),_selection))
125  { }
126 
127  //------------------------------------------------------------------
138  array_view(storage_type &a,array_selection &&s):
139  _parray(std::ref(a)),
140  _selection(std::move(s)),
141  _imap(map_utils<map_type>::create(_selection.shape<index_type>())),
142  _index(a.rank()),
143  _is_contiguous(pni::core::is_contiguous(a.map(),_selection)),
144  _start_offset(start_offset(a.map(),_selection))
145  {}
146 
147 
148  //-----------------------------------------------------------------
152  array_view(const array_type &c):
153  _parray(c._parray),
154  _selection(c._selection),
155  _imap(c._imap),
156  _index(c._index),
157  _is_contiguous(c._is_contiguous),
158  _start_offset(c._start_offset)
159  {}
160 
161  //-----------------------------------------------------------------
165  array_view(array_type &&c):
166  _parray(std::move(c._parray)),
167  _selection(std::move(c._selection)),
168  _imap(std::move(c._imap)),
169  _index(std::move(c._index)),
170  _is_contiguous(c._is_contiguous),
171  _start_offset(c._start_offset)
172  {}
173 
174  //-----------------------------------------------------------------
178  template<typename ETYPE>
179  array_type &operator=(const ETYPE &e)
180  {
181  if((void*)this == (void*)&e) return *this;
182 
183  //for(size_t i=0;i<size();++i) (*this)[i] = e[i];
184  std::copy(e.begin(),e.end(),this->begin());
185 
186  return *this;
187  }
188 
189 
190  //-----------------------------------------------------------------
194  array_type &operator=(array_type &&a)
195  {
196  if(this == &a) return *this;
197 
198  _parray = std::move(a._parray);
199  _selection = std::move(a._selection);
200  _imap = std::move(a._imap);
201  _index = std::move(a._index);
202  _is_contiguous = a._is_contiguous;
203  _start_offset = a._start_offset;
204 
205  return *this;
206  }
207 
208  //==================public member functions========================
221  template<
222  typename CTYPE,
223  typename = typename enable_element_cont<CTYPE>::type
224  >
225  value_type &operator()(const CTYPE &index)
226  {
227  typedef typename ATYPE::map_type omap_type;
228  auto &ref = _parray.get();
229 
230  if(_is_contiguous)
231  return ref[_start_offset + _imap.offset(index)];
232  else
233  {
234  auto map = const_cast<omap_type&>(ref.map());
235  size_t o = map.offset(_selection,index);
236  return ref[o];
237  }
238  }
239 
240  //-----------------------------------------------------------------
253  template<
254  typename CTYPE,
255  typename = typename enable_element_cont<CTYPE>::type
256  >
257  value_type operator()(const CTYPE &index) const
258  {
259  typedef typename ATYPE::map_type omap_type;
260  auto &ref = _parray.get();
261 
262  if(_is_contiguous)
263  return ref[_start_offset + _imap.offset(index)];
264  else
265  {
266  auto map = const_cast<omap_type&>(ref.map());
267  size_t o = map.offset(_selection,index);
268  return ref[o];
269  }
270  }
271 
272 
273  //-----------------------------------------------------------------
279 
286  template<typename ...ITypes>
292  value_type & operator()(ITypes ...indices)
293  {
294  typedef typename ATYPE::map_type omap_type;
295  auto &ref = _parray.get();
296 
297  if(_is_contiguous)
298  return ref[_start_offset +
299  _imap.offset(IDX_ARRAY(ITypes,indices))];
300  else
301  {
302  auto map = const_cast<omap_type&>(ref.map());
303  size_t o = map.offset(_selection,IDX_ARRAY(ITypes,indices));
304  return ref[o];
305  }
306 
307  }
308 
309  //-----------------------------------------------------------------
315 
322  template<typename ...ITypes>
329  value_type operator()(ITypes ...indices) const
330  {
331  typedef typename ATYPE::map_type omap_type;
332  auto &ref = _parray.get();
333 
334  if(_is_contiguous)
335  return ref[_start_offset +
336  _imap.offset(IDX_ARRAY(ITypes,indices))];
337  else
338  {
339  //have to do some more work here
340  auto map = const_cast<omap_type&>(ref.map());
341  return ref[map.offset(_selection,IDX_ARRAY(ITypes,indices))];
342  }
343  }
344 
345  //-----------------------------------------------------------------
355  template<typename CTYPE> CTYPE shape() const
356  {
357  return _selection.template shape<CTYPE>();
358  }
359 
360  //-----------------------------------------------------------------
371  value_type &operator[](size_t i)
372  {
373 #ifdef DEBUG
375 #endif
376  //compute the multidimensional index in the original array for
377  //the linear index i in the view
378  if(_is_contiguous) return _parray.get()[i+_start_offset];
379  else
380  {
381  auto index = _imap.template index<index_type>(i);
382  return (*this)(index);
383  }
384  }
385 
386  //-----------------------------------------------------------------
398 
399  value_type operator[](size_t i) const
400  {
401 #ifdef DEBUG
403 #endif
404  if(_is_contiguous) return _parray.get()[i+_start_offset];
405  else
406  {
407  //compute the multidimensional index in the original array for
408  //the linear index i in the view
409  auto index = _imap.template index<index_type>(i);
410  return (*this)(index);
411  }
412  }
413 
414  //-----------------------------------------------------------------
427  const value_type *data() const
428  {
429  if(_is_contiguous)
430  return &_parray.get()[_start_offset];
431  else
433  "Selection view is not contiguous!");
434  }
435 
436  //-----------------------------------------------------------------
449  value_type *data()
450  {
451  if(_is_contiguous)
452  return &_parray.get()[_start_offset];
453  else
455  "Selection view is not contiguous!");
456  }
457 
458  //-----------------------------------------------------------------
471  value_type &at(size_t i)
472  {
474  return (*this)[i];
475  }
476 
477  //-----------------------------------------------------------------
490  value_type at(size_t i) const
491  {
493  return (*this)[i];
494  }
495 
496  //-----------------------------------------------------------------
506  void insert(size_t i,const value_type &v) { at(i) = v; }
507 
508  //-----------------------------------------------------------------
512  value_type &front() { return at(0); }
513 
514  //-----------------------------------------------------------------
518  value_type front() const { return at(0); }
519 
520  //-----------------------------------------------------------------
524  value_type &back() { return at(size()-1); }
525 
526  //-----------------------------------------------------------------
530  value_type back() const { return at(size()-1); }
531 
532  //-----------------------------------------------------------------
539  size_t size() const
540  {
541  return _selection.size();
542  }
543 
544  //-----------------------------------------------------------------
552  size_t rank() const
553  {
554  return _selection.rank();
555  }
556 
557  //-----------------------------------------------------------------
564  iterator begin() { return iterator(this,0); }
565 
566  //-----------------------------------------------------------------
573  iterator end() { return iterator(this,this->size()); }
574 
575  //-----------------------------------------------------------------
584  const_iterator begin() const { return const_iterator(this,0); }
585 
586  //-----------------------------------------------------------------
596  const_iterator end() const { return const_iterator(this,size()); }
597 
598  //==========implementation of unary arithmetic operators===========
603 
612  array_type &operator+=(value_type s)
616  {
617  storage_type::inplace_arithmetic::add(*this,s);
618  return *this;
619  }
620 
621  //-----------------------------------------------------------------
625 
634  template<typename RTYPE>
640  array_type &operator+=(const RTYPE &v)
641  {
642  storage_type::inplace_arithmetic::add(*this,v);
643  return *this;
644  }
645 
646  //-----------------------------------------------------------------
650 
659  array_type &operator-=(value_type s)
663  {
664  storage_type::inplace_arithmetic::sub(*this,s);
665  return *this;
666  }
667 
668  //-----------------------------------------------------------------
672 
682  template<typename RTYPE>
688  array_type &operator-=(const RTYPE &v)
689  {
690  storage_type::inplace_arithmetic::sub(*this,v);
691  return *this;
692  }
693 
694  //-----------------------------------------------------------------
698 
707  array_type &operator*=(value_type s)
711  {
712  storage_type::inplace_arithmetic::mult(*this,s);
713  return *this;
714  }
715 
716  //-----------------------------------------------------------------
720 
729  template<typename RTYPE>
735  array_type &operator*=(const RTYPE &v)
736  {
737  storage_type::inplace_arithmetic::mult(*this,v);
738  return *this;
739  }
740 
741  //-----------------------------------------------------------------
745 
754  array_type &operator/=(value_type s)
758  {
759  storage_type::inplace_arithmetic::div(*this,s);
760  return *this;
761  }
762 
763  //-----------------------------------------------------------------
767 
776  template<typename RTYPE>
782  array_type &operator/=(const RTYPE &v)
783  {
784  storage_type::inplace_arithmetic::div(*this,v);
785  return *this;
786  }
787 
788  //-----------------------------------------------------------------
792  const map_type &map() const
793  {
794  return _imap;
795  }
796 
797  //-----------------------------------------------------------------
804  bool is_contiguous() const
805  {
806  return _is_contiguous;
807  }
808  };
809 
810  //------------------------------------------------------------------------
820  template<typename ATYPE>
822  {
824  }
825 
826  //------------------------------------------------------------------------
835  template<typename ATYPE>
837  {
839  static const bool is_random_access = true;
841  static const bool is_iterable = true;
843  static const bool is_contiguous = false;
845  static const bool is_multidim = true;
846  };
847 
848  //------------------------------------------------------------------------
861  template<typename ATYPE>
863  {
864  if(a.size()!=b.size())
866  "Array view sizes do not match!");
867 
868  return std::equal(a.begin(),a.end(),b.begin());
869  }
870 
871  //------------------------------------------------------------------------
884  template<typename ATYPE>
886  {
887  return !(a==b);
888  }
889 
890  //------------------------------------------------------------------------
902  template<typename ATYPE>
903  std::ostream &operator<<(std::ostream &stream,const array_view<ATYPE> &v)
904  {
905  for(auto x: v) stream<<x<<" ";
906 
907  return stream;
908  }
909 
910  //------------------------------------------------------------------------
922  template<typename ATYPE>
923  std::istream &operator>>(std::istream &stream,array_view<ATYPE> &v)
924  {
925  for(auto &x: v) stream>>x;
926 
927  return stream;
928  }
929 
930 //end of namespace
931 }
932 }
array_type & operator*=(value_type s)
unary multiplication of a scalar
Definition: array_view.hpp:710
bool check_index_in_dim(size_t index, size_t dimsize)
check index in dim
std::shared_ptr< array_type > shared_ptr
shared pointer type
Definition: array_view.hpp:74
array_view(array_type &&c)
move constructor
Definition: array_view.hpp:165
Size mismatch error.
Definition: exceptions.hpp:399
size_t size() const
get selection size
Definition: array_selection.hpp:290
ATYPE::inplace_arithmetic inplace_arithmetic
inplace arithetic type
Definition: array_view.hpp:86
value_type & front()
return reference to the first element
Definition: array_view.hpp:512
size_t size() const
get size
Definition: array_view.hpp:539
array_view(storage_type &a, array_selection &&s)
constructor
Definition: array_view.hpp:138
#define EXCEPTION_RECORD
macro creating an instance of ExceptionRecord
Definition: exceptions.hpp:48
value_type operator()(const CTYPE &index) const
access with container index
Definition: array_view.hpp:257
array_type & operator+=(value_type s)
unary addition of a scalar
Definition: array_view.hpp:615
Shape mismatch error.
Definition: exceptions.hpp:360
index_type _index
local index buffer for index calculations
Definition: array_view.hpp:101
STL namespace.
std::reference_wrapper< ATYPE > _parray
parent array from which to draw data
Definition: array_view.hpp:94
array_type & operator-=(const RTYPE &v)
unary subtraction of an array
Definition: array_view.hpp:688
bool operator==(const array_view< ATYPE > &a, const array_view< ATYPE > &b)
compare two array views
Definition: array_view.hpp:862
iterator type
Definition: container_iterator.hpp:59
value_type back() const
return value of last element
Definition: array_view.hpp:530
container_iterator< const array_type > const_iterator
const iterator type
Definition: array_view.hpp:80
array_view(const array_type &c)
copy constructor
Definition: array_view.hpp:152
size_t rank() const
get effective rank
Definition: array_selection.hpp:252
static const bool is_random_access
by default false
Definition: container_trait.hpp:60
array_type & operator=(const ETYPE &e)
copy assignment operator
Definition: array_view.hpp:179
std::unique_ptr< array_type > unique_ptr
unique pointer type
Definition: array_view.hpp:76
std::istream & operator>>(std::istream &stream, array_view< ATYPE > &v)
input operator for view
Definition: array_view.hpp:923
value_type operator[](size_t i) const
linearized access
Definition: array_view.hpp:399
static const type_id_t type_id
type id of the value_type
Definition: array_view.hpp:91
array_view(storage_type &a, const array_selection &s)
constructor
Definition: array_view.hpp:118
value_type at(size_t i) const
get value at index i
Definition: array_view.hpp:490
static const bool is_contiguous
by default false
Definition: container_trait.hpp:64
array_type & operator/=(const RTYPE &v)
unary division of an array
Definition: array_view.hpp:782
selection from a multidimensional array
Definition: array_selection.hpp:72
utility class for index maps
Definition: index_maps.hpp:100
bool is_contiguous() const
check if contiguous
Definition: array_view.hpp:804
container trait
Definition: container_trait.hpp:57
size_t start_offset(const MAPT &map, const array_selection &s)
compute first element offset
Definition: array_selection.hpp:535
value_type operator()(ITypes...indices) const
multidimensional access to data
Definition: array_view.hpp:329
Definition: add_op.hpp:29
array_type & operator-=(value_type s)
unary subtraction of a scalar
Definition: array_view.hpp:662
array_type & operator+=(const RTYPE &v)
unary addition of an array
Definition: array_view.hpp:640
type_id_t type_id(const array_view< ATYPE > &)
specialization for type_id
Definition: array_view.hpp:821
bool operator!=(const array_view< ATYPE > &a, const array_view< ATYPE > &b)
compare two array views
Definition: array_view.hpp:885
static const bool is_multidim
by default false
Definition: container_trait.hpp:66
static const bool is_iterable
by default false
Definition: container_trait.hpp:62
map from a type to type_id
Definition: type_id_map.hpp:55
container_iterator< array_type > iterator
iterator type
Definition: array_view.hpp:78
value_type * data()
get pointer to data
Definition: array_view.hpp:449
array_view< storage_type > array_type
type of the view
Definition: array_view.hpp:72
const value_type * data() const
get pointer to data
Definition: array_view.hpp:427
value_type & operator()(const CTYPE &index)
access with container index
Definition: array_view.hpp:225
std::vector< size_t > index_type
index type
Definition: array_view.hpp:84
map_type _imap
local index map - only used internally, this map describes the
Definition: array_view.hpp:99
size_t _start_offset
offset of the first element
Definition: array_view.hpp:106
value_type & operator[](size_t i)
linearzed access
Definition: array_view.hpp:371
iterator end()
iterator to last element
Definition: array_view.hpp:573
array_type & operator/=(value_type s)
unary division of a scalar
Definition: array_view.hpp:757
ATYPE storage_type
storage type
Definition: array_view.hpp:68
array_type & operator=(array_type &&a)
move assignment operator
Definition: array_view.hpp:194
bool _is_contiguous
check if selection is contiguous
Definition: array_view.hpp:103
value_type & operator()(ITypes...indices)
multidimensional access to data
Definition: array_view.hpp:292
void insert(size_t i, const value_type &v)
insert value at i
Definition: array_view.hpp:506
value_type & at(size_t i)
get value at index i
Definition: array_view.hpp:471
type_id_t
type codes for PNI data types
Definition: types/types.hpp:148
size_t rank() const
get rank of the view
Definition: array_view.hpp:552
value_type front() const
return value of first element
Definition: array_view.hpp:518
value_type & back()
return reference ot the last vlaue
Definition: array_view.hpp:524
array_selection _selection
selection object for index transformation
Definition: array_view.hpp:96
const_iterator begin() const
const iterator to first element
Definition: array_view.hpp:584
array_view< array_type > view_type
view type
Definition: array_view.hpp:82
index_map< index_type, typename ATYPE::map_type::implementation_type > map_type
map type
Definition: array_view.hpp:88
const_iterator end() const
const iterator to last element
Definition: array_view.hpp:596
ATYPE::value_type value_type
type of the data values
Definition: array_view.hpp:70
CTYPE shape() const
get shape of the view
Definition: array_view.hpp:355
const map_type & map() const
return reference to index map
Definition: array_view.hpp:792
size_t offset(const CTYPE &index) const
compute the offset
Definition: index_map.hpp:259
array_type & operator*=(const RTYPE &v)
unary multiplication of an array
Definition: array_view.hpp:735
iterator begin()
iterator to first element
Definition: array_view.hpp:564
provides a view on a part of an array
Definition: add_op.hpp:32