array_dec.h 18.7 KB
Newer Older
1
2
3
4
5
/*! \file array_dec.h
 * \brief array class declarations (prototypes)
 * 
 * ----------------------------------------------------------------------------
 * 
6
 * $Id: array_dec.h,v 1.8 2002-12-16 21:03:25 uid1201 Exp $
7
 * \author Thomas Forbriger
8
 * \since 08/12/2002
9
10
 * 
 * array class declarations (prototypes)
11
12
13
 *
 * \note
 * This should never be included directly. Use array.h or binarray.h instead.
14
15
16
17
 * 
 * Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt) 
 * 
 * REVISIONS and CHANGES 
18
 *  - 08/12/2002   V1.0   copied from libcontxx
19
20
21
22
 *  - 16/12/2002   V1.1   (thof)
 *                        - introduced new concept of const-correctness;
 *                          this should work for passing arrays as intrinsic
 *                          references for const element type
23
24
25
26
27
 * 
 * ============================================================================
 */

// include guard
28
#ifndef AFF_ARRAY_DEC_H_VERSION
29

30
#define AFF_ARRAY_DEC_H_VERSION \
31
  "AFF_ARRAY_DEC_H   V1.1"
32
#define AFF_ARRAY_DEC_H_CVSID \
33
  "$Id: array_dec.h,v 1.8 2002-12-16 21:03:25 uid1201 Exp $"
34

thomas.forbriger's avatar
thomas.forbriger committed
35
36
37
#include <aff/lib/sharedheap.h>
#include <aff/lib/strided.h>
// #include <aff/lib/range.h>
38

39
namespace aff {
40

41
#ifdef AFF_PREBUILT
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
namespace prebuilt {
#endif

