DSQSS  1.1
array.h
説明を見る。
00001 //
00002 // Array
00003 //
00004 // 今後の改良点:
00005 //   A[i][j][k]...[z] 
00006 // のような参照の仕方を許すこと.
00007 // そのためには,A[i] を自分自身より次元が1小さい
00008 // Array への参照を返す関数として定義する.
00009 // コンストラクタは再帰的に呼び出す.
00010 
00011 #ifndef ARRAY_H
00012 #define ARRAY_H
00013 
00014 //######################################################################
00015 
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <stdarg.h>
00019 #include <string>
00020 #include <iostream> 
00021 
00022 using namespace std;
00023 
00024 namespace ARRAY { int EOL = -1; }
00025 
00026 //######################################################################
00027 
00028 class IndexSystem {
00029 
00030  private:
00031 
00032   bool INI;
00033   string LBL; // label
00034   int  D;
00035   int* L;
00036   int  N;
00037 
00038  public:
00039 
00040   void init( const int d, const int* l, const string& LBL0 = ""  );
00041 
00042   IndexSystem() { INI = false; };
00043 
00044   IndexSystem( const int d, const int* l, const string& LBL0 = "" ) { 
00045     INI = false; init( d, l, LBL0); 
00046   };
00047 
00048   IndexSystem operator=(IndexSystem& I) {
00049     printf("IndexSystem::=()> Error.\n");
00050     printf("  ... The copy operation is prohibited.\n");
00051     exit(0);
00052   };
00053 
00054   IndexSystem(IndexSystem& I) {
00055     printf("IndexSystem::IndexSystem> Error.\n");
00056     printf("  ... The copy operation is prohibited.\n");
00057     exit(0);
00058   };
00059 
00060   ~IndexSystem() { 
00061     if ( initialized() ) delete [] L;
00062   };
00063 
00064   bool initialized() const { return INI; };
00065   int coord( const int ist, const int d );
00066   void coord( const int ist, int* x );
00067   int dimension() { 
00068     if ( !initialized() ) {
00069       printf("IndexSystem::dimension> Error. Not yet initialized.\n");
00070       exit(0);
00071     }
00072     return D; 
00073   };
00074   int size() { 
00075     if ( !initialized() ) {
00076       printf("IndexSystem::size()> Error. Not yet initialized.\n");
00077       exit(0);
00078     }
00079     return N; 
00080   };
00081   int size(int i) { 
00082     if ( !initialized() ) {
00083       printf("IndexSystem::size(int)> Error. Not yet initialized.\n");
00084       exit(0);
00085     }
00086     return L[i]; 
00087   };
00088   int operator() ( const int* x );
00089   int operator() ( const int M, va_list& ap );
00090   int operator() ( const int M , ... );
00091 
00092   void dump() const {
00093     if ( !initialized() ) {
00094       printf(" Not yet initialized.\n");
00095       return;
00096     }
00097     printf(" Label = %s\n", LBL.c_str());
00098     printf(" Dimension = %d\n", D);
00099     printf(" Size = ( ");
00100     for (int i=0; i<D; i++) {
00101       printf(" %d", L[i]);
00102     }
00103     printf(") = %d\n",N);
00104   };
00105 
00106 };
00107 
00108 //======================================================================
00109 
00110 void IndexSystem::init( const int d, const int* l, const string& LBL0 ) {
00111   if ( initialized() ) delete [] L;
00112   if ( d == 0 ) {
00113     printf("IndexSystem::init> Error. d = 0.\n");
00114     exit(0);
00115   }
00116   INI = true;
00117   LBL = LBL0; 
00118   D = d;
00119   L = new int [d];
00120   N = 1;
00121   for (int i=0; i<d; i++) {
00122     N *= l[i];
00123     L[i] = l[i];
00124   }
00125   if ( N == 0 ) {
00126     printf("IndexSystem::init> Error. N = 0.\n");
00127     for (int i=0; i<d; i++) printf("  L[%d] = %d\n", i, L[i]);
00128     exit(0);
00129   };
00130 }
00131 
00132 //======================================================================
00133 
00134 int IndexSystem::coord( const int ist, const int d) {
00135   if ( !initialized() ) {
00136     printf("IndexSystem::coord> Error. Not yet initialized.\n");
00137     exit(0);
00138   }
00139 #ifdef DEB
00140   if ( ist < 0 || ist >= N ) {
00141     printf("IndexSystem::coord> Error. (%s)\n",LBL.c_str());
00142     printf("   The first argument %d is out of bounds.\n", ist);
00143     exit(0);
00144   }
00145   if ( d < 0 || d >= D ) {
00146     printf("IndexSystem::coord> Error. (%s)\n",LBL.c_str());
00147     printf("   The second argument %d is out of bounds.\n", d);
00148     exit(0);
00149   }
00150 #endif
00151   int K=1;
00152   for (int j=d+1; j<D; j++) { K *= L[j]; }
00153   int ans = ist / K;
00154   ans %= L[d];
00155   return ans;
00156 }
00157 
00158 //======================================================================
00159 
00160 void IndexSystem::coord( const int ist, int* x ) {
00161   if ( !initialized() ) {
00162     printf("IndexSystem::coord> Error. Not yet initialized.\n");
00163     exit(0);
00164   }
00165 #ifdef DEB
00166   if ( ist < 0 || ist >= N ) {
00167     printf("IndexSystem::coord> Error. (%s)\n",LBL.c_str());
00168     printf("   The first argument %d is out of bounds.\n", ist);
00169     exit(0);
00170   }
00171 #endif
00172   int I = ist;
00173   for (int j=D-1; j>=0; j--) {
00174     x[j] = I % L[j];
00175     I /= L[j];
00176   }
00177 }
00178 
00179 //======================================================================
00180 
00181 int IndexSystem::operator() ( const int* x ) {
00182   if ( !initialized() ) {
00183     printf("IndexSystem::operator()(const int*)> Error. Not yet initialized.\n");
00184     exit(0);
00185   }
00186   int ans=0;
00187 
00188   for (int i=0; i<D; i++) {
00189 #ifdef DEB
00190     if ( x[i] < 0 || x[i] >= L[i] ) { 
00191       printf("IndexSystem::id> ERROR. (%s)\n",LBL.c_str());
00192       printf("  The %d th argument (= %d) exceeds the bound (= %d)\n", 
00193              i+1, x[i], L[i]-1
00194              ); 
00195       exit(0); 
00196     };
00197 #endif
00198     ans *= L[i];
00199     ans += x[i];
00200   }
00201   return ans;
00202 }
00203 
00204 //======================================================================
00205 
00206 int IndexSystem::operator() ( const int M, va_list& ap ) {
00207   if ( !initialized() ) {
00208     printf("IndexSystem::operator()> Error. Not yet initialized.\n");
00209     exit(0);
00210   }
00211 //  int x[D];
00212   int* x = new int[D]; //edit sakakura
00213   x[0] = M;
00214   for (int i=1; i<D; i++) x[i] = va_arg(ap,int);
00215   return (*this)(x);
00216 }
00217 
00218 //======================================================================
00219 
00220 int IndexSystem::operator() ( const int M, ... ) {
00221   if ( !initialized() ) {
00222     printf("IndexSystem::operator()> Error. Not yet initialized.\n");
00223     exit(0);
00224   }
00225   va_list ap;
00226   va_start( ap, M);
00227   int i = (*this)( M, ap);
00228   va_end(ap);
00229   return i;
00230 }
00231 
00232 //######################################################################
00233 
00234 template<class C> class Array {
00235 
00236  private:
00237 
00238   string LBL; // label
00239   int D;
00240   C* val;
00241   IndexSystem ID;
00242   void init(va_list& ap);
00243 
00244  public:
00245 
00246   bool isDefined();
00247   void reset();
00248   void init() { reset(); };
00249   void init(const string& s, int d, ...);
00250   void init(int d, ...);
00251   Array() { LBL = ""; val = 0; };
00252   Array(const string& LBL0) { LBL = LBL0; val = 0; };
00253   //Array(int d, ...);
00254   ~Array();
00255   void set_all(C v);
00256   // == edit sakakura == 
00257   void set_value(double* v);
00258   // == edit sakakura == 
00259   void setLabel(const char* label) { LBL = label; };
00260   int index(int i, int d);
00261   C& operator() (const int M, ...);
00262   C& operator() (int* x);
00263   C& operator[] (const int i);
00264   int size();
00265   int dimension();
00266   IndexSystem& index_system();
00267   void dump(char* fmt);
00268 
00269 };
00270 
00271 //======================================================================
00272 
00273 template<class C>
00274 bool Array<C>::isDefined() {
00275   if ( val != 0 ) return true;
00276   return false;
00277 }
00278 
00279 //======================================================================
00280 
00281 template<class C>
00282 IndexSystem& Array<C>::index_system() {
00283   return ID;
00284 }
00285 
00286 //======================================================================
00287 
00288 template<class C>
00289 void Array<C>::init(va_list& ap) {
00290 
00291   reset();
00292   int* L = new int [D];
00293   int N = 1;
00294   int l;
00295   int i = 0;
00296   for (i=0; i<D; i++) {
00297     l = va_arg(ap,int);
00298 
00299     if ( l == ARRAY::EOL ) break;
00300     L[i] = l;
00301     N *= l;
00302   }
00303   if ( N == 0 ) {
00304     printf("Array::init> Error.\n");
00305     printf("   ... tried to create an array with size 0.\n");
00306     exit(0);
00307   }
00308   if ( l == ARRAY::EOL ) {
00309     for (int j=i; j<D; j++) {
00310       L[j] = L[i-1];
00311       N *= L[j];
00312     }
00313   }
00314   val = new C[N];
00315   ID.init(D, L, LBL);
00316   delete [] L;
00317 }
00318 
00319 //======================================================================
00320 
00321 template<class C>
00322 void Array<C>::init(int d, ...) {
00323   //  printf("Array<C>::init (1)> d= %d\n",d);
00324   D = d;
00325   va_list ap;
00326   va_start( ap , d );
00327   init( ap );
00328   va_end( ap );
00329 }
00330 
00331 //======================================================================
00332 
00333 template<class C>
00334 void Array<C>::init(const string& s, int d, ...) {
00335   LBL = s;
00336   D = d;
00337   va_list ap;
00338   va_start( ap , d );
00339   init( ap );
00340   va_end( ap );
00341 }
00342 
00343 //======================================================================
00344 /*
00345   template<class C>
00346   Array<C>::Array(int d, ...) {
00347   LBL = "";
00348   D = d;
00349   va_list ap;
00350   va_start( ap , d );
00351   init( ap );
00352   va_end( ap );
00353   };
00354 */
00355 //======================================================================
00356 
00357 template<class C>
00358 void Array<C>::reset() {
00359   if ( val != 0 ) { 
00360     delete [] val; 
00361     val = 0;
00362   }
00363 }
00364 
00365 //======================================================================
00366 
00367 template<class C>
00368 Array<C>::~Array() {
00369   //  printf("*** Destroying Array (%s)\n", LBL.c_str());
00370   reset();
00371 }
00372 
00373 //======================================================================
00374 
00375 template<class C>
00376 void Array<C>::set_all(C v) { 
00377   for (int i=0; i<size(); i++) { val[i] = v; } 
00378 }
00379 
00380 // == edit sakakura == //
00381 //======================================================================
00382 
00383 template<class C>
00384 void Array<C>::set_value(double* v) { 
00385   for (int i=0; i<size(); i++) { val[i] = v[i]; } 
00386 }
00387 
00388 //======================================================================
00389 // == edit sakakura == //
00390 
00391 //======================================================================
00392 
00393 template<class C>
00394 int Array<C>::index(int i, int d) { return ID.coord(i,d); }
00395 
00396 //======================================================================
00397 
00398 template<class C>
00399 C& Array<C>::operator() (const int M, ...) {
00400   va_list ap;
00401   va_start( ap, M);
00402   int i = ID( M, ap);
00403   va_end(ap);
00404   return val[i];
00405 }
00406 
00407 //======================================================================
00408 
00409 template<class C>
00410 C& Array<C>::operator[] (const int i) {
00411 #ifdef DEB
00412   if ( i < 0 || i >= size() ) {
00413     printf("Array::operator[]> Error in array \"%s\".\n", LBL.c_str());
00414     printf("  The index (=%d) is out of the bounds [0,%d).\n",
00415            i, size());
00416     exit(0);
00417   }
00418 #endif
00419   return val[i];
00420 }
00421 
00422 //======================================================================
00423 
00424 template<class C>
00425 C& Array<C>::operator() (int* x) {
00426   int id = ID(x);
00427 #ifdef DEB
00428   if ( id < 0 || id > size() ) {
00429     printf("Array::operator()> Error.\n");
00430     printf("  Out of bounds.\n");
00431     exit(0);
00432   }
00433 #endif
00434   return val[id];
00435 }
00436 
00437 //======================================================================
00438 
00439 template<class C>
00440 int Array<C>::size() { return ID.size(); }
00441 
00442 //======================================================================
00443 
00444 template<class C>
00445 int Array<C>::dimension() { return ID.dimension(); }
00446 
00447 //======================================================================
00448 
00449 template<class C>
00450 void Array<C>::dump(char* fmt) {
00451   for (int i=0; i<size(); i++) {
00452     printf("%s", LBL.c_str());
00453     for (int d=0; d<dimension(); d++) {
00454       printf("[%d]", ID.coord(i,d));
00455     }
00456     printf(" = ");
00457     printf(fmt, (*this)[i]);
00458     printf("\n");
00459   }
00460 }
00461 
00462 #endif
 全て クラス ネームスペース ファイル 関数 変数 型定義 列挙型の値 フレンド マクロ定義