/*! \file array_dec.h * \brief array class declarations (prototypes) * * ---------------------------------------------------------------------------- * * $Id: array_dec.h,v 1.8 2002-12-16 21:03:25 uid1201 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 * * ============================================================================ */ // include guard #ifndef AFF_ARRAY_DEC_H_VERSION #define AFF_ARRAY_DEC_H_VERSION \ "AFF_ARRAY_DEC_H V1.1" #define AFF_ARRAY_DEC_H_CVSID \ "$Id: array_dec.h,v 1.8 2002-12-16 21:03:25 uid1201 Exp $" #include #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_shapes_and_subscriptors * \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 * class Array must be reworked itself entirely * * \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_main_constness * \sa aff::util::Qualified */ //@{ //! 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_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 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 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; //@} /*-----------------------------------------------------------------*/ /*! \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 limit explicit Array(const Tsize& s0): Tbase(s0) { } //! construct from index range limits Array(const Tsize& s0, const Tsize& s1): Tbase(s0, s1) { } //! construct from index range limits Array(const Tsize& s0, const Tsize& s1, const Tsize& s2): Tbase(s0, s1, s2) { } //! construct from index range limits Array(const Tsize& s0, const Tsize& s1, const Tsize& s2, const Tsize& s3): Tbase(s0, s1, s2, s3) { } //@} /*-----------------------------------------------------------------*/ /*! \name Data modification functions * * These functions are declared protected in the base class. Make them * visible here. */ //@{ //! full dimensionality access T& operator()(const TIndexVec& index) { return(this->Tbase::operator()(index)); } //! access from 1 index value T& operator()(const Tsubscript& i0) { return(this->Tbase::operator()(i0)); } //! access from 2 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1) { return(this->Tbase::operator()(i0, i1)); } //! access from 3 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1, const Tsubscript& i2) { return(this->Tbase::operator()(i0, i1, i2)); } //! access from 4 index values T& operator()(const Tsubscript& i0, const Tsubscript& i1, const Tsubscript& i2, const Tsubscript& i3) { 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 Array& copyin(const Array& a) { return(this->Tbase::copyin(a)); } //@} /*! \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)); } //@} //! tricky: only this class allows the conversion operator Trepresentation() { return (Trepresentation(this->Tbase)); } }; // class Array /*======================================================================*/ /*! \brief specialization for const data */ template class Array: public 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_main_constness * \sa aff::util::Qualified */ //@{ //! Type of representation typedef aff::SharedHeap 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 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 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 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); //@} /*-----------------------------------------------------------------*/ /*! \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. */ //@{ //! 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)); } //! 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()); } //@} /*! \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; //! offer conversion only to constant version of representation operator Trepresentation::Tcoc() 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->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))); } //@} /*-----------------------------------------------------------------*/ //! conversion to full representation is protected operator Trepresentation() { 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 ----- */