DSQSS
1.1
|
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