  /*! \brief Full multi-dimensional array functionality.
   *
   * The array class highly depends on base classes from which inherts most of
   * its functionality. 
   * The user may select from several provided array designs through template
   * parameters:
   * \param T element type of array (passed to Subscriptor base class)
   * \param N dimensionality of array (passed to Subscriptor base class)
   * \param Representation Representation (engine for memory access) base
   *        class type (passed to Subscriptor base class)
   * \param Subscriptor Subscriptor base class type
   *
   * \sa \ref page_shapes_and_subscriptors
   * \sa \ref page_representation
   * \sa \ref sec_main_modules
   * \sa tests/arraytest.cc
61
   *
thomas.forbriger's avatar
thomas.forbriger committed
62
63
64
65
66
67
68
69
   * \note
   * We may just use the default copy constructor and default copy operator.
   *
   * If you want to create an array for externally managed memory (e.g. arrays
   * taken from Fortran code): First create a SharedHeap representation for the
   * given memory pointer and size. Second create a shape, defining the memory
   * layout and then create the array object from these both.
   *
70
71
72
73
74
75
76
77
   * \todo
   * documentation of class Array must be reworked
   *
   * \todo
   * class Array must be reworked itself entirely
   *
   * \todo 
   * Explain the new concept of multidimensional array indexing
thomas.forbriger's avatar
thomas.forbriger committed
78
79
80
81
82
   *
   * \sa aff::Strided
   * \sa aff::SharedHeap<T>
   * \sa aff::Array<T>::copyin()
   * \sa aff::Array<T>::copyout()
83
   */
thomas.forbriger's avatar
thomas.forbriger committed
84
  template<class T>
85
    class Array:
86
      public Array<const T>
87
    {
thomas.forbriger's avatar
thomas.forbriger committed
88
      public:
thomas.forbriger's avatar
thomas.forbriger committed
89
90
91
92
93
94
95
96
97
98
        /*! \name Various types
         *
         * In particular due to our concept of const-correctness we need
         * several typedefs to declare types derived from the element type of
         * the array.
         *
         * \sa \ref sec_main_constness
         * \sa aff::util::Qualified<T>
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
99
100
        //! Type of this array
        typedef Array<T> Tcontainer;
101
102
        //! base is container of const (see specialization below)
        typedef Array<const T> Tbase;
thomas.forbriger's avatar
thomas.forbriger committed
103
        //! Type of the array of const values
104
        typedef Tbase Tcontainer_of_const;
thomas.forbriger's avatar
thomas.forbriger committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
        /*! \brief short for Tcontainer_of_const
         *
         * We generally distinguish between constness of the array and
         * constness of the contained data (see \ref sec_main_constness).
         * There will be situations, when you want to promise that a function
         * will not change the contents of an array. In this case you may use
         * a declaration (prototype) like
         * \code
         *   typedef aff::Array<int> Tmyarray;
         *   void myfunction(const Tmyarray::Tcoc& array);
         * \endcode
         * and you may use this function like
         * \code
         *   Tmyarray A(6,7);
         *   A=4;
         *   myfunction(A);
         * \endcode
         */
123
124
125
126
127
128
129
130
131
132
133
        typedef Tbase Tcoc;
        //! Type of representation
        typedef Tbase::Trepresentation Trepresentation;
        //! Type of subscriptor
        typedef Tbase::Tshape Tshape;
        //! Element type
        typedef T Tvalue;
        //! Type of pointer to element
        typedef T* Tpointer;
        //! Type of reference to element
        typedef T& Treference;
thomas.forbriger's avatar
thomas.forbriger committed
134
        //@}
thomas.forbriger's avatar
thomas.forbriger committed
135

thomas.forbriger's avatar
thomas.forbriger committed
136
137
138
139
140
141
142
143
144
145
146
147
148
        /*-----------------------------------------------------------------*/
        
        /*! \name Constructors
         *
         * \note
         * We use the default copy constructor, which automatically invokes
         * the copy constructors of the base classes aff::Strided and
         * aff::SharedHeap<T>. This essentially is a shallow copy of the
         * array, i.e. the copy will reference to the same elements in memory.
         * See aff::Array<T>::copyin() and aff::Array<T>::copyout() for deep
         * copy operations.
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
149
        //! construct from nothing (empty)
150
        Array(): Tbase() { }
thomas.forbriger's avatar
thomas.forbriger committed
151
152
        //! construct from shape and representation
        Array(const Tshape& shape, 
153
154
              const Trepresentation& representation):
          Tbase(shape, representation) { }
thomas.forbriger's avatar
thomas.forbriger committed
155
        //! construct from shape (defines size and layout)
156
157
        explicit Array(const Tshape& shape):
          Tbase(shape) { }
thomas.forbriger's avatar
thomas.forbriger committed
158
        //! construct from index range limit
159
160
        explicit Array(const Tsize& s0):
          Tbase(s0) { }
thomas.forbriger's avatar
thomas.forbriger committed
161
        //! construct from index range limits
162
163
        Array(const Tsize& s0, const Tsize& s1):
          Tbase(s0, s1) { }
thomas.forbriger's avatar
thomas.forbriger committed
164
        //! construct from index range limits
165
166
        Array(const Tsize& s0, const Tsize& s1, const Tsize& s2):
          Tbase(s0, s1, s2) { }
thomas.forbriger's avatar
thomas.forbriger committed
167
168
        //! construct from index range limits
        Array(const Tsize& s0, const Tsize& s1, 
169
170
              const Tsize& s2, const Tsize& s3):
          Tbase(s0, s1, s2, s3) { }
thomas.forbriger's avatar
thomas.forbriger committed
171
172
173
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
174
      
175
176
177
178
        /*! \name Data modification functions
         *
         * These functions are declared protected in the base class. Make them
         * visible here.
thomas.forbriger's avatar
thomas.forbriger committed
179
180
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
181
        //! full dimensionality access
182
        T& operator()(const TIndexVec& index) 
183
        { return(this->Tbase::operator()(index)); }
thomas.forbriger's avatar
thomas.forbriger committed
184
        //! access from 1 index value
185
        T& operator()(const Tsubscript& i0) 
186
        { return(this->Tbase::operator()(i0)); }
thomas.forbriger's avatar
thomas.forbriger committed
187
        //! access from 2 index values
188
189
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1) 
190
        { return(this->Tbase::operator()(i0, i1)); }
thomas.forbriger's avatar
thomas.forbriger committed
191
        //! access from 3 index values
192
193
194
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1,
                      const Tsubscript& i2) 
195
        { return(this->Tbase::operator()(i0, i1, i2)); }
thomas.forbriger's avatar
thomas.forbriger committed
196
        //! access from 4 index values
197
198
199
200
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1,
                      const Tsubscript& i2,
                      const Tsubscript& i3) 
201
202
203
204
205
206
207
208
209
210
211
        { return(this->Tbase::operator()(i0, i1, i2, i3)); }
          
        //! set whole array to value
        Array& operator=(const T& value)
        { return(this->Tbase::operator=(value)); }

        //! copy in from other array
        template<class TT>
          Array& copyin(const Array<TT>& a)
          { return(this->Tbase::copyin(a)); }
        //@}
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
      
        /*! \name Data access operators
         *
         * These functions are declared protected in the base class. Make them
         * visible here. Since we declare the non-const operators, the const
         * operators of the base class are hidden. Redeclare them here.
         */
        //@{
        //! full dimensionality access
        const T& operator()(const TIndexVec& index) const
        { return(this->Tbase::operator()(index)); }
        //! access from 1 index value
        const T& operator()(const Tsubscript& i0) const
        { return(this->Tbase::operator()(i0)); }
        //! access from 2 index values
        const T& operator()(const Tsubscript& i0,
                            const Tsubscript& i1) const
        { return(this->Tbase::operator()(i0, i1)); }
        //! access from 3 index values
        const T& operator()(const Tsubscript& i0,
                            const Tsubscript& i1,
                            const Tsubscript& i2) const
        { return(this->Tbase::operator()(i0, i1, i2)); }
        //! access from 4 index values
        const T& operator()(const Tsubscript& i0,
                            const Tsubscript& i1,
                            const Tsubscript& i2,
                            const Tsubscript& i3) const
        { return(this->Tbase::operator()(i0, i1, i2, i3)); }
        //@}
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
     
        //! tricky: only this class allows the conversion
        operator Trepresentation()
        { return (Trepresentation(this->Tbase)); }

    }; // class Array

