/*! \file array_dec.h * \brief array class declarations (prototypes) * * ---------------------------------------------------------------------------- * * $Id: array_dec.h,v 1.20 2002-12-31 17:19:46 forbrig Exp $ * \author Thomas Forbriger * \since 08/12/2002 * * array class declarations (prototypes) * * \note * This should never be included directly. Use array.h or binarray.h instead. * * Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt) * * REVISIONS and CHANGES * - 08/12/2002 V1.0 copied from libcontxx * - 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 * - 17/12/2002 V1.2 (thof) * - introduced access declarations * - 19/12/2002 V1.3 (thof) * - provide read access to base classes * and read/write access to representation of * non-const array * - replaced four size-argument constructors by one * constructor with default arguments * - distinguish between mutable and non-mutable * representation * - 20/12/2002 V1.4 (thof) * - Access declarations are nor useable with functions * that return a reference to *this. They must be * reimplemented. * - 23/12/2002 V1.5 (thof) * - copyin() and copyout() work * - 28/12/2002 V1.6 (thof) * - changed base class from specialization to * independent class template * - 29/12/2002 V1.7 (thof) * - ConstArray now inherits from ConstSharedHeap * (see "\ref sec_design_replicated") * - use "using" syntax for access declarations * - arrays do no longer derive from shared heap * classes * - reworked shared heap access concept fundamentally; * code looks much simpler now * - member template must be defined here * - factored out copyin code * - 31/12/2002 V1.8 (thof) * - Removed non-initializing constructors in * ConstArray (except default constructor, which is * needed, when object is a container element) as * suggested by Wolfgang. * * ============================================================================ */ // include guard #ifndef AFF_ARRAY_DEC_H_VERSION #define AFF_ARRAY_DEC_H_VERSION \ "AFF_ARRAY_DEC_H V1.8" #define AFF_ARRAY_DEC_H_CVSID \ "$Id: array_dec.h,v 1.20 2002-12-31 17:19:46 forbrig Exp $" #include #include #include #include namespace aff { #ifdef AFF_PREBUILT namespace prebuilt { #endif /*! \brief Array base class * * This is a multidimensional (array) container that uses a strided memory * layout (Fortran shape) and counted references to data in global memory. * For examples see the various test programs. * * \sa \ref sec_design_multidimensional * \sa \ref sec_design_interface * \sa \ref sec_design_const * \sa \ref page_representation * \sa \ref sec_design_replicated * \sa aff::Strided * \sa aff::SharedHeap * \sa tests/arraytest.cc * \sa tests/f77test.cc * \sa tests/helpertest.cc */ template class ConstArray: private aff::Strided { 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. * * This is in particular usefull for function templates that may take * any container class as argument (e.g. aff::subarray) or for other * classes dealing with any container (e.g. aff::Iterator). * By means of these typedefs they may retrieve appropriate types they * have to deal with. * * \sa \ref sec_design_interface_typedef * \sa \ref sec_design_const */ //@{ //! Type of representation typedef aff::ConstSharedHeap Trepresentation; //! Type of shape 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; //! const element type typedef const T Tconst_value; //! Type of pointer to const element typedef const T* Tconst_pointer; //! Type of reference to const element typedef const T& Tconst_reference; //! Type of this array typedef ConstArray Tcontainer; //! Type of the array of const values typedef Tcontainer Tcontainer_of_const; //! Short for Tcontainer_of_const 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. This essentially is a shallow copy of the * array, i.e. the copy will reference to the same elements in memory. * See aff::Array::copyin() and aff::Array::copyout() for deep * copy operations. */ //@{ //! construct from nothing (empty) ConstArray() { } //! construct from shape and representation ConstArray(const Tshape& shape, const Trepresentation& representation): Tshape(shape), Mrepresentation(representation) { check_consistency(); } //@} /*-----------------------------------------------------------------*/ /*! \name Const access operators * * Although we generally distinguish between the constness of the * container and the constness of the contained data (see * \ref sec_design_const), 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. */ //@{ //! full dimensionality access const T& operator()(const TIndexVec& index) const { return(Mrepresentation[offset(index)]); } //! access from 1 index value const T& operator()(const Tsubscript& i0) const { return(Mrepresentation[offset(i0)]); } //! access from 2 index values const T& operator()(const Tsubscript& i0, const Tsubscript& i1) const { return(Mrepresentation[offset(i0, i1)]); } //! access from 3 index values const T& operator()(const Tsubscript& i0, const Tsubscript& i1, const Tsubscript& i2) const { return(Mrepresentation[offset(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(Mrepresentation[offset(i0, i1, i2, i3)]); } //@} /*-----------------------------------------------------------------*/ /*! \name Shape access */ //@{ //! 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)); } //@} /*! \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 A(3,4); * A=5.; * aff::Array 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. */ Tcontainer copyout() const; //! \name access declarations //@{ //! access to base class function using Tshape::first; using Tshape::last; using Tshape::size; //@} //! provide access to const shape const Tshape& shape() const { return(*this); } //! provide restricted access representation const Trepresentation& representation() const { return (Mrepresentation); } protected: //! provide access to shape offset functions for derived class using Tshape::offset; private: //! check consitency between representation and shape void check_consistency() const; //! representation member Trepresentation Mrepresentation; }; // class ConstArray /*======================================================================*/ /*! \brief Full multi-dimensional array functionality. * * This is the full array class template. It adds no additional * functionality to its base class aff::ConstArray. But it provied acess to * all member functions of the base, also to functions that allow data * modification. * * \sa aff::ConstArray * \sa \ref sec_design_const * \sa \ref sec_design_replicated */ template class Array: public ConstArray { 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_design_interface_typedef * \sa \ref sec_design_const */ //@{ //! Type of this array typedef Array Tcontainer; //! base is container of const (see specialization below) typedef aff::ConstArray Tbase; //! Type of the array of const values typedef Tbase 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_design_const). * 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 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 * * \sa \ref sec_design_const */ typedef Tbase Tcoc; //! Type of representation typedef aff::SharedHeap Trepresentation; //! Type of subscriptor typedef aff::Strided Tshape; //! Element type typedef T Tvalue; //! Type of pointer to element typedef T* Tpointer; //! Type of reference to element typedef T& Treference; //! const element type typedef const T Tconst_value; //! Type of pointer to const element typedef const T* Tconst_pointer; //! Type of reference to const element typedef const T& Tconst_reference; //@} /*-----------------------------------------------------------------*/ /*! \name Constructors * * \note * We use the default copy constructor, which automatically invokes * the copy constructors of the base classes aff::Strided and * aff::SharedHeap. This essentially is a shallow copy of the * array, i.e. the copy will reference to the same elements in memory. * See aff::Array::copyin() and aff::Array::copyout() for deep * copy operations. */ //@{ //! construct from nothing (empty) Array() { } //! construct from shape and representation Array(const Tshape& shape, const Trepresentation& representation): Tbase(shape, representation), Mrepresentation(representation) { } //! construct from shape (defines size and layout) explicit Array(const Tshape& shape) { Tshape newshape(shape.first(), shape.last()); Mrepresentation=Trepresentation(newshape.memory_size()); this->Tbase::operator=(Tbase(newshape, Mrepresentation)); } //! construct from dimension sizes explicit Array(const Tsize& s0, const Tsize& s1=1, const Tsize& s2=1, const Tsize& s3=1) { Tshape newshape(s0, s1, s2, s3); Mrepresentation=Trepresentation(newshape.memory_size()); this->Tbase::operator=(Tbase(newshape, Mrepresentation)); } //@} /*-----------------------------------------------------------------*/ //! \name access declarations //@{ //! access to base class function using Tbase::operator(); using Tbase::shape; //@} /*! \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 A(24); * A=15. * aff::Array 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 container with element type convertible to element * type of this array and appropriate stepper class * \return itself */ template Array& copyin(const C& a) { aff::util::deepcopy(a, *this); return(*this); } //! create a copy of this array Tcontainer copyout() const { Tcontainer copy(Tshape(this->first(),this->last())); copy.copyin(*this); return(copy); } //! return full access representation const Trepresentation& representation() { return (Mrepresentation); } /*-----------------------------------------------------------------*/ //! set whole array to value Tcontainer& operator=(const T& value); /*-----------------------------------------------------------------*/ //! full dimensionality access T& operator()(const TIndexVec& index) { return(Mrepresentation[this->Tbase::offset(index)]); } //! access from 1 index value T& operator()(const Tsubscript& i0) { return(Mrepresentation[this->Tbase::offset(i0)]); } //! access from 2 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1) { return(Mrepresentation[this->Tbase::offset(i0, i1)]); } //! access from 3 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1, const Tsubscript& i2) { return(Mrepresentation[this->Tbase::offset(i0, i1, i2)]); } //! access from 4 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1, const Tsubscript& i2, const Tsubscript& i3) { return(Mrepresentation[this->Tbase::offset(i0, i1, i2, i3)]); } private: //! my (mutable) data representation Trepresentation Mrepresentation; }; // class Array /*----------------------------------------------------------------------*/ #ifdef AFF_PREBUILT } // namespace prebuilt #endif } // namespace aff #ifndef AFF_NO_DEFINITIONS #include #endif #endif // AFF_ARRAY_DEC_H_VERSION (includeguard) /* ----- END OF array_dec.h ----- */