Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!usc!cs.utexas.edu!uunet!mcvax!kth!sunic!liuida!isy!news From: tobbe@isy.liu.se (Torbjorn Kronander) Newsgroups: gnu.g++ Subject: Re: fetching the multi-dimensional array classes Message-ID: <1989Jul3.220630.4764@isy.liu.se> Date: 3 Jul 89 22:06:30 GMT References: <1041@aber-cs.UUCP> Reply-To: tobbe@joakim.liu.se (Torbjorn Kronander) Distribution: gnu Organization: Information Theory Lines: 219 In article <1041@aber-cs.UUCP> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes: >In article <8906281652.AA04026@AENEAS.MIT.EDU> SAITO@sdr.slb.com ("Naoki Saito Ext. 5471", GEO-002) writes: > > [ on multiple dimensional arrays ] > > And the definition of the fetching method is something like this: > > float& Matrix::operator(int i, int j) > { > return buf[i*cols+j]; // return without checking the index. > } > There is no need to use (,) type indexing for multiple arrays. By defining a dummy class, matrow in the exanple below, that is only used for address resolving yiu can have ordinary [][] type indeces. I enclose source for a generic matrix package as an example. (works as generic vector and compiles under CFRONT 1.2. I haven tried g++). /* mat.hxx */ /* This module is a generic matrix module. Tobbe K (and ragge N) 880630 If the DEBUG is defined (#define DEBUG) BEFORE! including this file you will get array bounds checking, if not a more efficient (and more dangerous) declaration is given. NOTE if you change anything in declare(), do this in both places (i.e.) declare is written twice below, one for each case of DEBUG. */ #ifndef MATHXX #define MATHXX 1 #include #ifndef MATCOMMON #define MATCOMMON 1 #include #endif #define MAT(COMPONENT) name2(COMPONENT,mat) #define MATROW(COMPONENT) name2(COMPONENT,matrow) #ifndef DEBUG #define matdeclare(COMPONENT) \ class MATROW(COMPONENT) { \ protected: \ COMPONENT* r; \ public: \ COMPONENT& operator[](int col){ return *(r+col);}; \ MATROW(COMPONENT)(COMPONENT* p) { r=p;}; \ }; \ \ \ \ class MAT(COMPONENT) { \ /* allocated size (at allocation = rows*cols) */ \ public: \ int physicalsize; \ COMPONENT* p; \ int rows; \ int cols; \ MAT(COMPONENT)(){ \ p=0; physicalsize=0; \ rows=0; cols=0; \ }; \ MAT(COMPONENT)(int r,int c){ \ p=new COMPONENT[r*c]; physicalsize=r*c; \ rows=r;cols=c;}; \ MAT(COMPONENT)(MAT(COMPONENT)&); \ ~MAT(COMPONENT)() {delete p;}; \ MATROW(COMPONENT)& operator[](int row){ \ return( MATROW(COMPONENT)(p+row*cols) ); \ }; \ virtual MAT(COMPONENT)& operator=(MAT(COMPONENT)&); \ virtual MAT(COMPONENT)& operator=(COMPONENT); \ \ void transpose(); \ }; #else // This means array bounds checking is on, somewhat slower.... // but SAFER !! #define matdeclare(COMPONENT) \ class MATROW(COMPONENT) { \ protected: \ COMPONENT* r; \ int length; \ public: \ COMPONENT& operator[](int col) { \ if (col >= length){ \ cerr << "Error, subsrcipt out of range in MAT, (column)\n"; \ exit(1); \ }; \ return *(r+col); \ }; \ \ MATROW(COMPONENT)(COMPONENT* p, int cols) {length=cols; r=p;}; \ }; \ \ \ \ class MAT(COMPONENT) { \ /* allocated size (at allocation = rows*cols) */ \ public: \ int physicalsize; \ COMPONENT* p; \ int rows; \ int cols; \ MAT(COMPONENT)(){ \ p=0; physicalsize=0; \ rows=0; cols=0; \ }; \ MAT(COMPONENT)(int r,int c){ \ p=new COMPONENT[r*c]; physicalsize=r*c; \ if ((int)p==0) { \ cerr << "Error1, unsuccessful allocation in mat.hxx\n"; \ exit(1); \ }; \ ;rows=r;cols=c;}; \ MAT(COMPONENT)(MAT(COMPONENT)&); \ ~MAT(COMPONENT)() {delete p;}; \ MATROW(COMPONENT)& operator[](int row){ \ if (row >= rows) { \ cerr << "Error, subsrcipt out of range in MAT, (row)\n"; \ exit(1); \ }; \ return( MATROW(COMPONENT)(p+row*cols,cols) ); \ }; \ virtual MAT(COMPONENT)& operator=(MAT(COMPONENT)&); \ virtual MAT(COMPONENT)& operator=(COMPONENT); \ \ void transpose(); \ }; #endif #define matimplement(COMPONENT) \ MAT(COMPONENT)::MAT(COMPONENT)(MAT(COMPONENT)& in){ \ p=new COMPONENT[in.rows*in.cols]; \ if ((int)p==0) { \ cerr << "Error2,unsuccessful allocation in mat.hxx\n"; \ exit(1); \ }; \ memcpy(p,in.p,sizeof(COMPONENT)*in.rows*in.cols); \ rows=in.rows; \ cols=in.cols; \ physicalsize=in.rows*in.cols; \ }; \ \ MAT(COMPONENT)& MAT(COMPONENT)::operator=(MAT(COMPONENT)& in){ \ if ((rows != in.rows) || (cols != in.cols)){ \ cerr << "Size must be equal in a MAT(COMPONENT) op= \n"; \ exit(1); \ }; \ memcpy(p,in.p,sizeof(COMPONENT)*in.rows*in.cols); \ return *this; \ } /*op=*/ \ \ MAT(COMPONENT)& MAT(COMPONENT)::operator=(COMPONENT x){ \ register int i = rows*cols; \ register COMPONENT* pu = p; \ \ while (i--){ \ *pu++ = x; \ }; \ return *this; \ } /*op=*/ \ \ \ void MAT(COMPONENT)::transpose() { \ register int ir,ic; \ MAT(COMPONENT) ut(cols,rows); \ for (ir=0; ir < rows; ir++) \ for (ic=0; ic < cols; ic++) { \ *(ut.p+ir+ic*rows)= *(p+ic+cols*ir); \ }; \ memcpy(p,ut.p,sizeof(COMPONENT)*rows*cols); \ int tmp=rows; \ rows=cols; \ cols=tmp; \ }; /* MAT(COMPONENT)::transpose() */ \ \ \ \ #endif Good luck. -- ----------------------------------------------------------------------- Torbj|rn Kronander Tobbe%joakim@rainier.se Dept. of EE T-kronander@linnea.liu.se