  /*======================================================================*/

  /*! \brief specialization for const data
   */
  template<class T>
    class Array<const T>:
      public aff::Strided, private aff::SharedHeap<T>
    {
      public:
        /*! \name Various types
         *
         * In particular due to our concept of const-correctness we need
         * several typedefs to declare types derived from the element type of
         * the array.
         *
         * \sa \ref sec_main_constness
         * \sa aff::util::Qualified<T>
         */
        //@{
        //! Type of representation
        typedef aff::SharedHeap<T> Trepresentation;
        //! Type of subscriptor
        typedef aff::Strided Tshape;
        //! Element type
        typedef const T Tvalue;
        //! Type of pointer to element
        typedef const T* Tpointer;
        //! Type of reference to element
        typedef const T& Treference;
        //! Type of this array
        typedef Array<T> Tcontainer;
        //! Type of the array of const values
        typedef Tcontainer Tcontainer_of_const;
        /*! \brief short for Tcontainer_of_const
         *
         * We generally distinguish between constness of the array and
         * constness of the contained data (see \ref sec_main_constness).
         * There will be situations, when you want to promise that a function
         * will not change the contents of an array. In this case you may use
         * a declaration (prototype) like
         * \code
         *   typedef aff::Array<int> Tmyarray;
         *   void myfunction(const Tmyarray::Tcoc& array);
         * \endcode
         * and you may use this function like
         * \code
         *   Tmyarray A(6,7);
         *   A=4;
         *   myfunction(A);
         * \endcode
         */
        typedef Tcontainer Tcoc;
        //@}

        /*-----------------------------------------------------------------*/
        
        /*! \name Constructors
         *
         * \note
         * We use the default copy constructor, which automatically invokes
         * the copy constructors of the base classes aff::Strided and
         * aff::SharedHeap<T>. This essentially is a shallow copy of the
         * array, i.e. the copy will reference to the same elements in memory.
         * See aff::Array<T>::copyin() and aff::Array<T>::copyout() for deep
         * copy operations.
         */
        //@{
        //! construct from nothing (empty)
        Array() { }
        //! construct from shape and representation
        Array(const Tshape& shape, 
              const Trepresentation& representation);
        //! construct from shape (defines size and layout)
        explicit Array(const Tshape& shape);
        //! construct from index range limit
        explicit Array(const Tsize& s0);
        //! construct from index range limits
        Array(const Tsize& s0, const Tsize& s1);
        //! construct from index range limits
        Array(const Tsize& s0, const Tsize& s1, const Tsize& s2);
        //! construct from index range limits
        Array(const Tsize& s0, const Tsize& s1, 
              const Tsize& s2, const Tsize& s3);
thomas.forbriger's avatar
thomas.forbriger committed
332
333
334
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
335
      
thomas.forbriger's avatar
thomas.forbriger committed
336
337
338
339
340
341
342
343
344
        /*! \name Const access operators
         *
         * Although we generally distinguish between the constness of the
         * container and the constness of the contained data (see 
         * \ref sec_main_constness), we provide const element access operators
         * the prohibit element modification. We assume that a const version
         * of the array is usually meant to be used only for reading.
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
345
        //! full dimensionality access
346
        const T& operator()(const TIndexVec& index) const
thomas.forbriger's avatar
thomas.forbriger committed
347
348
349
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(index))); }
        //! access from 1 index value
350
        const T& operator()(const Tsubscript& i0) const
thomas.forbriger's avatar
thomas.forbriger committed
351
352
353
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0))); }
        //! access from 2 index values
354
        const T& operator()(const Tsubscript& i0,
thomas.forbriger's avatar
thomas.forbriger committed
355
356
357
358
                            const Tsubscript& i1) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1))); }
        //! access from 3 index values
359
        const T& operator()(const Tsubscript& i0,
thomas.forbriger's avatar
thomas.forbriger committed
360
361
362
363
364
                            const Tsubscript& i1,
                            const Tsubscript& i2) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1, i2))); }
        //! access from 4 index values
365
        const T& operator()(const Tsubscript& i0,
thomas.forbriger's avatar
thomas.forbriger committed
366
367
368
369
370
                            const Tsubscript& i1,
                            const Tsubscript& i2,
                            const Tsubscript& i3) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1, i2, i3))); }
thomas.forbriger's avatar
thomas.forbriger committed
371
372
373
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
374

thomas.forbriger's avatar
thomas.forbriger committed
375
376
377
        /*! \name Shape access
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
378
379
380
381
382
383
384
        //! return first index of dimension i
        const Tsubscript& f(const Tsubscript& i) const
        { return(this->Tshape::first(i)); }
        //! return last index of dimension i
        const Tsubscript& l(const Tsubscript& i) const
        { return(this->Tshape::last(i)); }

thomas.forbriger's avatar
thomas.forbriger committed
385
386
387
388
389
390
        //! by size we mean the size defined by the shape
        Tsize size(const Tsubscript& i) const
        { return(this->Tshape::size(i)); }
        //! by size we mean the size defined by the shape
        Tsize size() const
        { return(this->Tshape::size()); }
thomas.forbriger's avatar
thomas.forbriger committed
391
        //@}
thomas.forbriger's avatar
thomas.forbriger committed
392

thomas.forbriger's avatar
thomas.forbriger committed
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
        /*! \brief create an identical copy (deep copy) of this array
         *
         * This is mainly used to create a copy of a truely identical array
         * (i.e. array with same element type or at least const version of
         * same element type). Use this function in conjunction with the
         * assignment operator. E.g.:
         * \code
         *   aff::Array<int> A(3,4);
         *   A=5.;
         *   aff::Array<int> B, C;
         *   B=A.copyout();
         *   C=A;
         * \endcode
         * Here arrays \c A and \c B have exactly the same contents but use
         * different memory. While changes to elements of \c C will also
         * affect elements of \c A, this not the case for changes applied to
         * \c B.
         */
thomas.forbriger's avatar
thomas.forbriger committed
411
412
        Array copyout() const;

413
414
415
416
417
418
419
420
        //! offer conversion only to constant version of representation
        operator Trepresentation::Tcoc() const
        { return (*this); }

      /*-----------------------------------------------------------------*/
      // here starts the PROTECTED section!
      // ----------------------------------
      protected:
thomas.forbriger's avatar
thomas.forbriger committed
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
        /*! \brief copy values (deep copy) from other array of convertible type
         *
         * This member function reads the element values of another array of
         * same shape and applies them to this array. In fact the shape needs
         * not be the same. The copy is done through sequential access and as
         * most number as possible will be copied in increasing memory address
         * order.
         *
         * Example:
         * \code
         *   aff::Array<float> A(24);
         *   A=15.
         *   aff::Array<double> B(3,8);
         *   B.copyin(A);
         * \endcode
         * \c B will preserve its shape but is filled with the contents of 
         * \c A (which are not where interesting in this example). Changes
         * applied to the contents of B will not affect the contents of A.
         *
         * \param a other array with element type convertible to element type
         *          of this array
         * \return itself
         */
thomas.forbriger's avatar
thomas.forbriger committed
444
445
        template<class TT>
          Array& copyin(const Array<TT>& a);
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

        /*-----------------------------------------------------------------*/
          
        //! set whole array to value
        Array& operator=(const T& value);

        /*-----------------------------------------------------------------*/
      
        /*! \name Access operators
         */
        //@{
        //! full dimensionality access
        T& operator()(const TIndexVec& index) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(index))); }
        //! access from 1 index value
        T& operator()(const Tsubscript& i0) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0))); }
        //! access from 2 index values
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1))); }
        //! access from 3 index values
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1,
                      const Tsubscript& i2) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1, i2))); }
        //! access from 4 index values
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1,
                      const Tsubscript& i2,
                      const Tsubscript& i3) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1, i2, i3))); }
thomas.forbriger's avatar
thomas.forbriger committed
483
        //@}
484

485
486
487
488
489
490
491
        /*-----------------------------------------------------------------*/

        //! conversion to full representation is protected
        operator Trepresentation()
        { return (*this); }

    }; // class Array<const T>
492

493
494
#ifdef AFF_PREBUILT
} // namespace prebuilt
495
496
#endif

497
} // namespace aff
498

499
500
#ifndef AFF_NO_DEFINITIONS
#include <aff/array_def.h>
501
502
#endif

503
#endif // AFF_ARRAY_DEC_H_VERSION (includeguard)
504
505

/* ----- END OF array_dec.h ----- */