array_dec.h 12.3 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.5 2002-12-13 22:38:24 forbrig Exp $
7
 * \author Thomas Forbriger
8
 * \since 08/12/2002
9
10
 * 
 * array class declarations (prototypes)
11
12
13
14
15
16
 *
 * \note
 * This should never be included directly. Use array.h or binarray.h instead.
 *
 * \todo 
 * Do we need the using directive?
17
18
19
20
 * 
 * Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt) 
 * 
 * REVISIONS and CHANGES 
21
 *  - 08/12/2002   V1.0   copied from libcontxx
22
23
24
25
26
 * 
 * ============================================================================
 */

// include guard
27
#ifndef AFF_ARRAY_DEC_H_VERSION
28

29
30
31
#define AFF_ARRAY_DEC_H_VERSION \
  "AFF_ARRAY_DEC_H   V1.0   "
#define AFF_ARRAY_DEC_H_CVSID \
thomas.forbriger's avatar
thomas.forbriger committed
32
  "$Id: array_dec.h,v 1.5 2002-12-13 22:38:24 forbrig Exp $"
33

34
35
36
#include <aff/sharedheap.h>
#include <aff/strided.h>
#include <aff/range.h>
37

38
namespace aff {
39

40
#ifdef AFF_PREBUILT
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
60
   *
thomas.forbriger's avatar
thomas.forbriger committed
61
62
63
64
65
66
67
68
   * \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.
   *
69
70
71
72
73
74
75
76
   * \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
77
78
79
80
81
   *
   * \sa aff::Strided
   * \sa aff::SharedHeap<T>
   * \sa aff::Array<T>::copyin()
   * \sa aff::Array<T>::copyout()
82
   */
thomas.forbriger's avatar
thomas.forbriger committed
83
  template<class T>
84
    class Array:
thomas.forbriger's avatar
thomas.forbriger committed
85
      public aff::Strided, public aff::SharedHeap<T>
86
    {
thomas.forbriger's avatar
thomas.forbriger committed
87
      public:
thomas.forbriger's avatar
thomas.forbriger committed
88
89
90
91
92
93
94
95
96
97
        /*! \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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
        //! Type of representation
        typedef aff::SharedHeap<T> Trepresentation;
        //! Type of subscriptor
        typedef aff::Strided Tshape;
        //! Element type
        typedef typename Trepresentation::Tvalue Tvalue;
        //! Type of pointer to element
        typedef typename Trepresentation::Tpointer Tpointer;
        //! Type of reference to element
        typedef typename Trepresentation::Treference Treference;
        //! Type of const reference to element
        typedef typename Trepresentation::Tconst_reference Tconst_reference;
        //! Type to be used as data representation
        typedef typename Trepresentation::Tmutable_value Tmutable_value;
        //! Type to be used as element for const version
        typedef typename Trepresentation::Tconst_value Tconst_value;
        //! Type of this array
        typedef Array<T> Tcontainer;
        //! Type of the array of const values
        typedef Array<Tconst_value> Tcontainer_of_const;
thomas.forbriger's avatar
thomas.forbriger committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        /*! \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
         */
thomas.forbriger's avatar
thomas.forbriger committed
136
        typedef Array<Tconst_value> Tcoc;
thomas.forbriger's avatar
thomas.forbriger committed
137
        //@}
thomas.forbriger's avatar
thomas.forbriger committed
138

thomas.forbriger's avatar
thomas.forbriger committed
139
140
141
142
143
144
145
146
147
148
149
150
151
        /*-----------------------------------------------------------------*/
        
        /*! \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
152
153
154
155
156
157
158
        //! 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);
thomas.forbriger's avatar
thomas.forbriger committed
159
160
161
162
163
164
165
166
167
        //! 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
168
169
170
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
171
      
thomas.forbriger's avatar
thomas.forbriger committed
172
173
174
        /*! \name Access operators
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        //! full dimensionality access
        Tvalue& operator()(const TIndexVec& index) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(index))); }
        //! access from 1 index value
        Tvalue& operator()(const Tsubscript& i0) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0))); }
        //! access from 2 index values
        Tvalue& operator()(const Tsubscript& i0,
                            const Tsubscript& i1) 
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1))); }
        //! access from 3 index values
        Tvalue& 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
        Tvalue& 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
201
202
203
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
204
      
thomas.forbriger's avatar
thomas.forbriger committed
205
206
207
208
209
210
211
212
213
        /*! \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
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
        //! full dimensionality access
        const Tvalue& operator()(const TIndexVec& index) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(index))); }
        //! access from 1 index value
        const Tvalue& operator()(const Tsubscript& i0) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0))); }
        //! access from 2 index values
        const Tvalue& operator()(const Tsubscript& i0,
                            const Tsubscript& i1) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1))); }
        //! access from 3 index values
        const Tvalue& operator()(const Tsubscript& i0,
                            const Tsubscript& i1,
                            const Tsubscript& i2) const
        { return(this->Trepresentation::operator[](
                       this->Tshape::offset(i0, i1, i2))); }
        //! access from 4 index values
        const Tvalue& operator()(const Tsubscript& i0,
                            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
240
241
242
        //@}

        /*-----------------------------------------------------------------*/
thomas.forbriger's avatar
thomas.forbriger committed
243
244
245
246
247
248
249
250

        //! conversion to container of const values
        operator Tcontainer_of_const() const
        {
          Tcontainer_of_const retval(*this, *this);
          return(retval);
        }

thomas.forbriger's avatar
thomas.forbriger committed
251
252
253
        /*! \name Shape access
         */
        //@{
thomas.forbriger's avatar
thomas.forbriger committed
254
255
256
257
258
259
260
        //! 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
261
262
263
264
265
266
        //! 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
267
        //@}
thomas.forbriger's avatar
thomas.forbriger committed
268
269
270
271
          
        //! set whole array to value
        Array& operator=(const T& value);

thomas.forbriger's avatar
thomas.forbriger committed
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
        /*! \name Deep copy
         */
        //@{
        /*! \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
293
294
        Array copyout() const;

thomas.forbriger's avatar
thomas.forbriger committed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
        /*! \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
318
319
        template<class TT>
          Array& copyin(const Array<TT>& a);
thomas.forbriger's avatar
thomas.forbriger committed
320
        //@}
321
322
323

    }; // class Array

324
325
#ifdef AFF_PREBUILT
} // namespace prebuilt
326
327
#endif

328
} // namespace aff
329

330
331
#ifndef AFF_NO_DEFINITIONS
#include <aff/array_def.h>
332
333
#endif

334
#endif // AFF_ARRAY_DEC_H_VERSION (includeguard)
335
336

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