array_dec.h 16.8 KB
Newer Older
1
2
3
4
5
/*! \file array_dec.h
 * \brief array class declarations (prototypes)
 * 
 * ----------------------------------------------------------------------------
 * 
thomas.forbriger's avatar
thomas.forbriger committed
6
 * $Id: array_dec.h,v 1.15 2002-12-20 18:26:13 forbrig 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
thomas.forbriger's avatar
...    
thomas.forbriger committed
23
24
 *  - 17/12/2002   V1.2   (thof)
 *                        - introduced access declarations
thomas.forbriger's avatar
thomas.forbriger committed
25
26
27
28
 *  - 19/12/2002   V1.3   (thof)
 *                        - provide read access to base classes
 *                          and read/write access to representation of
 *                          non-const array
thomas.forbriger's avatar
thomas.forbriger committed
29
30
31
32
 *                        - replaced four size-argument constructors by one
 *                          constructor with default arguments
 *                        - distinguish between mutable and non-mutable
 *                          representation
thomas.forbriger's avatar
thomas.forbriger committed
33
34
35
36
 *  - 20/12/2002   V1.4   (thof)
 *                        - Access declarations are nor useable with functions
 *                          that return a reference to *this. They must be
 *                          reimplemented.
37
38
39
40
41
 * 
 * ============================================================================
 */

// include guard
42
#ifndef AFF_ARRAY_DEC_H_VERSION
43

44
#define AFF_ARRAY_DEC_H_VERSION \
thomas.forbriger's avatar
thomas.forbriger committed
45
  "AFF_ARRAY_DEC_H   V1.3"
46
#define AFF_ARRAY_DEC_H_CVSID \
thomas.forbriger's avatar
thomas.forbriger committed
47
  "$Id: array_dec.h,v 1.15 2002-12-20 18:26:13 forbrig Exp $"
48

thomas.forbriger's avatar
thomas.forbriger committed
49
50
#include <aff/lib/sharedheap.h>
#include <aff/lib/strided.h>
51

