ATLAS Offline Software
Array.icc
Go to the documentation of this file.
1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
2 
3 /*
4  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 /**
8  * @file Array.icc
9  * @author scott snyder <snyder@bnl.gov>
10  * @date June, 2004
11  * @brief Simple multidimensional arrays (inline and template implementations).
12  */
13 
14 
15 #include "CxxUtils/unused.h"
16 #include <ostream>
17 #include <cassert>
18 
19 
20 // cppcheck doesn't properly handle recursive templates like this.
21 #ifndef __CPPCHECK__
22 namespace CxxUtils {
23 
24 
25 /**
26  * @brief Construct an @c Array<N>::const_iterator.
27  * @param rep @c Arrayrep from which to initialize the iterator.
28  * @param offs Offset of the first element referenced by the iterator
29  * within @a rep.
30  * @return The new iterator.
31  */
32 template <unsigned int N>
33 inline
34 typename ArrayIteratorChooser<N>::const_iterator
35 ArrayIteratorChooser<N>::make_iterator (const Arrayrep* rep,
36  unsigned int offs)
37 {
38  return const_iterator (rep, offs);
39 }
40 
41 
42 /**
43  * @brief Construct an @c Array<1>::const_iterator.
44  * @param rep @c Arrayrep from which to initialize the iterator.
45  * @param offs Offset of the first element referenced by the iterator
46  * within @a rep.
47  * @return The new iterator.
48  */
49 inline
50 ArrayIteratorChooser<1>::const_iterator
51 ArrayIteratorChooser<1>::make_iterator (const Arrayrep* rep,
52  unsigned int offs)
53 {
54  return rep ? &rep->m_data[offs] : 0;
55 }
56 
57 
58 //**********************************************************************
59 
60 
61 /**
62  * @brief Default constructor.
63  *
64  * This produces an invalid @c Array that is not associated with
65  * an @c Arrayrep. @c valid() will return @c false for such an array.
66  * The only other thing that it is legal to do with an invalid array
67  * is to assign to it (which may make it valid).
68  */
69 template <unsigned int N>
70 Array<N>::Array ()
71  : m_rep (0),
72  m_offs (0)
73 {
74 }
75 
76 
77 /**
78  * @brief Constructor.
79  * @param rep @c Arrayrep from which to initialize the array.
80  *
81  * Initialize an array from an @c Arrayrep. The new array will
82  * represent the entire @c Arrayrep. The dimension @c N must
83  * match the length of the @c Arrayrep's shape.
84  */
85 template <unsigned int N>
86 Array<N>::Array (const Arrayrep& rep)
87  : m_rep (&rep),
88  m_offs (0)
89 {
90  assert (m_rep->m_shape.size() == N);
91  assert (m_rep->m_sizes.size() == m_rep->m_shape.size());
92 }
93 
94 
95 /**
96  * @brief Test for validity.
97  * @return True if the @c Array is associated with an @c Arrayrep,
98  * false if not.
99  */
100 template <unsigned int N>
101 bool Array<N>::valid() const
102 {
103  return m_rep != 0;
104 }
105 
106 
107 /**
108  * @brief Return the array shape.
109  * @return The array shape.
110  *
111  * The array shape is vector with one element for each array dimension,
112  * giving the size of the array along that dimension.
113  */
114 template <unsigned int N>
115 std::vector<unsigned int> Array<N>::shape() const
116 {
117  return std::vector<unsigned int>
118  (m_rep->m_shape.begin() + m_rep->m_shape.size() - N,
119  m_rep->m_shape.end());
120 }
121 
122 
123 /**
124  * @brief Return the size of the array along one dimension.
125  * @param dim The dimension of the size to retrieve.
126  * Must be less than the number of dimensions.
127  *
128  * As a special case, the size of an invalid array will always be 0.
129  * @return The array size along dimension @dim.
130  */
131 template <unsigned int N>
132 unsigned int Array<N>::size (unsigned int dim /*=0*/) const
133 {
134  assert (dim < N);
135  if (!m_rep) return 0;
136  return m_rep->m_shape[m_rep->m_shape.size() - N + dim];
137 }
138 
139 
140 /**
141  * @brief Array indexing.
142  * @param i The desired index. Must be less than the array size
143  * along this dimension.
144  * @return The @a i'th @c N-1 dimensional subarray in the array.
145  *
146  * Note that this operation is not available if @c N is 0.
147  */
148 template <unsigned int N>
149 inline
150 Array<N-1> Array<N>::operator[] (unsigned int i) const
151 {
152  assert (i < m_rep->m_shape[m_rep->m_shape.size() - N]);
153  return Array<N-1> (*m_rep, m_offs + i * m_rep->m_sizes[N-1]);
154 }
155 
156 
157 /**
158  * @brief Return a direct pointer to array elements.
159  * @return A pointer to the first array elements.
160  *
161  * Subsequent elements follow in standard C indexing order.
162  */
163 template <unsigned int N>
164 inline
165 const Arrayelt* Array<N>::ptr () const
166 {
167  return &m_rep->m_data[m_offs];
168 }
169 
170 
171 /**
172  * @brief Return an iterator pointing at the beginning of the container.
173  * @return An iterator pointing at the beginning of the container.
174  */
175 template <unsigned int N>
176 inline
177 typename Array<N>::const_iterator Array<N>::begin () const
178 {
179  return ArrayIteratorChooser<N>::make_iterator (m_rep, m_offs);
180 }
181 
182 
183 /**
184  * @brief Return an iterator pointing past the end of the container.
185  * @return An iterator pointing past the end of the container.
186  */
187 template <unsigned int N>
188 inline
189 typename Array<N>::const_iterator Array<N>::end () const
190 {
191  unsigned int offs = m_rep ? m_offs + size() * m_rep->m_sizes[N-1] : 0;
192  return ArrayIteratorChooser<N>::make_iterator (m_rep, offs);
193 }
194 
195 
196 /**
197  * @brief Creates a text representation of the array content.
198  * @param std::ostream where the text should be written
199  *
200  * Writes the content of the array to a ostream. The sub-arrays are
201  * enclosed by square brackets and separated by commas.
202  */
203 template <unsigned int N>
204 inline
205 void Array<N>::write_array (std::ostream& stream) const
206 {
207  if (!m_rep) {
208  stream << "\"\"";
209  }
210  else {
211  m_rep->write_array (stream);
212  }
213 }
214 
215 
216 /**
217  * @brief Private constructor for array indexing.
218  * @param rep @c Arrayrep from which to initialize the array.
219  * @param offs Offset of the first element of the new array
220  * within @a rep.
221  *
222  * This is a private constructor used to make the @c Array
223  * instances returned from an indexing operation.
224  */
225 template <unsigned int N>
226 inline
227 Array<N>::Array (const Arrayrep& rep, unsigned int offs)
228  : m_rep (&rep),
229  m_offs (offs)
230 {
231 }
232 
233 
234 /**
235  * @brief Default constructor.
236  *
237  * This produces an invalid @c Array that is not associated with
238  * an @c Arrayrep. @c valid() will return @c false for such an array.
239  * The only other thing that it is legal to do with an invalid array
240  * is to assign to it (which may make it valid).
241  */
242 inline
243 Array<0>::Array ()
244  : m_elt (0)
245 {
246 }
247 
248 
249 /**
250  * @brief Constructor.
251  * @param rep @c Arrayrep from which to initialize the array.
252  *
253  * Initialize an array from an @c Arrayrep. The new array will
254  * represent the entire @c Arrayrep. The dimension @c N must
255  * match the length of the @c Arrayrep's shape.
256  */
257 inline
258 Array<0>::Array (const Arrayrep& rep)
259  : m_elt (&rep.m_data[0])
260 {
261  assert (rep.m_shape.size() == 0);
262  assert (rep.m_sizes.size() == rep.m_shape.size());
263 }
264 
265 
266 /**
267  * @brief Test for validity.
268  * @return True if the @c Array is associated with an @c Arrayrep,
269  * false if not.
270  */
271 inline
272 bool Array<0>::valid() const
273 {
274  return m_elt != 0;
275 }
276 
277 
278 /**
279  * @brief Return the array shape.
280  * @return The array shape.
281  *
282  * The array shape is vector with one element for each array dimension,
283  * giving the size of the array along that dimension.
284  * For @c Array<0>, this will always be an empty array.
285  */
286 inline
287 std::vector<unsigned int> Array<0>::shape() const
288 {
289  return std::vector<unsigned int> ();
290 }
291 
292 
293 /**
294  * @brief Return the size of the array along one dimension.
295  * @param dim The dimension of the size to retrieve.
296  * Must be less than the number of dimensions.
297  * @return The array size along dimension @dim.
298  *
299  * For @c Array<0>, @a dim must be 0, and the function
300  * will always return 1.
301  */
302 inline
303 unsigned int Array<0>::size ([[maybe_unused]] unsigned int dim /*=0*/) const
304 {
305  assert (dim == 0);
306  return 1;
307 }
308 
309 
310 /**
311  * @brief Convert to a number.
312  * @return The @c Array<0> contents as a number.
313  */
314 inline
315 Array<0>::operator Arrayelt() const
316 {
317  return *m_elt;
318 }
319 
320 
321 /**
322  * @brief Convert to an integer.
323  * @return The @c Array<0> contents as an integer.
324  */
325 inline
326 int Array<0>::asint() const
327 {
328  return static_cast<int> (*m_elt);
329 }
330 
331 
332 /**
333  * @brief Creates a text representation of the array content.
334  * @param std::ostream where the text should be written
335  *
336  * Writes the content of the array to a ostream. The sub-arrays are
337  * enclosed by square brackets and separated by commas.
338  */
339 inline
340 void Array<0>::write_array (std::ostream& stream) const
341 {
342  stream << *m_elt;
343 }
344 
345 
346 /**
347  * @brief Private constructor for array indexing.
348  * @param rep @c Arrayrep from which to initialize the array.
349  * @param offs Offset of the first element of the new array
350  * within @a rep.
351  *
352  * This is a private constructor used to make the @c Array
353  * instances returned from an indexing operation.
354  */
355 inline
356 Array<0>::Array (const Arrayrep& rep, unsigned int offs)
357  : m_elt (&rep.m_data[offs])
358 {
359 }
360 
361 
362 template <unsigned int N>
363 std::ostream& operator<< (std::ostream& s, const Array<N>& a)
364 {
365  a.write_array (s);
366  return s;
367 }
368 
369 
370 //**********************************************************************
371 
372 
373 /**
374  * @brief Proxy constructor.
375  * @param i The iterator that is being dereferenced.
376  */
377 template <unsigned int N>
378 ArrayIterator<N>::pointer::pointer (const ArrayIterator& i)
379  : m_a (*i)
380 {
381 }
382 
383 
384 /**
385  * @brief Dereference the proxy.
386  * @return A copy of the @c Array proxy.
387  */
388 template <unsigned int N>
389 typename ArrayIterator<N>::value_type
390 ArrayIterator<N>::pointer::operator* () const
391 {
392  return m_a;
393 }
394 
395 
396 /**
397  * @brief Dereference the proxy.
398  * @return A pointer to the @c Array proxy.
399  * This proxy is only until the @c pointer instance
400  * is destroyed.
401  */
402 template <unsigned int N>
403 const typename ArrayIterator<N>::value_type*
404 ArrayIterator<N>::pointer::operator-> () const
405 {
406  return &m_a;
407 }
408 
409 
410 /**
411  * @brief Default constructor.
412  * Makes an invalid iterator.
413  */
414 template <unsigned int N>
415 ArrayIterator<N>::ArrayIterator ()
416  : m_rep (0),
417  m_offs (0)
418 {
419 }
420 
421 
422 /**
423  * @brief Constructor from @c Arrayrep and offset.
424  * @param rep The underlying array representation.
425  * @param offs The offset in the representation of the
426  * first element referenced by this iterator.
427  */
428 template <unsigned int N>
429 ArrayIterator<N>::ArrayIterator (const Arrayrep* rep, unsigned int offs)
430  : m_rep (rep),
431  m_offs (offs)
432 {
433 }
434 
435 
436 /**
437  * @brief Equality comparison.
438  * @param other The other object with which to compare.
439  * @return True if the iterators are equal.
440  */
441 template <unsigned int N>
442 bool ArrayIterator<N>::operator== (const ArrayIterator<N>& other) const
443 {
444  return m_rep == other.m_rep && m_offs == other.m_offs;
445 }
446 
447 
448 /**
449  * @brief Inequality comparison.
450  * @param other The other object with which to compare.
451  * @return True if the iterators are not equal.
452  */
453 template <unsigned int N>
454 bool ArrayIterator<N>::operator!= (const ArrayIterator<N>& other) const
455 {
456  return !(*this == other);
457 }
458 
459 
460 /**
461  * @brief Less-than comparison.
462  * @param other The other object with which to compare.
463  * @return True if this iterator is less than @a other.
464  * This will always return false for iterators
465  * over different arrays.
466  */
467 template <unsigned int N>
468 bool ArrayIterator<N>::operator< (const ArrayIterator<N>& other) const
469 {
470  return m_rep == other.m_rep && m_offs < other.m_offs;
471 }
472 
473 
474 /**
475  * @brief Greater-than comparison.
476  * @param other The other object with which to compare.
477  * @return True if this iterator is greater than @a other.
478  * This will always return false for iterators
479  * over different arrays.
480  */
481 template <unsigned int N>
482 bool ArrayIterator<N>::operator> (const ArrayIterator<N>& other) const
483 {
484  return other < *this;
485 }
486 
487 
488 /**
489  * @brief Less-than-or-equal comparison.
490  * @param other The other object with which to compare.
491  * @return True if this iterator is less than or equal to @a other.
492  * This will always return false for iterators
493  * over different arrays.
494  */
495 template <unsigned int N>
496 bool ArrayIterator<N>::operator<= (const ArrayIterator<N>& other) const
497 {
498  return m_rep == other.m_rep && m_offs <= other.m_offs;
499 }
500 
501 
502 /**
503  * @brief Greater-than-or-equal comparison.
504  * @param other The other object with which to compare.
505  * @return True if this iterator is less than or equal to @a other.
506  * This will always return false for iterators
507  * over different arrays.
508  */
509 template <unsigned int N>
510 bool ArrayIterator<N>::operator>= (const ArrayIterator<N>& other) const
511 {
512  return other <= *this;
513 }
514 
515 
516 /**
517  * @brief Dereference the iterator.
518  * @return The value that the iterator points to.
519  * Note that this method returns a @c value_type, not
520  * a @c reference. (Thus, this class does not quite
521  * conform to the iterator requirements.)
522  */
523 template <unsigned int N>
524 typename ArrayIterator<N>::value_type ArrayIterator<N>::operator* () const
525 {
526  assert (m_offs < m_rep->m_data.size());
527  return Array<N-1> (*m_rep, m_offs);
528 }
529 
530 
531 /**
532  * @brief Dereference the iterator.
533  * @return A proxy for the iterator element.
534  *
535  * This method will return a proxy for the array, which you
536  * can then dereference. Note that if you get a C++ pointer
537  * from this, then it will be valid only until the proxy
538  * object gets destroyed.
539  */
540 template <unsigned int N>
541 typename ArrayIterator<N>::pointer ArrayIterator<N>::operator-> () const
542 {
543  return pointer (*this);
544 }
545 
546 
547 /**
548  * @brief Advance the iterator.
549  * @returns This iterator.
550  */
551 template <unsigned int N>
552 ArrayIterator<N>& ArrayIterator<N>::operator++ ()
553 {
554  m_offs += m_rep->m_sizes[N-1];
555  return *this;
556 }
557 
558 
559 /**
560  * @brief Advance the iterator.
561  * @returns The iterator before being advanced.
562  */
563 template <unsigned int N>
564 ArrayIterator<N> ArrayIterator<N>::operator++ (int)
565 {
566  ArrayIterator tmp (*this);
567  m_offs += m_rep->m_sizes[N-1];
568  return tmp;
569 }
570 
571 
572 /**
573  * @brief Back up the iterator.
574  * @returns This iterator.
575  */
576 template <unsigned int N>
577 ArrayIterator<N>& ArrayIterator<N>::operator-- ()
578 {
579  m_offs -= m_rep->m_sizes[N-1];
580  return *this;
581 }
582 
583 
584 /**
585  * @brief Back up the iterator.
586  * @returns The iterator before being backed up.
587  */
588 template <unsigned int N>
589 ArrayIterator<N> ArrayIterator<N>::operator-- (int)
590 {
591  ArrayIterator tmp (*this);
592  m_offs -= m_rep->m_sizes[N-1];
593  return tmp;
594 }
595 
596 
597 /**
598  * @brief Array indexing relative to the iterator.
599  * @param n The array index.
600  * @return The array item at an offset of @a n from the
601  * current iterator position.
602  * Note that this method returns a @c value_type, not
603  * a @c reference. (Thus, this class does not quite
604  * conform to the iterator requirements.)
605  */
606 template <unsigned int N>
607 typename ArrayIterator<N>::value_type
608 ArrayIterator<N>::operator[] (difference_type n) const
609 {
610  unsigned int offs = m_offs + n * m_rep->m_sizes[N-1];
611  assert (offs < m_rep->m_data.size());
612  return Array<N-1> (*m_rep, offs);
613 }
614 
615 
616 /**
617  * @brief Advance the iterator.
618  * @param n Number of steps by which to advance the iterator.
619  * @return This iterator.
620  */
621 template <unsigned int N>
622 ArrayIterator<N>& ArrayIterator<N>::operator+= (difference_type n)
623 {
624  m_offs += n * m_rep->m_sizes[N-1];
625  return *this;
626 }
627 
628 
629 /**
630  * @brief Return a new iterator pointing @a n steps ahead.
631  * @param n Number of steps by which to advance.
632  * @return The new iterator.
633  */
634 template <unsigned int N>
635 ArrayIterator<N> ArrayIterator<N>::operator+ (difference_type n) const
636 {
637  return ArrayIterator (m_rep, m_offs + n * m_rep->m_sizes[N-1]);
638 }
639 
640 
641 /**
642  * @brief Back up the iterator.
643  * @param n Number of steps by which to advance the iterator.
644  * @return This iterator.
645  */
646 template <unsigned int N>
647 ArrayIterator<N>& ArrayIterator<N>::operator-= (difference_type n)
648 {
649  m_offs -= n * m_rep->m_sizes[N-1];
650  return *this;
651 }
652 
653 
654 /**
655  * @brief Return a new iterator pointing @a n steps behind.
656  * @param n Number of steps by which to back up.
657  * @return The new iterator.
658  */
659 template <unsigned int N>
660 ArrayIterator<N> ArrayIterator<N>::operator- (difference_type n) const
661 {
662  return ArrayIterator (m_rep, m_offs - n * m_rep->m_sizes[N-1]);
663 }
664 
665 
666 /**
667  * @brief Return the difference between two iterators.
668  * @param other The other iterator for the comparison.
669  * @return The number of elements difference between
670  * this iterator and @a other.
671  * Undefined if the two iterators do not point
672  * into the same array.
673  */
674 template <unsigned int N>
675 typename ArrayIterator<N>::difference_type
676 ArrayIterator<N>::operator- (const ArrayIterator& other) const
677 {
678  return (m_offs - other.m_offs) / m_rep->m_sizes[N-1];
679 }
680 
681 
682 //**********************************************************************
683 
684 
685 /**
686  * @brief Constructor.
687  * @param rep @c Arrayrep from which to initialize the array.
688  *
689  * Initialize an array from an @c Arrayrep. The new array will
690  * represent the entire @c Arrayrep. The dimension @c N must
691  * match the length of the @c Arrayrep's shape.
692  */
693 template <unsigned int N>
694 inline
695 WritableArray<N>::WritableArray (Arrayrep& rep)
696  : Array<N> (rep),
697  m_rep_nc (&rep)
698 {
699 }
700 
701 
702 /**
703  * @brief Array indexing.
704  * @param i The desired index. Must be less than the array size
705  * along this dimension.
706  * @return The @a i'th @c N-1 dimensional subarray in the array.
707  *
708  * Note that this operation is not available if @c N is 0.
709  */
710 template <unsigned int N>
711 inline
712 WritableArray<N-1> WritableArray<N>::operator[] (unsigned int i)
713 {
714  assert (i < this->m_rep_nc->m_shape[this->m_rep_nc->m_shape.size() - N]);
715  return WritableArray<N-1> (*this->m_rep_nc,
716  this->m_offs + i * this->m_rep_nc->m_sizes[N-1]);
717 }
718 
719 
720 /**
721  * @brief Array indexing.
722  * @param i The desired index. Must be less than the array size
723  * along this dimension.
724  * @return The @a i'th @c N-1 dimensional subarray in the array.
725  *
726  * Note that this operation is not available if @c N is 0.
727  */
728 template <unsigned int N>
729 inline
730 Array<N-1> WritableArray<N>::operator[] (unsigned int i) const
731 {
732  assert (i < this->m_rep_nc->m_shape[this->m_rep_nc->m_shape.size() - N]);
733  return Array<N-1> (*this->m_rep_nc,
734  this->m_offs + i * this->m_rep_nc->m_sizes[N-1]);
735 }
736 
737 
738 /**
739  * @brief Return a direct pointer to array elements.
740  * @return A pointer to the first array elements.
741  *
742  * Subsequent elements follow in standard C indexing order.
743  */
744 template <unsigned int N>
745 inline
746 Arrayelt* WritableArray<N>::ptr ()
747 {
748  return &this->m_rep_nc->m_data[this->m_offs];
749 }
750 
751 
752 /**
753  * @brief Private constructor for array indexing.
754  * @param rep @c Arrayrep from which to initialize the array.
755  * @param offs Offset of the first element of the new array
756  * within @a rep.
757  *
758  * This is a private constructor used to make the @c Array
759  * instances returned from an indexing operation.
760  */
761 template <unsigned int N>
762 inline
763 WritableArray<N>::WritableArray (Arrayrep& rep, unsigned int offs)
764  : Array<N> (rep, offs),
765  m_rep_nc (&rep)
766 {
767 }
768 
769 
770 /**
771  * @brief Constructor.
772  * @param rep @c Arrayrep from which to initialize the array.
773  *
774  * Initialize an array from an @c Arrayrep. The new array will
775  * represent the entire @c Arrayrep. The dimension @c N must
776  * match the length of the @c Arrayrep's shape.
777  */
778 inline
779 WritableArray<0>::WritableArray (Arrayrep& rep)
780  : Array<0> (rep),
781  m_elt_nc (&rep.m_data[0])
782 {
783 }
784 
785 
786 /**
787  * @brief Assignment.
788  * @param elt The RHS of the assignment.
789  * @return This object.
790  *
791  * Assign into the array.
792  */
793 inline
794 WritableArray<0>& WritableArray<0>::operator= (Arrayelt elt)
795 {
796  *m_elt_nc = elt;
797  return *this;
798 }
799 
800 
801 /**
802  * @brief Private constructor for array indexing.
803  * @param rep @c Arrayrep from which to initialize the array.
804  * @param offs Offset of the first element of the new array
805  * within @a rep.
806  *
807  * This is a private constructor used to make the @c Array
808  * instances returned from an indexing operation.
809  */
810 inline
811 WritableArray<0>::WritableArray (Arrayrep& rep, unsigned int offs)
812  : Array<0> (rep, offs),
813  m_elt_nc (&rep.m_data[offs])
814 {
815 }
816 
817 
818 //**********************************************************************
819 
820 
821 /**
822  * @brief Constructor.
823  * @param shape The shape of the array, as a C array.
824  * Should be @c N elements long. \
825  *
826  * The shape is the size of the array along each dimension.
827  */
828 template <unsigned int N>
829 WritableArrayData<N>::WritableArrayData(const unsigned int shape[])
830  : Arrayrep (shape, N),
831  WritableArray<N> (*static_cast<Arrayrep*>(this))
832 {
833 }
834 
835 
836 /**
837  * @brief Constructor.
838  * @param shape The shape of the array, as a std::vector.
839  * Should be @c N elements long.
840  *
841  * The shape is the size of the array along each dimension.
842  */
843 template <unsigned int N>
844 WritableArrayData<N>::WritableArrayData(const std::vector<unsigned int>& shape)
845  : Arrayrep (shape),
846  WritableArray<N> (*static_cast<Arrayrep*>(this))
847 {
848  assert (shape.size() == N);
849 }
850 
851 
852 /**
853  * @brief Helper to convert from an @x Arrayrep to a scalar type.
854  * @param rep Representation object to convert.
855  * @param x[out] Result of the conversion.
856  */
857 template <class T>
858  ATH_REQUIRES(std::assignable_from<T&, float>)
859 void fromArrayrep (const CaloRec::Arrayrep& rep, T& x)
860 {
861  x = rep.m_data[0];
862 }
863 
864 
865 /**
866  * @brief Helper to convert from an @x Arrayrep to an @c Array.
867  * @param rep Representation object to convert.
868  * @param x[out] Result of the conversion.
869  */
870 template <unsigned int N>
871 void fromArrayrep (const CaloRec::Arrayrep& rep, CxxUtils::Array<N>& x)
872 {
873  x = CxxUtils::Array<N> (rep);
874 }
875 
876 
877 } // namespace CxxUtils
878 #endif // not __CPPCHECK__