/*! \file array_dec.h * \brief array class declarations (prototypes) * * ---------------------------------------------------------------------------- * * $Id: array_dec.h,v 1.15 2002-12-20 18:26:13 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. * * ============================================================================ */ // include guard #ifndef AFF_ARRAY_DEC_H_VERSION #define AFF_ARRAY_DEC_H_VERSION \ "AFF_ARRAY_DEC_H V1.3" #define AFF_ARRAY_DEC_H_CVSID \ "$Id: array_dec.h,v 1.15 2002-12-20 18:26:13 forbrig Exp $" #include #include namespace aff { #ifdef AFF_PREBUILT 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 * * \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. * * \todo * documentation of class Array must be reworked * * \todo * Explain the new concept of multidimensional array indexing * * \sa aff::Strided * \sa aff::SharedHeap * \sa aff::Array::copyin() * \sa aff::Array::copyout() */ template class Array: public Array { 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_const */ //@{ //! Type of this array typedef Array Tcontainer; //! base is container of const (see specialization below) typedef Array 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 */ typedef Tbase Tcoc; //! Type of representation typedef SharedHeap Trepresentation; //! Type of subscriptor typedef Strided Tshape; //! Element type typedef T Tvalue; //! Type of pointer to element typedef T* Tpointer; //! Type of reference to element typedef T& Treference; //@} /*-----------------------------------------------------------------*/ /*! \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(): Tbase() { } //! construct from shape and representation Array(const Tshape& shape, const Trepresentation& representation): Tbase(shape, representation) { } //! construct from shape (defines size and layout) explicit Array(const Tshape& shape): Tbase(shape) { } //! construct from index range limits explicit Array(const Tsize& s0, const Tsize& s1=1, const Tsize& s2=1, const Tsize& s3=1): Tbase(s0, s1, s2, s3) { } //@} /*-----------------------------------------------------------------*/ //! \name access declarations //@{ //! access to base class function Tbase::operator(); Tbase::operator=; Tbase::copyin; Tbase::shape; //@} //! 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 Array& copyin(const Array& a) { this->Tbase::copyin(a); return(*this); } //! return full access representation 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); } }; // class Array /*======================================================================*/ /*! \brief specialization for const data */ template class Array: private aff::Strided, private aff::SharedHeap { 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_const */ //@{ //! Type of representation typedef aff::SharedHeap Tmutable_representation; //! Type of representation typedef aff::SharedHeap 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; //! Type of this array typedef Array 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_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 */ 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) Array() { } //! construct from shape and representation Array(const Tshape& shape, const Tmutable_representation& representation); //! construct from shape (defines size and layout) explicit Array(const Tshape& shape); //! construct from index range limits explicit Array(const Tsize& s0, const Tsize& s1=1, const Tsize& s2=1, const Tsize& s3=1); //@} /*-----------------------------------------------------------------*/ /*! \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(this->Trepresentation::operator[]( this->Tshape::offset(index))); } //! access from 1 index value const T& operator()(const Tsubscript& i0) const { return(this->Trepresentation::operator[]( this->Tshape::offset(i0))); } //! access from 2 index values const T& operator()(const Tsubscript& i0, const Tsubscript& i1) const { return(this->Trepresentation::operator[]( this->Tshape::offset(i0, i1))); } //! access from 3 index values const T& 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 T& 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))); } //@} /*-----------------------------------------------------------------*/ /*! \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. */ Array copyout() const; //! \name access declarations //@{ //! access to base class function Tshape::first; Tshape::last; Tshape::size; //@} //! provide access to const shape const Tshape& shape() const { return(*this); } //! provide restricted access representation const SharedHeap& representation() const { return (*this); } /*-----------------------------------------------------------------*/ // here starts the PROTECTED section! // ---------------------------------- protected: /*! \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 array with element type convertible to element type * of this array * \return itself */ template Array& copyin(const Array& a); /*-----------------------------------------------------------------*/ //! set whole array to value Array& operator=(const T& value); /*-----------------------------------------------------------------*/ /*! \name Access operators */ //@{ //! full dimensionality access T& operator()(const TIndexVec& index) { return(this->Tmutable_representation::operator[]( this->Tshape::offset(index))); } //! access from 1 index value T& operator()(const Tsubscript& i0) { return(this->Tmutable_representation::operator[]( this->Tshape::offset(i0))); } //! access from 2 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1) { return(this->Tmutable_representation::operator[]( this->Tshape::offset(i0, i1))); } //! access from 3 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1, const Tsubscript& i2) { return(this->Tmutable_representation::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->Tmutable_representation::operator[]( this->Tshape::offset(i0, i1, i2, i3))); } //@} /*-----------------------------------------------------------------*/ //! return full access representation const SharedHeap& mutable_representation() { return (*this); } }; // 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 ----- */