52
namespace aff {
53

54
#ifdef AFF_PREBUILT
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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_representation
   * \sa \ref sec_main_modules
   * \sa tests/arraytest.cc
73
   *
thomas.forbriger's avatar
thomas.forbriger committed
74
75
76
77
78
79
80
81
   * \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.
   *
82
83
84
85
86
   * \todo
   * documentation of class Array must be reworked
   *
   * \todo 
   * Explain the new concept of multidimensional array indexing
thomas.forbriger's avatar
thomas.forbriger committed
87
88
89
90
91
   *
   * \sa aff::Strided
   * \sa aff::SharedHeap<T>
   * \sa aff::Array<T>::copyin()
   * \sa aff::Array<T>::copyout()
92
   */
thomas.forbriger's avatar
thomas.forbriger committed
93
  template<class T>
94
    class Array:
95
      public Array<const T>
96
    {
thomas.forbriger's avatar
thomas.forbriger committed
97
      public:
thomas.forbriger's avatar
thomas.forbriger committed
98
99
100
101
102
103
        /*! \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.
         *
thomas.forbriger's avatar
thomas.forbriger committed
104
         * \sa \ref sec_design_const
thomas.forbriger's avatar
thomas.forbriger committed
105
106
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
107
108
        //! Type of this array
        typedef Array<T> Tcontainer;
109
110
        //! base is container of const (see specialization below)
        typedef Array<const T> Tbase;
thomas.forbriger's avatar
thomas.forbriger committed
111
        //! Type of the array of const values
112
        typedef Tbase Tcontainer_of_const;
thomas.forbriger's avatar
thomas.forbriger committed
113
114
115
        /*! \brief short for Tcontainer_of_const
         *
         * We generally distinguish between constness of the array and
thomas.forbriger's avatar
thomas.forbriger committed
116
         * constness of the contained data (see \ref sec_design_const).
thomas.forbriger's avatar
thomas.forbriger committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
         * 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
         */
131
132
        typedef Tbase Tcoc;
        //! Type of representation
thomas.forbriger's avatar
thomas.forbriger committed
133
        typedef SharedHeap<T> Trepresentation;
134
        //! Type of subscriptor
thomas.forbriger's avatar
thomas.forbriger committed
135
        typedef Strided Tshape;
136
137
138
139
140
141
        //! 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
142
        //@}
thomas.forbriger's avatar
thomas.forbriger committed
143

thomas.forbriger's avatar
thomas.forbriger committed
144
145
146
147
148
149
150
151
152
153
154
155
156
        /*-----------------------------------------------------------------*/
        
        /*! \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
157
        //! construct from nothing (empty)
158
        Array(): Tbase() { }
thomas.forbriger's avatar
thomas.forbriger committed
159
160
        //! construct from shape and representation
        Array(const Tshape& shape, 
161
162
              const Trepresentation& representation):
          Tbase(shape, representation) { }
thomas.forbriger's avatar
thomas.forbriger committed
163
        //! construct from shape (defines size and layout)
164
165
        explicit Array(const Tshape& shape):
          Tbase(shape) { }
thomas.forbriger's avatar
thomas.forbriger committed
166
        //! construct from index range limits
thomas.forbriger's avatar
thomas.forbriger committed
167
168
        explicit Array(const Tsize& s0, const Tsize& s1=1, 
                       const Tsize& s2=1, const Tsize& s3=1):
169
          Tbase(s0, s1, s2, s3) { }
thomas.forbriger's avatar
thomas.forbriger committed
170
171
172
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
173
      
thomas.forbriger's avatar
thomas.forbriger committed
174
        //! \name access declarations
thomas.forbriger's avatar
thomas.forbriger committed
175
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
176
177
178
179
        //! access to base class function
        Tbase::operator();
        Tbase::operator=;
        Tbase::copyin;
thomas.forbriger's avatar
thomas.forbriger committed
180
        Tbase::shape;
181
        //@}
thomas.forbriger's avatar
thomas.forbriger committed
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
          
        //! set whole array to value
        Array& operator=(const T& value)
        { 
          this->Tbase::operator=(value);
          return(*this);
        }

        //! copy in is allowed here (delegate to base)
        template<class TT>
          Array& copyin(const Array<TT>& a)
          {
            this->Tbase::copyin(a);
            return(*this);
          }
197
     
thomas.forbriger's avatar
thomas.forbriger committed
198
        //! return full access representation
thomas.forbriger's avatar
thomas.forbriger committed
199
200
201
202
203
204
205
206
        const Trepresentation& representation()
        { return (this->Tbase::mutable_representation()); }

      private:
        //! reimplement copy operator for base class to override access
        //! declaration
        Tcontainer& operator=(const Tcoc& array) 
        { AFF_abort("illegal call"); return(*this); }
207
208
209
210
211
212
213
214
215

    }; // class Array

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

  /*! \brief specialization for const data
   */
  template<class T>
    class Array<const T>:
thomas.forbriger's avatar
thomas.forbriger committed
216
      private aff::Strided, private aff::SharedHeap<T>
217
218
219
220
221
222
223
224
    {
      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.
         *
thomas.forbriger's avatar
thomas.forbriger committed
225
         * \sa \ref sec_design_const
226
227
228
         */
        //@{
        //! Type of representation
thomas.forbriger's avatar
thomas.forbriger committed
229
230
231
        typedef aff::SharedHeap<T> Tmutable_representation;
        //! Type of representation
        typedef aff::SharedHeap<const T> Trepresentation;
thomas.forbriger's avatar
thomas.forbriger committed
232
        //! Type of shape
233
234
235
236
237
238
239
240
        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
thomas.forbriger's avatar
thomas.forbriger committed
241
        typedef Array<const T> Tcontainer;
242
243
244
245
246
        //! 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
thomas.forbriger's avatar
thomas.forbriger committed
247
         * constness of the contained data (see \ref sec_design_const).
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
         * 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, 
thomas.forbriger's avatar
thomas.forbriger committed
282
              const Tmutable_representation& representation);
283
284
285
        //! construct from shape (defines size and layout)
        explicit Array(const Tshape& shape);
        //! construct from index range limits
thomas.forbriger's avatar
thomas.forbriger committed
286
287
        explicit Array(const Tsize& s0, const Tsize& s1=1, 
                       const Tsize& s2=1, const Tsize& s3=1);
thomas.forbriger's avatar
thomas.forbriger committed
288
289
290
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
291
      
thomas.forbriger's avatar
thomas.forbriger committed
292
293
294
295
        /*! \name Const access operators
         *
         * Although we generally distinguish between the constness of the
         * container and the constness of the contained data (see 
thomas.forbriger's avatar
thomas.forbriger committed
296
         * \ref sec_design_const), we provide const element access operators
thomas.forbriger's avatar
thomas.forbriger committed
297
298
299
300
         * 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
301
        //! full dimensionality access
302
        const T& operator()(const TIndexVec& index) const
thomas.forbriger's avatar
thomas.forbriger committed
303
304
305
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(index))); }
        //! access from 1 index value
306
        const T& operator()(const Tsubscript& i0) const
thomas.forbriger's avatar
thomas.forbriger committed
307
308
309
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0))); }
        //! access from 2 index values
310
        const T& operator()(const Tsubscript& i0,
thomas.forbriger's avatar
thomas.forbriger committed
311
312
313
314
                            const Tsubscript& i1) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1))); }
        //! access from 3 index values
315
        const T& operator()(const Tsubscript& i0,
thomas.forbriger's avatar
thomas.forbriger committed
316
317
318
319
320
                            const Tsubscript& i1,
                            const Tsubscript& i2) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1, i2))); }
        //! access from 4 index values
321
        const T& operator()(const Tsubscript& i0,
thomas.forbriger's avatar
thomas.forbriger committed
322
323
324
325
326
                            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
327
328
329
        //@}

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

thomas.forbriger's avatar
thomas.forbriger committed
331
332
333
        /*! \name Shape access
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
334
335
336
337
338
339
        //! 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
340
        //@}
thomas.forbriger's avatar
thomas.forbriger committed
341

thomas.forbriger's avatar
thomas.forbriger committed
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
        /*! \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
360
        Array copyout() const;
thomas.forbriger's avatar
thomas.forbriger committed
361
362
363
364
365
366
367
368
369
      
        //! \name access declarations
        //@{
        //! access to base class function
        Tshape::first;
        Tshape::last;
        Tshape::size;
        //@}
     
thomas.forbriger's avatar
thomas.forbriger committed
370
371
372
373
374
        //! provide access to const shape
        const Tshape& shape() const
        { return(*this); }
     
        //! provide restricted access representation
thomas.forbriger's avatar
thomas.forbriger committed
375
        const SharedHeap<const T>& representation() const
thomas.forbriger's avatar
thomas.forbriger committed
376
        { return (*this); }
377
378
379
380
381

      /*-----------------------------------------------------------------*/
      // here starts the PROTECTED section!
      // ----------------------------------
      protected:
thomas.forbriger's avatar
thomas.forbriger committed
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
        /*! \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
405
406
        template<class TT>
          Array& copyin(const Array<TT>& a);
407
408
409
410
411
412
413
414
415
416
417
418
419

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

        /*-----------------------------------------------------------------*/
      
        /*! \name Access operators
         */
        //@{
        //! full dimensionality access
        T& operator()(const TIndexVec& index) 
thomas.forbriger's avatar
thomas.forbriger committed
420
        { return(this->Tmutable_representation::operator[](
421
422
423
                       this->Tshape::offset(index))); }
        //! access from 1 index value
        T& operator()(const Tsubscript& i0) 
thomas.forbriger's avatar
thomas.forbriger committed
424
        { return(this->Tmutable_representation::operator[](
425
426
427
428
                       this->Tshape::offset(i0))); }
        //! access from 2 index values
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1) 
thomas.forbriger's avatar
thomas.forbriger committed
429
        { return(this->Tmutable_representation::operator[](
430
431
432
433
434
                       this->Tshape::offset(i0, i1))); }
        //! access from 3 index values
        T& operator()(const Tsubscript& i0,
                      const Tsubscript& i1,
                      const Tsubscript& i2) 
thomas.forbriger's avatar
thomas.forbriger committed
435
        { return(this->Tmutable_representation::operator[](
436
437
438
439
440
441
                       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) 
thomas.forbriger's avatar
thomas.forbriger committed
442
        { return(this->Tmutable_representation::operator[](
443
                       this->Tshape::offset(i0, i1, i2, i3))); }
thomas.forbriger's avatar
thomas.forbriger committed
444
        //@}
445

446
        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
447
448
     
        //! return full access representation
thomas.forbriger's avatar
thomas.forbriger committed
449
        const SharedHeap<T>& mutable_representation()
450
451
452
        { return (*this); }

    }; // class Array<const T>
453

454
455
#ifdef AFF_PREBUILT
} // namespace prebuilt
456
457
#endif

458
} // namespace aff
459

460
461
#ifndef AFF_NO_DEFINITIONS
#include <aff/array_def.h>
462
463
#endif

464
#endif // AFF_ARRAY_DEC_H_VERSION (includeguard)
465
466

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