Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
AbsArr.h
Go to the documentation of this file.
1#ifndef ABSARR_H
2#define ABSARR_H
3/*
4Simple arrays with variable length.
5DynLinArr - "Dynamic Linear Array" - it is what it is.
6The name is choosen to distinguish this template class from every known
7other libraries.
8The information is kept in one block of memory and accessible with
9indexes. The array is characterized by the only parameter - its physical
10size. If you need a logicl size different from physical, keep the
11logical size in a separated place.
12Increasing of the array size leads to allocation of
13another block of memory and copying all elements to it by
14operator= (which can be correctly defined in the class definitions).
15This is difference with STL, in which vector have logical size
16which can be smaller than the volume of allocated memory.
17Currently the array boundaries are checked at each access, this is
18also difference with STL.
19These checks can be switched out by undefining macro ALR_CHECK_BOUND.
20The copying of array leads to copying all elements, destruction - to
21destruction of elements.
22The array DynLinArr can keep other array DynLinArr as elements
23and constitute multy-dimensional array of not "parallelogram" shape,
24that is for each first index, the dimension corresponding to
25the second index can be different from that of the other first indexes.
26This is very powerful feature, but it is not always desirable.
27If you need box-like array or "parallelogram" shape, use DynArr -
28"Dynamic Array".
29
30In DynArr the number of dimensions is arbitrary, but size of this
31array along each dimension is fixed and independent on
32the indexes of other dimensions. So this is rectangular array.
33The access is performed by indexes,
34but not through operators []. Since it is not trivial to provide
35such access for this array, I preferred the simplest solutions
36and arranged this access through little functions "ac":
37 T& DynArr::ac(long i) // for 1-dimensional array
38 T& DynArr::ac(long i1, long i2) // for 2-dimensional array
39 T& DynArr::ac(const DynLinArr<long>& ind)
40 // for arbitrary number of dimensions
41 // but the number of them in array should be equal to size of ind.
42 // ind is array of indexes. Its first element if the first index,
43 // second is second, etc.
44class DynArr is constructed with the help of DynLinArr.
45DynArr can keep as elements another DynArr's or DynLinArr's.
46DynLinArr can also keep DynArr as elements.
47
48There are many various auxiliary utilites assosiated with these arrays.
49Some of them look little bit antiquated, since they was created in
50stone age and were not revised after innovation of electricity.:)
51This happened because the author needed to port his programs on
52very various computers, not all of them had very advanced C++-related
53software. Today the situation with C++ is being changed rapidly
54and some of these pearls may be arranged by more modern way.
55But the main components of this file are actual and very convenient.
56
57Copyright (c) 1999-2005 I. B. Smirnov
58
59The file can be used, copied, modified, and distributed
60according to the terms of GNU Lesser General Public License version 2.1
61as published by the Free Software Foundation,
62and provided that the above copyright notice, this permission notice,
63and notices about any modifications of the original text
64appear in all copies and in supporting documentation.
65The file is provided "as is" without express or implied warranty.
66*/
67#include <iostream>
68#include <iomanip>
69#include <sstream>
72#include "wcpplib/util/String.h"
74
75// Here there is a good place to switch on the bound check in all programs
76#ifndef ALR_CHECK_BOUND
77#define ALR_CHECK_BOUND
78#endif
79#ifndef ALR_CHECK_EACH_BOUND
80#define ALR_CHECK_EACH_BOUND
81#endif
82
83//#define DEBUG_DYNLINARR // make some print
84//#define DEBUG_DYNARR // make some print and in addition
85// functions from DynArr make some formally unnecessary checks, which are
86// however useful for debug.
87
88namespace Heed {
89extern long max_qel_DynLinArr; // increase it if need
90// Helps to detect access to not inited DynLinArr,
91// what may happen at initializetion of class members
92// and use of not inited member for initialization of the other.
93
94template <class T>
95class DynArr;
96
98class ArgInterp_SingleAdr {}; // for put_qel()
100
101template <class T>
102class DynLinArr : public RegPassivePtr {
103 public:
104 // Constructors
105 DynLinArr(void) : qel(0), el(NULL) { ; }
106 explicit DynLinArr(long fqel) : qel(fqel), el(NULL) {
107 if (qel > max_qel_DynLinArr) {
108 mcerr << "ERROR in DynLinArr(long fqel):\n";
109 mcerr << "qel > max_qel_DynLinArr:\n";
111 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
112 << '\n';
113 spexit(mcerr);
114 }
115 if (qel < 0) {
116 mcerr << "ERROR in DynLinArr(long fqel):\n";
117 mcerr << "qel < 0:\n";
118 Iprintn(mcout, qel);
119 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
120 << '\n';
121 spexit(mcerr);
122 }
123 el = (fqel > 0) ? (new T[fqel]) : (T*)NULL;
124 }
125
126 DynLinArr(long fqel, const T& val) : qel(fqel), el(NULL) {
127 if (qel > max_qel_DynLinArr) {
128 mcerr << "ERROR in DynLinArr(long fqel, const T& val):\n";
129 mcerr << "qel > max_qel_DynLinArr:\n";
131 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
132 << '\n';
133 spexit(mcerr);
134 }
135 if (qel < 0) {
136 mcerr << "ERROR in DynLinArr(long fqel, const T& val):\n";
137 mcerr << "qel < 0:\n";
138 Iprintn(mcout, qel);
139 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
140 << '\n';
141 spexit(mcerr);
142 }
143 el = (fqel > 0) ? (new T[fqel]) : (T*)NULL;
144 assignAll(val);
145 }
146 DynLinArr(long fqel, const T* ar, ArgInterp_Arr /*t*/) : qel(fqel), el(NULL) {
147 if (qel > max_qel_DynLinArr) {
148 mcerr << "ERROR in DynLinArr(long fqel, const T* ar, ArgInterp_Arr):\n";
149 mcerr << "qel > max_qel_DynLinArr:\n";
151 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
152 << '\n';
153 spexit(mcerr);
154 }
155 if (qel < 0) {
156 mcerr << "ERROR in DynLinArr(long fqel, const T* ar, ArgInterp_Arr):\n";
157 mcerr << "qel < 0:\n";
158 Iprintn(mcout, qel);
159 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
160 << '\n';
161 spexit(mcerr);
162 }
163 el = (fqel > 0) ? (new T[fqel]) : (T*)NULL;
164 for (long n = 0; n < qel; n++) el[n] = ar[n];
165 }
166 // const T* ar is array here (of course).
167 // ArgInterp_Arr serves to distinguish this
168 // from previous constructor when second argument
169 // does not coincide with T but can be converted to it.
170 // Typical example is when T is double and second argument is 0.
171 // It is assumed that 0 should be converted to 0.0 and previous
172 // constructor should be called. But in practice (Red Hat Linux 6.0)
173 // the compiler says
174 // call of overloaded `DynLinArr(int &, int)' is ambiguous.
175 // I don't know whether this is error of particular compiler or
176 // general problem. But the third dummy argument is anyway convenient
177 // to distringuish these cases.
178
180 template <class D>
182
183 void pass(long fqel, T* fel) {
184 // Do not call directly! Is to be used only
185 // from assignment operator above
186 clear();
187 qel = fqel;
188 el = fel;
189 }
190
191 inline DynLinArr(const DynLinArr<T>& f);
192 DynLinArr(const DynLinArr<T>& f, Pilfer) : qel(f.qel), el(f.el) {
193#ifdef DEBUG_DYNLINARR
194 mcout << "DynLinArr( DynLinArr<T>& f, Pilfer) is working\n";
195#endif
196 f.qel = 0;
197 f.el = 0;
198 }
199 DynLinArr(const DynArr<T>& f); // works only if f has one dimension
200 // otherwise calls spexit.
201
202 DynLinArr(const DynArr<T>& f, int n_of_dim,
203 // 0 - first dim) 1 - second dim)
204 long roc_number);
205 // takes only mentioned raw or column.
206
207 DynLinArr& assignAll(const T& f) {
208 check();
209 for (long n = 0; n < qel; n++) el[n] = f;
210 return *this;
211 }
212 template <class X>
214 // assumes that element is object
215 // which also accepts assignAll, which is called for it.
216 check();
217 for (long n = 0; n < qel; n++) el[n].assignAll(f);
218 return *this;
219 }
220 // DynLinArr& operator=(const T& f) { int n; for( n=0; n<qel; n++) el[n]=f; }
221 inline T& operator[](long n) {
222#ifdef ALR_CHECK_BOUND
223 if (n >= 0 && n < qel) return el[n];
224 mcerr << "ERROR in const T& DynLinArr::operator[](long n) const: "
225 << "n is out of bounds, n=" << n << " qel=" << qel << '\n';
226 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
227 << '\n';
228 spexit(mcerr);
229 return el[0];
230#else
231 return el[n];
232#endif
233 }
234 inline const T& operator[](long n) const {
235#ifdef ALR_CHECK_BOUND
236 if (n >= 0 && n < qel) return el[n];
237 mcerr << "ERROR in const T& DynLinArr::operator[](long n) const: "
238 << "n is out of bounds, n=" << n << " qel=" << qel << '\n';
239 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
240 << '\n';
241 spexit(mcerr);
242 return el[0];
243#else
244 return el[n];
245#endif
246 }
247 inline T& acu(long n) {
248 // unchecked access
249 return el[n];
250 }
251 inline const T& acu(long n) const {
252 // unchecked access
253 return el[n];
254 }
255 inline T& last_el(void) {
256#ifdef ALR_CHECK_BOUND
257 if (qel > 0) return el[qel - 1];
258 mcerr << "ERROR in const T& DynLinArr::last_el(void) const: qel <=0:"
259 << " qel" << qel << '\n';
260 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
261 << '\n';
262 spexit(mcerr);
263 return el[0];
264#else
265 return el[qel];
266#endif
267 }
268
269 inline const T& last_el(void) const {
270#ifdef ALR_CHECK_BOUND
271 if (qel > 0) return el[qel - 1];
272 mcerr << "ERROR in const T& DynLinArr::last_el(void) const: qel <=0:"
273 << " qel" << qel << '\n';
274 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
275 << '\n';
276 spexit(mcerr);
277 return el[0];
278#else
279 return el[qel];
280#endif
281 }
282
283 long get_qel(void) const { return qel; }
284 void put_qel(long fqel);
285 void put_qel(long fqel, const T* val, ArgInterp_SingleAdr t);
286 // creates array with size fqel
287 // If old array existed, then
288 // If it was less than fqel, it all is copied to new array
289 // and the other elements either assigned *val or
290 // remains not inited.
291 // else its fqel part is copyed to new array.
292 // ArgInterp_SingleAdr serves to distinguish this
293 // from next function when second argument
294 // does not coincide with T but can be converted to it
295 // (for example NULL to int and it is not clear which function
296 // should be called.
297 // Attention!, val is an element, this is assimetry with contructor,
298 // in which ar is an array.
299
300 void put_qel(long fqel, const T& val) {
301 put_qel(fqel, &val, ArgInterp_SingleAdr());
302 }
303 void increment(const T* val = NULL) {
304 check();
305 long q = qel + 1;
306 put_qel(q, *val);
307 }
308 void increment(const T& val) {
309 check();
310 long q = qel + 1;
311 put_qel(q, val);
312 }
313 void clear(void) { put_qel(0); } // Not only clears the content,
314 // but makes zero dimension.
315 void pilfer(const DynLinArr<T>& f) {
316#ifdef DEBUG_DYNLINARR
317 mcout << "DynLinArr::pilfer is called\n";
318#endif
319 if (this != &f) {
320 if (qel != 0) {
321 if (f.qel != 0) {
322 mcerr << "ERROR in DynLinArr::pilfer(...):\n";
323 mcerr << "Both the destination and source arrays are not empty\n";
324 // For explanations why it is dengerous, see similar function
325 // of ActivePtr.
326 spexit(mcerr);
327 } else {
328 delete[] el;
329 qel = 0;
330 }
331 }
332 el = f.el;
333 qel = f.qel;
334 f.el = NULL;
335 f.qel = 0;
336 }
337 }
338
339 void check(void) const;
340
341 /*
342 void print(std::ostream& file, long qpr) const
343 {
344 Ifile<<"DynLinArr<T>: qel="<<get_qel()<<" qpr="<<qpr<<'\n';
345 long n;
346 indn.n+=2;
347 for( n=0; n<qpr; n++)
348 {
349 Ifile<<"n="<<n<<" el[n]="<<this->DynLinArr<T>::operator[](n)<<'\n';
350 }
351 indn.n-=2;
352 }
353 */
354 DynArr<T> top(void); // transpose the vector, rotate it
355 // from vertical colunm to horisontal line for the purpose
356 // of linear algebra calculations.
357
358 // friend void DLA_sort<T>(DynLinArr<T>& f);
359 // Apply any function of one argument (of type T) to each element.
360 template <class P>
361 friend void apply1(DynLinArr<P>& ar, void (*fun)(P& f));
362 // template<class P> friend void apply1m(DynLinArr<P>& ar,
363 // void (*P::fun)(void));
364 // Apply any function of two arguments
365 // (first of which is of type T and the second is of type of address
366 // of another function (possibly apply1) to each element.
367 template <class P, class X>
368 friend void apply2(DynLinArr<P>& ar, void (*fun1)(P& f, void (*fun21)(X& f)),
369 void (*fun2)(X& f));
370
371 // template<class P, class X> friend void apply2m(DynLinArr<P>& ar,
372 // void (*fun1)(P& f, void (*fun21)(X& f) ),
373 // void (*X::fun2)(void) );
374 // void apply(void (*fun)(T& f))
375 //{ long n; for(n=0; n<qel; n++) (*fun)(el[n]); }
376
377 // Attention: the both sorts below at large N are much less efficient
378 // then sort for standard vectors.
379 // At N of the order of 50000 thay take several seconds,
380 // whereas sort for vectors takes several tenths of second.
381
382 void sort(long q_to_sort = 0); // sorts first q_to_sort to increasing order.
383 // If q_to_sort = 0, it sorts all get_qel() elements.
384
385 void sort(DynLinArr<long>& sort_ind, long q_to_sort = 0) const;
386 // to increasing order
387 // Does not change array, but creates index array which gives access
388 // in sorted order. For example:
389 // DynLinArr< long > sort_ind;
390 // collection.sort(sort_ind);
391 // for(n=0; n<q; n++)
392 // {
393 // collection_ordered[n] = collection[sort_ind[n]];
394 // }
395 // Thus content of each n-th element of sort_ind gives
396 // position of n-th (by size) element of array.
397
398 // finds and sorts minimal q_to_sort elements from all.
400 long q_to_sort = 0) const;
402 long q_to_sort = 0) const;
403
404 virtual DynLinArr* copy() const;
405
406 virtual ~DynLinArr() {
407 check();
408 if (el) delete[] el;
409 }
410
411 private:
412 mutable long qel; // number of elements, mutable only for pilfer
413 mutable T* el; // array of qel elements, mutable only for pilfer
414 //(regarding mutable and pilfer see ActivePtr for more comments).
415};
416template <class T>
418 return new DynLinArr<T>(*this);
419}
420
421template <class T>
422void apply1(DynLinArr<T>& ar, void (*fun)(T& f)) {
423 for (long n = 0; n < ar.qel; n++) (*fun)(ar.el[n]);
424}
425
426template <class T, class X>
427void apply2(DynLinArr<T>& ar, void (*fun1)(T& f, void (*fun21)(X& f)),
428 void (*fun2)(X& f)) {
429 for (long n = 0; n < ar.qel; n++) (*fun1)(ar.el[n], fun2);
430}
431
432template <class T>
433void DynLinArr<T>::check(void) const {
434 if (qel < 0) {
435 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
436 mcerr << "qel < 0, qel=" << qel << '\n';
437 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
438 << '\n';
439 spexit(mcerr);
440 }
441 if (qel == 0 && el != NULL) {
442 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
443 mcerr << "qel == 0 && el != NULL: el=" << el << '\n';
444 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
445 << '\n';
446 spexit(mcerr);
447 }
448 if (qel > 0) {
449 if (el == NULL) {
450 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
451 mcerr << "qel > 0 && el == NULL: qel=" << qel << '\n';
452 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
453 << '\n';
454 spexit(mcerr);
455 }
456 if (qel > max_qel_DynLinArr) {
457 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
458 mcerr << "qel > max_qel_DynLinArr: \n";
460 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
461 << '\n';
462 spexit(mcerr);
463 }
464 }
465}
466
467template <class T>
469#ifdef DEBUG_DYNLINARR
470 mcout << "DynLinArr<T>& DynLinArr<T>::operator=(const DynLinArr<T>& f) is "
471 "working\n";
472#endif
473 if (this != &f) {
474 // mcout<<"DynLinArr<T>& operator=(const DynLinArr<T>& f): long(el)="
475 //<<long(el)<<'\n';
476 check();
477 f.check();
478 // First of all we allocate memory and copy to there
479 // all elements from f, because f can be part of this array,
480 // for example, one of its elements.
481 long q = f.get_qel();
482 T* temp_el = (T*)NULL;
483 if (q > 0) {
484 temp_el = new T[q];
485 for (long n = 0; n < q; n++) temp_el[n] = f.el[n];
486 }
487 pass(q, temp_el);
488 }
489 return *this;
490}
491
492template <class T>
493template <class D>
495#ifdef DEBUG_DYNLINARR
496 mcout << "DynLinArr<T>& DynLinArr<T>::operator=(const DynLinArr<D>& f) is "
497 "working\n";
498#endif
499 if (this == &f) return *this;
500 check();
501 f.check();
502 // First of all we allocate memory and copy to there
503 // all elements from f, because f can be part of this array,
504 // for example, one of its elements.
505 long q = f.get_qel();
506 T* temp_el = (T*)NULL;
507 if (q > 0) {
508 temp_el = new T[q];
509 for (long n = 0; n < q; n++) temp_el[n] = f[n];
510 }
511 pass(q, temp_el);
512 return *this;
513}
514
515template <class T>
517 : RegPassivePtr(),
518 qel(0),
519 el(NULL) {
520#ifdef DEBUG_DYNLINARR
521 mcout << "DynLinArr(const DynLinArr<T>& f) is working\n";
522#endif
523 *this = f;
524}
525
526template <class T>
527void DynLinArr<T>::put_qel(long fqel) {
528 //
529 // creates array with size fqel
530 // If old array existed, then
531 // If it was less than fqel, it all is copied to new array
532 // and the other elements either assigned *val or
533 // remains not inited.
534 // else its fqel part is copyed to new array.
535 // mcout<<"put_qel: *this="<<(*this);
536 if (fqel < 0) {
537 mcerr << "ERROR in template<class T> void DynLinArr<T>::put_qel(long "
538 "fqel):\n";
539 mcerr << "fqel < 0, fqel=" << fqel << '\n';
540 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
541 << '\n';
542 spexit(mcerr);
543 }
544 check();
545 if (el == NULL) {
546 qel = fqel;
547 if (qel > 0) el = new T[fqel];
548 } else {
549 if (qel != fqel) {
550 if (fqel <= 0) {
551 qel = 0;
552 delete[] el;
553 el = NULL;
554 } else {
555 T* elh;
556 elh = new T[fqel];
557 for (long n = 0; n < fqel; ++n) {
558 if (n < qel) elh[n] = el[n];
559 }
560 delete[] el;
561 el = elh;
562 qel = fqel;
563 }
564 }
565 }
566}
567
568template <class T>
569void DynLinArr<T>::put_qel(long fqel, const T* val, ArgInterp_SingleAdr t) {
570 // By default val == NULL
571 // creates array with size fqel
572 // If old array existed, then
573 // If it was less than fqel, it all is copied to new array
574 // and the other elements either assigned *val or
575 // remains not inited.
576 // else its fqel part is copyed to new array.
577 // mcout<<"put_qel: *this="<<(*this);
578 if (fqel < 0) {
579 mcerr << "ERROR in template<class T> void DynLinArr<T>::put_qel(long fqel, "
580 "const T* val, ArgInterp_SingleAdr):\n";
581 mcerr << "fqel < 0, fqel=" << fqel << '\n';
582 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
583 << '\n';
584 spexit(mcerr);
585 // Avoid compiler warning because of unused variable t (HS).
586 mcerr << sizeof(t) << "\n";
587 }
588 check();
589 if (el == NULL) {
590 qel = fqel;
591 if (qel > 0) el = new T[fqel];
592 if (val != NULL)
593 for (long n = 0; n < qel; ++n) el[n] = *val;
594 } else {
595 if (qel != fqel) {
596 if (fqel <= 0) {
597 qel = 0;
598 delete[] el;
599 el = NULL;
600 } else {
601 T* elh;
602 elh = new T[fqel];
603 for (long n = 0; n < fqel; ++n) {
604 if (n < qel)
605 elh[n] = el[n];
606 else if (val != NULL)
607 elh[n] = *val;
608 }
609 delete[] el;
610 el = elh;
611 qel = fqel;
612 }
613 }
614 }
615}
616
617// Simple sorting routine optimized for DynLiArr. )ptimized means
618// not doing checks at each indexing, but it is not the best for the large
619// number of N.
620// Note that it can be made better if at choosing n_possible_next
621// to arrange going backward. But this is much more complicated so currently
622// I am not going to do this.
623
624template <class T>
625void DynLinArr<T>::sort(long q_to_sort) {
626 mfunnamep("void DynLinArr<T>::sort(long q_to_sort = 0)");
627
628 check_econd12(q_to_sort, >, qel, mcerr);
629 if (q_to_sort <= 0) q_to_sort = qel;
630 if (q_to_sort <= 1) return;
631
632 long n_possible_next = 1;
633 long q_comp = 0;
634 long n, m;
635 for (n = 0; n < q_to_sort - 1; n++) {
636 // Iprint2n(mcout, n, n_possible_next);
637 // first it finds the minimum along the rest and replaces if it is less
638 // long nmin = n+1;
639 long nmin = n_possible_next;
640 T el_min = el[nmin];
641 int s_change_possible_next = 0;
642
643 // for(m=n+2; m<q_to_sort; m++)
644 for (m = n_possible_next + 1; m < q_to_sort; m++) {
645 q_comp++;
646 // if(el[nmin] > el[m])
647 if (el_min > el[m]) {
648 n_possible_next = nmin;
649 s_change_possible_next = 1;
650 nmin = m;
651 el_min = el[nmin];
652 }
653 }
654 // Iprint4n(mcout, n_possible_next, s_change_possible_next, nmin, el_min);
655 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
656 n_possible_next = n + 2;
657 }
658 // if(el[n] > el[nmin])
659 //{
660 // T t = el[nmin];
661 // el[nmin] = el[n];
662 // el[n] = t;
663 //}
664 // Iprintn(mcout, n_possible_next);
665 // Iprint2n(mcout, el[n], el_min);
666 if (el[n] > el_min) {
667 if (s_change_possible_next == 1) {
668 // if(n_possible_next < q_to_sort)
669 if (n_possible_next < q_to_sort && el[n] < el[n_possible_next]) {
670 n_possible_next = nmin;
671 }
672 }
673 // mcout<<"replacing el[n] and el_min\n";
674 T t = el_min;
675 el[nmin] = el[n];
676 el[n] = t;
677 }
678 // Iprintn(mcout, (*this));
679 }
680 // Iprintn(mcout, q_comp);
681}
682
683// New variant, should be faster, the old is below.
684
685template <class T>
686void DynLinArr<T>::sort(DynLinArr<long>& sort_ind, long q_to_sort) const {
687 mfunnamep(
688 "void DynLinArr<T>::sort(DynLinArr< long >& sort_ind, long "
689 "q_to_sort = 0) const");
690
691 check_econd12(q_to_sort, >, qel, mcerr);
692 if (q_to_sort <= 0) q_to_sort = qel;
693 // if(q_to_sort <= 1) return;
694
695 sort_ind.clear();
696 sort_ind.pilfer(DynLinArr<long>(q_to_sort));
697 long n, m;
698 for (n = 0; n < q_to_sort; n++) {
699 sort_ind.acu(n) = n;
700 }
701 if (q_to_sort <= 1) return;
702
703 long n_possible_next = 1;
704
705 for (n = 0; n < q_to_sort - 1; n++) {
706 // first it finds the minimum along the rest and replaces if it is less
707 long nmin = n_possible_next;
708 long ind_nmin = sort_ind.acu(nmin);
709 int s_change_possible_next = 0;
710
711 // for(m=n+2; m<q_to_sort; m++)
712 for (m = n_possible_next + 1; m < q_to_sort; m++) {
713 if (el[ind_nmin] > el[sort_ind.acu(m)])
714 // if(el[sort_ind.acu(nmin)] > el[sort_ind.acu(m)])
715 {
716 n_possible_next = nmin;
717 s_change_possible_next = 1;
718 nmin = m;
719 ind_nmin = sort_ind.acu(nmin);
720 }
721 }
722 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
723 n_possible_next = n + 2;
724 }
725 if (el[sort_ind.acu(n)] > el[ind_nmin])
726 // if(el[sort_ind.acu(n)] > el[sort_ind.acu(nmin)])
727 {
728 if (s_change_possible_next == 1) {
729 if (n_possible_next < q_to_sort &&
730 el[sort_ind.acu(n)] < el[sort_ind.acu(n_possible_next)]) {
731 n_possible_next = nmin;
732 }
733 }
734 // long t = sort_ind.acu(nmin);
735 sort_ind.acu(nmin) = sort_ind.acu(n);
736 sort_ind.acu(n) = ind_nmin;
737 }
738 }
739}
740
741template <class T>
743 long q_to_sort) const {
744 mfunnamep(
745 "void DynLinArr<T>::sort_select_increasing(DynLinArr< long >& "
746 "sort_ind, long q_to_sort = 0) const");
747
748 check_econd12(q_to_sort, >, qel, mcerr);
749 long s_last_noninc = 0;
750 if (q_to_sort <= 0) {
751 q_to_sort = qel;
752 s_last_noninc = 1;
753 } else if (q_to_sort == qel) {
754 s_last_noninc = 1;
755 }
756
757 // if(qel <= 1) return;
758 sort_ind.clear();
759 sort_ind.pilfer(DynLinArr<long>(qel));
760 long n, m;
761 for (n = 0; n < qel; n++) {
762 sort_ind[n] = n;
763 }
764 if (q_to_sort <= 1) return;
765
766 long n_possible_next = 1;
767
768 for (n = 0; n < q_to_sort - s_last_noninc; n++) {
769 // first it finds the minimum along the rest and replaces if it is less
770 long nmin = n_possible_next;
771 long ind_nmin = sort_ind[nmin];
772 int s_change_possible_next = 0;
773
774 // for(m=n+2; m<q_to_sort; m++)
775 for (m = n_possible_next + 1; m < qel; m++) {
776 if (el[ind_nmin] > el[sort_ind[m]])
777 // if(el[sort_ind.acu(nmin)] > el[sort_ind.acu(m)])
778 {
779 n_possible_next = nmin;
780 s_change_possible_next = 1;
781 nmin = m;
782 ind_nmin = sort_ind[nmin];
783 }
784 }
785 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
786 n_possible_next = n + 2;
787 }
788 if (el[sort_ind[n]] > el[ind_nmin])
789 // if(el[sort_ind.acu(n)] > el[sort_ind.acu(nmin)])
790 {
791 if (s_change_possible_next == 1) {
792 if (n_possible_next < q_to_sort &&
793 el[sort_ind[n]] < el[sort_ind[n_possible_next]]) {
794 n_possible_next = nmin;
795 }
796 }
797 // long t = sort_ind.acu(nmin);
798 sort_ind[nmin] = sort_ind[n];
799 sort_ind[n] = ind_nmin;
800 }
801 }
802 sort_ind.put_qel(qel);
803}
804
805template <class T>
807 long q_to_sort) const {
808 mfunnamep(
809 "void DynLinArr<T>::sort_select_decreasing(DynLinArr< long >& "
810 "sort_ind, long q_to_sort = 0) const");
811
812 check_econd12(q_to_sort, >, qel, mcerr);
813 long s_last_noninc = 0;
814 if (q_to_sort <= 0) {
815 q_to_sort = qel;
816 s_last_noninc = 1;
817 } else if (q_to_sort == qel) {
818 s_last_noninc = 1;
819 }
820 // Iprintn(mcout, q_to_sort);
821
822 // if(qel <= 1) return;
823 sort_ind.clear();
824 sort_ind.pilfer(DynLinArr<long>(qel));
825 long n, m;
826 for (n = 0; n < qel; n++) {
827 sort_ind[n] = n;
828 }
829 if (q_to_sort <= 1) return;
830
831 long n_possible_next = 1;
832
833 for (n = 0; n < q_to_sort - s_last_noninc; n++) {
834 // Iprintn(mcout, n);
835 // first it finds the minimum along the rest and replaces if it is less
836 long nmax = n_possible_next;
837 // Iprintn(mcout, nmax);
838 long ind_nmax = sort_ind[nmax];
839 int s_change_possible_next = 0;
840
841 // for(m=n+2; m<q_to_sort; m++)
842 for (m = n_possible_next + 1; m < qel; m++) {
843 // Iprint3n(mcout, ind_nmax, m, sort_ind[m]);
844 if (el[ind_nmax] < el[sort_ind[m]]) {
845 n_possible_next = nmax;
846 s_change_possible_next = 1;
847 nmax = m;
848 // Iprintn(mcout, nmax);
849 ind_nmax = sort_ind[nmax];
850 }
851 }
852 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
853 n_possible_next = n + 2;
854 }
855 // Iprint4n(mcout, n, sort_ind[n], ind_nmax, el[ind_nmax]);
856 if (el[sort_ind[n]] < el[ind_nmax]) {
857 if (s_change_possible_next == 1) {
858 if (n_possible_next < q_to_sort &&
859 el[sort_ind[n]] > el[sort_ind[n_possible_next]]) {
860 n_possible_next = nmax;
861 }
862 }
863 // long t = sort_ind.acu(nmin);
864 sort_ind[nmax] = sort_ind[n];
865 sort_ind[n] = ind_nmax;
866 }
867 }
868 sort_ind.put_qel(qel);
869}
870
871/*
872template<class T>
873void DynLinArr<T>::sort(DynLinArr< long >& sort_ind, long q_to_sort) const
874{
875 mfunnamep("void DynLinArr<T>::sort(DynLinArr< long >& sort_ind, long q_to_sort
876= 0) const");
877
878 check_econd12(q_to_sort , > , qel , mcerr);
879 if(q_to_sort <= 0) q_to_sort = qel;
880 if(q_to_sort <= 1) return;
881
882 //if(qel <= 1) return;
883 sort_ind.clear();
884 sort_ind.pilfer(DynLinArr< long >(q_to_sort));
885 long n,m;
886 for(n=0; n<q_to_sort; n++)
887 {
888 sort_ind.acu(n) = n;
889 }
890
891 for(n=0; n<q_to_sort-1; n++)
892 {
893 // first it finds the minimum along the rest and replaces if it is less
894 long nmin = n+1;
895 long ind_nmin = sort_ind.acu(nmin);
896 for(m=n+2; m<q_to_sort; m++)
897 {
898 if(el[ind_nmin] > el[sort_ind.acu(m)])
899 //if(el[sort_ind.acu(nmin)] > el[sort_ind.acu(m)])
900 {
901 nmin = m;
902 ind_nmin = sort_ind.acu(nmin);
903 }
904 }
905 if(el[sort_ind.acu(n)] > el[ind_nmin])
906 //if(el[sort_ind.acu(n)] > el[sort_ind.acu(nmin)])
907 {
908 //long t = sort_ind.acu(nmin);
909 sort_ind.acu(nmin) = sort_ind.acu(n);
910 sort_ind.acu(n) = ind_nmin;
911 }
912 }
913}
914*/
915
916/*
917template<T> void DLA_sort(DynLinArr<T>& f)
918{
919 mfunnamep("template<T> void DLA_sort(DynLinArr<T>& f)");
920
921 long q = f.get_qel();
922 if(q <= 1) return;
923 long n,m;
924 T* a = &(f[0]);
925 for(n=0; n<q-1; n++)
926 {
927 for(m=n+1; m<q; m++)
928 {
929 if(a[n] > a[m])
930 {
931 T t = a[m];
932 a[m] = a[n];
933 a[n] = t;
934 }
935 }
936 }
937}
938*/
939/*
940//Somewhy this doen not work prolerly if T is template class itself
941//AbsCont_ts.c:167: type unification failed for function template
942//`template <class T> long int append_TreeNode(TreeNode<...> &,
943//TreeNode<...> &, long int &, T * = 0, long int = 0)'
944*/
945/*
946This is not compiled in Solaris:
947Error: Function templates may not have default parameters.
948*/
949#ifndef BAN_DEFAULT_PAR_FUN_TEMPL
950template <class T>
951long append(const T& t, // value to assign
952 DynLinArr<T>& dla, // array to whose elements this value is to be
953 // assigned
954 long& qael, // input: index of element to which it will be assigned
955 // if qael == get_qel(), the qel will be increased
956 // to either new_qel or by 3 times.
957 // But if qael > get_qel(), it is considered as error.
958 // output: the next index
959 T* tempt = NULL, // data filled to extra elements
960 long new_qel = 0 // recommended new size
961 ) {
962 if (dla.get_qel() < qael) {
963 mcerr << "ERROR in long append(class DynLinArr& dla, ...): dla.get_qel() < "
964 "qael\n"
965 << "dla.get_qel()=" << dla.get_qel() << " qael=" << qael << '\n';
966 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
967 << '\n';
968 spexit(mcerr);
969 }
970 if (dla.get_qel() == qael) {
971 if (new_qel <= qael) new_qel = std::max(3 * qael, long(3));
972 dla.put_qel(new_qel, tempt, ArgInterp_SingleAdr());
973 }
974 dla[qael++] = t;
975 return qael;
976}
977
978#else
979
980#define append_to_DynLinArr(t, dla, qael, tempt, new_qel) \
981 { \
982 if (dla.get_qel() < qael) { \
983 mcerr << "append(class DynLinArr& dla, ...): dla.get_qel() < qael, " \
984 << "dla.get_qel()=" << dla.get_qel() << " qael=" << qael << '\n'; \
985 spexit(mcerr); \
986 } \
987 int nn = new_qel; \
988 if (dla.get_qel() == qael) { \
989 if (new_qel <= qael) nn = std::max(3 * qael, long(3)); \
990 dla.put_qel(nn, tempt); \
991 } \
992 dla[qael++] = t; \
993 }
994#define append_to_DynLinArr_short(t, dla, qael) \
995 { \
996 if (dla.get_qel() < qael) { \
997 mcerr << "append(class DynLinArr& dla, ...): dla.get_qel() < qael, " \
998 << "dla.get_qel()=" << dla.get_qel() << " qael=" << qael << '\n'; \
999 spexit(mcerr); \
1000 } \
1001 int nn = 0; \
1002 if (dla.get_qel() == qael) { \
1003 nn = std::max(3 * qael, long(3)); \
1004 dla.put_qel(nn, NULL); \
1005 } \
1006 dla[qael++] = t; \
1007 }
1008#endif
1009
1010template <class T>
1011std::ostream& operator<<(std::ostream& file, const DynLinArr<T>& f) {
1012 // mfunnamep("template<class T> std::ostream& operator<<(std::ostream& file,
1013 // const DynLinArr<T>& f)");
1014 // mcout<<"operator<<(std::ostream& file, const DynLinArr<T>& f) is
1015 // started\n";
1016 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << '\n';
1017 f.check();
1018 long n;
1019 indn.n += 2;
1020 for (n = 0; n < f.get_qel(); n++) {
1021 // Ifile<<"n="<<n<<" el[n]="<<noindent<<f[n]<<yesindent<<'\n';
1022 if (s_short_output == 0) {
1023 Ifile << "n=" << n << " el[n]=";
1024 }
1025 std::ostringstream ost;
1026 ost << indn << noindent << f[n] << yesindent;
1027 put_one_n(ost);
1028 file << ost.str();
1029 }
1030 // file<<yesindent;
1031 indn.n -= 2;
1032 return file;
1033}
1034
1035
1036
1037template <class T>
1038std::istream& operator>>(std::istream& file, DynLinArr<T>& f) {
1039 mfunnamep(
1040 "template<class T> istream& operator>>(istream& file, DynLinArr<T>& f)");
1041 // mcout<<"operator<<(std::ostream& file, const DynLinArr<T>& f) is
1042 // started\n";
1043 definp_endpar dep(&file, 0, 1, 0, s_short_output);
1044 long qel = 0;
1045 dep.s_short = 0;
1046 DEFINPAP(qel);
1047 dep.s_short = s_short_output;
1048 check_econd11(qel, < 0, mcerr);
1049 f.clear();
1050 f.put_qel(qel);
1051 long fn;
1052 for (fn = 0; fn < qel; fn++) {
1053 if (s_short_output == 0) {
1054 long n = 0;
1055 DEFINPAP(n);
1056 check_econd12(fn, !=, n, mcerr);
1057 }
1058 // set_position("el[n]=", *dep.istrm, dep.s_rewind, dep.s_req_sep);
1059 // file >> f[n];
1060 definp_any_par(f[fn], "el[n]=", dep);
1061 }
1062 return file;
1063}
1064
1065// Commented out unused function (hschindl)
1066/*
1067template<class T>
1068void output_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l, long q)
1069{
1070 //mfunnamep("template<class T> void output_DynLinArr(std::ostream& file, const
1071DynLinArr<T>& f, int l, long q)");
1072 Ifile<<"DynLinArr<T>: qel="<<f.get_qel()<<" q to print is "<<q<<'\n';
1073 f.check();
1074 if(q>f.get_qel())
1075 {
1076 mcerr<<"output_DynLinArr(...): q>f.get_qel(), q="<<q
1077 <<" f.get_qel()="<<f.get_qel()<<'\n';
1078 mcerr<<"Type of T is (in internal notations) "<<typeid(T).name()<<'\n';
1079 spexit(mcerr);
1080 }
1081 long n;
1082 indn.n+=2;
1083 for( n=0; n<q; n++)
1084 {
1085 //Ifile<<"n="<<n<<" el[n]="<<noindent<<f[n]<<yesindent<<'\n';
1086 Ifile<<"n="<<n<<" el[n]="<<noindent;
1087 std::ostringstream ost;
1088 ost<<f[n]<<yesindent;
1089 put_one_n(ost);
1090 file<<ost.str();
1091 }
1092 //file<<yesindent;
1093 indn.n-=2;
1094}
1095*/
1096
1097template <class T>
1098void print_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l) {
1099 // mfunnamep("template<class T> void print_DynLinArr(std::ostream& file, const
1100 // DynLinArr<T>& f, int l)");
1101 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << '\n';
1102 f.check();
1103 long n;
1104 indn.n += 2;
1105 for (n = 0; n < f.get_qel(); n++) {
1106 // Ifile<<"n="<<n<<" el[n]="<<noindent; f[n].print(file, l);
1107 // file<<yesindent;
1108 Ifile << "n=" << n << " el[n]=" << noindent;
1109 std::ostringstream ost;
1110 f[n].print(ost, l);
1111 ost << yesindent;
1112 put_one_n(ost);
1113 file << ost.str();
1114 }
1115 indn.n -= 2;
1116}
1117
1118template <class T>
1119void print_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l, long q) {
1120 // mfunnamep("template<class T> void print_DynLinArr(std::ostream& file, const
1121 // DynLinArr<T>& f, int l, long q)");
1122 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << " q to print is " << q
1123 << '\n';
1124 f.check();
1125 if (q > f.get_qel()) {
1126 mcerr << "print_DynLinArr(...): q>f.get_qel(), q=" << q
1127 << " f.get_qel()=" << f.get_qel() << '\n';
1128 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1129 << '\n';
1130 spexit(mcerr);
1131 }
1132 long n;
1133 indn.n += 2;
1134 for (n = 0; n < q; n++) {
1135 // Ifile<<"n="<<n<<" el[n]="<<noindent; f[n].print(file, l);
1136 // file<<yesindent;
1137 Ifile << "n=" << n << " el[n]=" << noindent;
1138 std::ostringstream ost;
1139 f[n].print(ost, l);
1140 ost << yesindent;
1141 put_one_n(ost);
1142 file << ost.str();
1143 }
1144 indn.n -= 2;
1145}
1146
1147template <class T>
1148void print_adr_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l,
1149 long q) {
1150 // mfunnamep("template<class T> void print_adr_DynLinArr(std::ostream& file,
1151 // const DynLinArr<T>& f, int l, long q)");
1152 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << " q to print is " << q
1153 << '\n';
1154 f.check();
1155 if (q > f.get_qel()) {
1156 mcerr << "print_adr_DynLinArr(...): q>f.get_qel(), q=" << q
1157 << " f.get_qel()=" << f.get_qel() << '\n';
1158 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1159 << '\n';
1160 spexit(mcerr);
1161 }
1162 long n;
1163 indn.n += 2;
1164 for (n = 0; n < q; n++) {
1165 // Ifile<<"n="<<n<<" el[n]="<<noindent; f[n]->print(file, l);
1166 // file<<yesindent;
1167 Ifile << "n=" << n << " el[n]=" << noindent;
1168 std::ostringstream ost;
1169 f[n]->print(ost, l);
1170 ost << yesindent;
1171 put_one_n(ost);
1172 file << ost.str();
1173 }
1174 indn.n -= 2;
1175}
1176
1178
1179void print_DynLinArr_int(std::ostream& file, const DynLinArr<int>& f);
1180void print_DynLinArr_long(std::ostream& file, const DynLinArr<long>& f);
1181void print_DynLinArr_float(std::ostream& file, const DynLinArr<float>& f);
1182void print_DynLinArr_double(std::ostream& file, const DynLinArr<double>& f);
1183// See AbsArrD for similar function with DoubleAc
1184
1185void print_DynLinArr_double2(std::ostream& file, const DynLinArr<double>& f1,
1186 const DynLinArr<double>& f2);
1187// Print two arrays in two colums side-by-side.
1188// Good for arrays of equal dimensions.
1189
1190void print_DynLinArr_int_double(std::ostream& file, const DynLinArr<int>& iar,
1191 const DynLinArr<double>& dar);
1192
1193void print_DynLinArr_int_double3(std::ostream& file, const DynLinArr<int>& iar,
1194 const DynLinArr<double>& dar1,
1195 const DynLinArr<double>& dar2,
1196 const DynLinArr<double>& dar3);
1197// Print 4 arrays in two colums side-by-side.
1198// Good for arrays of equal dimensions.
1199
1200#define Iprintdla_int(file, name) \
1201 file << indn << #name << "=" << noindent; \
1202 print_DynLinArr_int(file, name);
1203#define Iprintdla_long(file, name) \
1204 file << indn << #name << "=" << noindent; \
1205 print_DynLinArr_long(file, name);
1206#define Iprintdla_float(file, name) \
1207 file << indn << #name << "=" << noindent; \
1208 print_DynLinArr_float(file, name);
1209#define Iprintdla_double(file, name) \
1210 file << indn << #name << "=" << noindent; \
1211 print_DynLinArr_double(file, name);
1212// See AbsArrD for similar function with DoubleAc
1213
1214template <class T, class X>
1215void copy_DynLinArr(const T& s, X& d) {
1216 mfunnamep("template<class T, class X> void copy_DynLinArr(const T& s, X& d)");
1217 s.check();
1218 d.check();
1219 long q = s.get_qel();
1220 d.put_qel(q);
1221 long n;
1222 for (n = 0; n < q; n++) {
1223 d[n] = s[n];
1224 }
1225}
1226
1227// Covert to another compatible type
1228template <class T, class X>
1229void convert_DynLinArr(const T& s, X& d) {
1230 long q = s.get_qel();
1231 d.put_qel(q);
1232 long n;
1233 for (n = 0; n < q; n++) {
1234 d[n] = X(s[n]);
1235 }
1236}
1237
1238template <class T>
1239void put_qel_1(DynLinArr<T>& f, long fq) // change dimensions of arrays
1240 // which are elements of the main one
1241{
1242 long q = f.get_qel();
1243 long n;
1244 for (n = 0; n < q; n++) f[n].put_qel(fq);
1245}
1246
1247template <class T, class T1>
1248void assignAll_1(DynLinArr<T>& f, const T1& ft) // assign ft to all elements
1249 // of arrays which are elements of the main one
1250{
1251 long q = f.get_qel();
1252 long n;
1253 for (n = 0; n < q; n++) f[n].assignAll(ft);
1254}
1255
1256template <class T>
1258 public:
1259 IterDynLinArr(DynLinArr<T>* fdar) : dar(fdar), ncur(-1) { ; }
1260 T* more(void) {
1261 if (ncur < dar->get_qel() - 1)
1262 return &((*dar)[++ncur]);
1263 else
1264 ncur = dar->get_qel();
1265 return NULL;
1266 }
1267 T* current(void) {
1268 if (ncur >= 0 || ncur < dar->get_qel())
1269 return &((*dar)[ncur]);
1270 else
1271 return NULL;
1272 }
1273 T* less(void) // switch current to previous
1274 {
1275 if (ncur >= 1)
1276 return &((*dar)[--ncur]);
1277 else
1278 ncur = -1;
1279 return NULL;
1280 }
1281 long get_ncur(void) { return ncur; }
1282
1283 private:
1284 long ncur;
1285 DynLinArr<T>* dar;
1286};
1287
1288int gconfirm_ind(const DynLinArr<long>& qel, const DynLinArr<long>& ind);
1289int gconfirm_ind_ext(const DynLinArr<long>& qel, const DynLinArr<long>& ind);
1290
1291// The following function checks whether the arrays or their first qfirst
1292// elements are equal.
1293// In the first case this means that their dimensions and all elements
1294// should be equal to each other.
1295// In the second case if either of the dimensions is less than qfirst,
1296// the result is negative (0), so the arrays are considered different.
1297// If the dimensions are equal or more than qfirst,
1298// the function compares that number of first elements.
1299// If to put here just equal, the program may not be compiled since
1300// instead of this function the program will insert
1301// template <class InputIterator1, class InputIterator2>
1302// inline bool equal(InputIterator1 first1, InputIterator1 last1,
1303// InputIterator2 first2) {
1304// Therefore I substituted it to ifequal.
1305template <class T>
1306int ifequal(const DynLinArr<T>& fd1, const DynLinArr<T>& fd2,
1307 long qfirst = -1) {
1308 long n;
1309 if (qfirst == -1) {
1310 if ((qfirst = fd1.get_qel()) != fd2.get_qel()) return 0;
1311 // qfirst=fd1.get_qel();
1312 } else {
1313 if (qfirst > fd1.get_qel() || qfirst > fd2.get_qel()) return 0;
1314 }
1315 // Iprintn(mcout, qfirst);
1316 for (n = 0; n < qfirst; n++) {
1317 // Iprint3n(mcout, n, fd1[n], fd2[n]);
1318 if (!(fd1[n] == fd2[n])) return 0;
1319 }
1320 return 1;
1321}
1322
1323// The same as above, but compares DynLinArr with ordinary array.
1324template <class T>
1325int ifequal(const DynLinArr<T>& fd1, const T* fd2, long qfirst = -1) {
1326 long n;
1327 if (qfirst == -1) {
1328 qfirst = fd1.get_qel();
1329 } else {
1330 if (qfirst > fd1.get_qel()) return 0;
1331 }
1332 for (n = 0; n < qfirst; n++)
1333 if (!(fd1[n] == fd2[n])) return 0;
1334 return 1;
1335}
1336
1337template <class T>
1338int ifequal(T* fd1, T* fd2, long qfirst) {
1339 long n;
1340 for (n = 0; n < qfirst; n++)
1341 if (!(fd1[n] == fd2[n])) return 0;
1342 return 1;
1343}
1344
1345template <class T>
1346DynLinArr<T> merge(const DynLinArr<T>& fd1, long qfd1, const DynLinArr<T>& fd2,
1347 long qfd2) {
1348 long n;
1349 if (qfd1 < 0) {
1350 qfd1 = fd1.get_qel();
1351 }
1352 if (qfd2 < 0) {
1353 qfd2 = fd2.get_qel();
1354 }
1355 DynLinArr<T> ret(qfd1 + qfd2);
1356 if (qfd1 + qfd2 == 0) return ret;
1357 for (n = 0; n < qfd1; n++) {
1358 ret[n] = fd1[n];
1359 }
1360 for (n = 0; n < qfd2; n++) {
1361 ret[qfd1 + n] = fd2[n];
1362 }
1363 return ret;
1364}
1365
1366template <class T>
1367class DynArr : public RegPassivePtr {
1368 public:
1369 // Constructors
1370 DynArr(void) { ; }
1371 // For one-dimensional array:
1372 explicit DynArr(long fqel, T* val = NULL)
1373 : qel(DynLinArr<long>(1)),
1374 cum_qel(DynLinArr<long>(1)),
1375 el(DynLinArr<T>(fqel)) {
1376#ifdef DEBUG_DYNARR
1377 mcout << "explicit DynArr(long fqel, T* val=NULL) is called\n";
1378#endif
1379 qel[0] = fqel;
1380 cum_qel[0] = 1;
1381 if (val != NULL) assignAll(*val);
1382 }
1383 DynArr(long fqel, T val, ArgInterp_Val /*t*/)
1384 : qel(DynLinArr<long>(1)),
1385 cum_qel(DynLinArr<long>(1)),
1386 el(DynLinArr<T>(fqel)) {
1387#ifdef DEBUG_DYNARR
1388 mcout << "explicit DynArr(long fqel, T* val=NULL) is called\n";
1389#endif
1390 qel[0] = fqel;
1391 cum_qel[0] = 1;
1392 assignAll(val);
1393 }
1394 DynArr(long fqel, const T* ar, ArgInterp_Arr /*t*/)
1395 : qel(DynLinArr<long>(1)), cum_qel(DynLinArr<long>(1)), el(fqel) {
1396 qel[0] = fqel;
1397 cum_qel[0] = 1;
1398 long n;
1399 for (n = 0; n < fqel; n++) el.acu(n) = ar[n];
1400 }
1401 // Another variant for one-dimensional array
1402 // Attention: if the T is long, this might be mixed with array of dimensions.
1403 // To avoid this the latter should be accompanied by address, see below.
1405 : qel(DynLinArr<long>(1)), cum_qel(DynLinArr<long>(1)), el(f.get_qel()) {
1406 qel[0] = f.get_qel();
1407 cum_qel[0] = 1;
1408 for (long n = 0; n < qel[0]; n++) ac(n) = f[n];
1409 }
1410
1411 // For two-dimensional array:
1412 DynArr(long fqel1, long fqel2, T* val = NULL)
1413 : qel(DynLinArr<long>(2)),
1414 cum_qel(DynLinArr<long>(2)),
1415 el(fqel1 * fqel2) {
1416#ifdef DEBUG_DYNARR
1417 mcout << "DynArr(long fqel1, long fqel2, T* val=NULL) is called\n";
1418#endif
1419 qel[0] = fqel1;
1420 qel[1] = fqel2;
1421 cum_qel[0] = fqel2;
1422 cum_qel[1] = 1;
1423 if (val != NULL) assignAll(*val);
1424 }
1425
1426 DynArr(long fqel1, long fqel2, T val, ArgInterp_Val /*t*/)
1427 : qel(DynLinArr<long>(2)),
1428 cum_qel(DynLinArr<long>(2)),
1429 el(fqel1 * fqel2) {
1430#ifdef DEBUG_DYNARR
1431 mcout
1432 << "DynArr(long fqel1, long fqel2, T val, ArgInterp_Val t) is called\n";
1433#endif
1434 qel[0] = fqel1;
1435 qel[1] = fqel2;
1436 cum_qel[0] = fqel2;
1437 cum_qel[1] = 1;
1438 assignAll(val);
1439 }
1440
1441 // For three-dimensional array:
1442 DynArr(long fqel1, long fqel2, long fqel3, T* val = NULL)
1443 : qel(DynLinArr<long>(3)),
1444 cum_qel(DynLinArr<long>(3)),
1445 el(fqel1 * fqel2 * fqel3) {
1446 qel[0] = fqel1;
1447 qel[1] = fqel2;
1448 qel[2] = fqel3;
1449 cum_qel[0] = fqel2 * fqel3;
1450 cum_qel[1] = fqel3;
1451 cum_qel[2] = 1;
1452 if (val != NULL) assignAll(*val);
1453 }
1454
1455 // For four-dimensional array:
1456 DynArr(long fqel1, long fqel2, long fqel3, long fqel4, T* val = NULL)
1457 : qel(DynLinArr<long>(4)),
1458 cum_qel(DynLinArr<long>(4)),
1459 el(fqel1 * fqel2 * fqel3 * fqel4) {
1460 qel[0] = fqel1;
1461 qel[1] = fqel2;
1462 qel[2] = fqel3;
1463 qel[3] = fqel4;
1464 cum_qel[0] = fqel2 * fqel3 * fqel4;
1465 cum_qel[1] = fqel3 * fqel4;
1466 cum_qel[2] = fqel4;
1467 cum_qel[3] = 1;
1468 if (val != NULL) assignAll(*val);
1469 }
1470
1471 // Default value is removed in order to avoid confusions with copy
1472 // constructor from DynLinArr at T = long.
1473 // If initialization of values is not necessary, just put NULL as argument.
1474 // It creates array with structure determined by fqel.
1475
1476 DynArr(const DynLinArr<long>& fqel, T val, ArgInterp_Val /*t*/) : qel(fqel) {
1477 long qdim = qel.get_qel();
1478 if (qdim <= 0) return;
1479 cum_qel.put_qel(qdim);
1480 long ndim;
1481 long size = qel[0];
1482 for (ndim = 1; ndim < qdim; ndim++) size *= qel[ndim];
1483 el.put_qel(size);
1484 cum_qel[qdim - 1] = 1;
1485 for (ndim = qdim - 2; ndim >= 0; ndim--)
1486 cum_qel[ndim] = qel[ndim + 1] * cum_qel[ndim + 1];
1487 assignAll(val);
1488 }
1489
1490 explicit DynArr(const DynLinArr<long>& fqel, T* val) : qel(fqel) {
1491 // fqel: array of dimensions
1492 // val: address of value to fill, may be NULL
1493 long qdim = qel.get_qel();
1494 if (qdim <= 0) return;
1495 cum_qel.put_qel(qdim);
1496 long ndim;
1497 long size = qel[0];
1498 for (ndim = 1; ndim < qdim; ndim++) size *= qel[ndim];
1499 el.put_qel(size);
1500 cum_qel[qdim - 1] = 1;
1501 for (ndim = qdim - 2; ndim >= 0; ndim--)
1502 cum_qel[ndim] = qel[ndim + 1] * cum_qel[ndim + 1];
1503 if (val != NULL) assignAll(*val);
1504 }
1505
1507#ifdef DEBUG_DYNARR
1508 mcout << "DynArr(const DynArr<T>& f) is working\n";
1509#endif
1510 *this = f;
1511 }
1513 : qel(f.qel, steal), cum_qel(f.cum_qel, steal), el(f.el, steal) {
1514#ifdef DEBUG_DYNARR
1515 mcout << "DynArr( DynArr<T>& f, Pilfer) is working\n";
1516#endif
1517 }
1518
1519 void pilfer(const DynArr<T>& f) {
1520#ifdef DEBUG_DYNARR
1521 mcout << "DynArr::pilfer is called\n";
1522#endif
1523 if (this != &f) {
1524 if (qel.get_qel() != 0) {
1525 if (f.qel.get_qel() != 0) {
1526 mcerr << "ERROR in DynArr::pilfer(...):\n";
1527 mcerr << "Both the destination and source arrays are not empty\n";
1528 // For explanations why it is dangerous, see similar function
1529 // of ActivePtr.
1530 spexit(mcerr);
1531 } else {
1532 qel.clear();
1533 cum_qel.clear();
1534 el.clear();
1535 }
1536 }
1537 qel.pilfer(f.qel);
1538 cum_qel.pilfer(f.cum_qel);
1539 el.pilfer(f.el);
1540 f.qel.clear();
1541 f.cum_qel.clear();
1542 f.el.clear();
1543 }
1544 }
1545
1547 template <class D>
1549
1550 void pass(long q, DynLinArr<long> fqel, DynLinArr<long> fcum_qel, T* fel)
1551 // Do not call directly! Is to be used only
1552 // from assignment operator above
1553 {
1554 clear();
1555 qel = fqel;
1556 cum_qel = fcum_qel;
1557 el.pass(q, fel);
1558 }
1559
1560 // Auxiliary class that provides indexing through ordinary way
1561 // It is perhaps quite slow.
1562 template <class D>
1564 public:
1566 mutable long q_deref_ind;
1567 mutable long current_pos;
1568 IndexingProvider(DynArr<D>& farr, long fq_deref_ind, long fcurrent_pos)
1569 : arr(farr), q_deref_ind(fq_deref_ind), current_pos(fcurrent_pos) {}
1570 operator D&() const {
1571 if (q_deref_ind != arr.qel.get_qel()) {
1572 mcerr << "ERROR in IndexingProvider::operator D& (): q_deref_ind != "
1573 "qel.get_qel()\n";
1575 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1576 << '\n';
1577 spexit(mcerr);
1578 }
1579#ifdef ALR_CHECK_BOUND
1580 return arr.el[current_pos];
1581#else
1582 return arr.el.acu(current_pos);
1583#endif
1584 }
1585 D& operator=(const D& f) {
1586 if (q_deref_ind != arr.get_qel().get_qel()) {
1587 mcerr << "ERROR in T& IndexingProvider::operator=(T& f): q_deref_ind "
1588 "!= arr.get_qel().get_qel()\n";
1590 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1591 << '\n';
1592 spexit(mcerr);
1593 }
1594#ifdef ALR_CHECK_BOUND
1595 arr.ac_lin(current_pos) = f;
1596#else
1597 arr.acu_lin(current_pos) = f;
1598#endif
1599 // return arr.el[current_pos];
1600 }
1601
1603 if (q_deref_ind >= arr.get_qel().get_qel()) {
1604 mcerr << "ERROR in DynArr::IndexingProvider& DynArr::operator[](long "
1605 "n): q_deref_ind >= arr.get_qel().get_qel()\n";
1607 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1608 << '\n';
1609 spexit(mcerr);
1610 }
1611#ifdef ALR_CHECK_EACH_BOUND
1612 if (n < 0 || n >= arr.qel.acu(q_deref_ind)) {
1613 mcerr << "Error in IndexingProvider<D>& "
1614 "IndexingProvider::operator[](long n): n < 0 || n >= "
1615 "qel.acu(q_deref_ind)\n";
1616 Iprint2n(mcout, n, arr.qel.acu(q_deref_ind));
1617 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1618 << '\n';
1619 spexit(mcerr);
1620 }
1621#endif
1623 q_deref_ind++;
1624 return *this;
1625 }
1626
1627 inline const IndexingProvider<D>& operator[](long n) const {
1628 if (q_deref_ind >= arr.get_qel().get_qel()) {
1629 mcerr << "ERROR in DynArr::IndexingProvider& DynArr::operator[](long "
1630 "n): q_deref_ind >= arr.get_qel().get_qel()\n";
1632 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1633 << '\n';
1634 spexit(mcerr);
1635 }
1636#ifdef ALR_CHECK_EACH_BOUND
1637 if (n < 0 || n >= arr.qel.acu(q_deref_ind)) {
1638 mcerr << "Error in IndexingProvider<D>& "
1639 "IndexingProvider::operator[](long n): n < 0 || n >= "
1640 "qel.acu(q_deref_ind)\n";
1641 Iprint2n(mcout, n, arr.qel.acu(q_deref_ind));
1642 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1643 << '\n';
1644 spexit(mcerr);
1645 }
1646#endif
1648 q_deref_ind++;
1649 return *this;
1650 }
1651 };
1652
1653 // This operator can be used to provide ordinary indexing [][][]... .
1654 // It is perhaps quite slow compared with ac() functions.
1655 // It is provided only for the use in contexts in which [][][]...
1656 // is needed.
1658 if (qel.get_qel() < 1) {
1659 mcerr << "ERROR in DynArr::IndexingProvider DynArr::operator[](long n): "
1660 "qel.get_qel()< 1, qel.get_qel()=" << qel.get_qel() << '\n';
1661 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1662 << '\n';
1663 spexit(mcerr);
1664 }
1665#ifdef ALR_CHECK_EACH_BOUND
1666 if (n < 0 || n >= qel.acu(0)) {
1667 mcerr << "Error in IndexingProvider<T> DynArr::operator[](long n): n < 0 "
1668 "|| n >= qel.acu(0)\n";
1669 Iprint2n(mcout, n, qel.acu(0));
1670 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1671 << '\n';
1672 spexit(mcerr);
1673 }
1674#endif
1675 return IndexingProvider<T>(*this, 1, n * cum_qel.acu(0));
1676 }
1677
1678 inline const IndexingProvider<T> operator[](long n) const {
1679 if (qel.get_qel() < 1) {
1680 mcerr << "ERROR in DynArr::IndexingProvider DynArr::operator[](long n): "
1681 "qel.get_qel()< 1, qel.get_qel()=" << qel.get_qel() << '\n';
1682 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1683 << '\n';
1684 spexit(mcerr);
1685 }
1686#ifdef ALR_CHECK_EACH_BOUND
1687 if (n < 0 || n >= qel.acu(0)) {
1688 mcerr << "Error in IndexingProvider<T> DynArr::operator[](long n): n < 0 "
1689 "|| n >= qel.acu(0)\n";
1690 Iprint2n(mcout, n, qel.acu(0));
1691 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1692 << '\n';
1693 spexit(mcerr);
1694 }
1695#endif
1696 DynArr<T>* temp = const_cast<DynArr<T>*>(this);
1697 return IndexingProvider<T>(*temp, 1, n * cum_qel.acu(0));
1698 }
1699
1700 T& ac(long i) {
1701 // for 1-dimensional array
1702 if (qel.get_qel() == 1) return el[i];
1703 mcerr << "ERROR in DynArr::ac(long i): qel.get_qel()!= 1, qel.get_qel()="
1704 << qel.get_qel() << '\n';
1705 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1706 << '\n';
1707 spexit(mcerr);
1708 return el[0];
1709 }
1710 const T& ac(long i) const {
1711 // for 1-dimensional array
1712 if (qel.get_qel() == 1) return el[i];
1713 mcerr << "ERROR in DynArr::ac(long i): qel.get_qel()!= 1, qel.get_qel()="
1714 << qel.get_qel() << '\n';
1715 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1716 << '\n';
1717 spexit(mcerr);
1718 return el[0];
1719 }
1720 inline T& acu(long i1) // for 1-dimensional array, completely unchecked
1721 {
1722 return el.acu(i1);
1723 }
1724 inline const T& acu(long i1) const // for 1-dimensional array, completely
1725 // unchecked
1726 {
1727 return el.acu(i1);
1728 }
1729
1730 T& ac(const DynLinArr<long>& ind) // for arbitrary number of dimensions
1731 // but the number of them in array should be equal to size of ind.
1732 // ind is array of indexes. Its first element if the first index,
1733 // second is second, etc.
1734 {
1735 long q;
1736 if ((q = qel.get_qel()) != ind.get_qel()) {
1737 mcerr << "ERROR in DynArr::ac(const DynLinArr<long>& ind): "
1738 << "qel.get_qel()!= ind.get_qel()\n"
1739 << "qel.get_qel()=" << qel.get_qel()
1740 << " ind.get_qel()=" << ind.get_qel() << '\n';
1741 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1742 << '\n';
1743 spexit(mcerr);
1744 }
1745#ifdef ALR_CHECK_EACH_BOUND
1746#ifdef DEBUG_DYNARR
1747 if (q == 1) // faster for this case
1748 return el[ind.acu(0)];
1749 else
1750 return el[calc_lin_ind(ind)];
1751#else
1752 if (q == 1)
1753 return el[ind.acu(0)];
1754 else
1755 return el.acu(calc_lin_ind(ind));
1756#endif
1757#else
1758 if (q == 1)
1759 return el[ind.acu(0)];
1760 else
1761 return el[calc_lin_ind(ind)];
1762#endif
1763 }
1764 const T& ac(const DynLinArr<long>& ind) const // the same as above
1765 {
1766 long q;
1767 if ((q = qel.get_qel()) != ind.get_qel()) {
1768 mcerr << "ERROR in DynArr::ac(const DynLinArr<long>& ind): "
1769 << "qel.get_qel()!= ind.get_qel()\n"
1770 << "qel.get_qel()=" << qel.get_qel()
1771 << " ind.get_qel()=" << ind.get_qel() << '\n';
1772 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1773 << '\n';
1774 spexit(mcerr);
1775 }
1776/*
1777#ifdef ALR_CHECK_EACH_BOUND
1778#ifdef DEBUG_DYNARR
1779 return el[calc_lin_ind(ind)];
1780#else
1781 return el.acu(calc_lin_ind(ind));
1782#endif
1783#else
1784 return el[calc_lin_ind(ind)];
1785#endif
1786 //return el[calc_lin_ind(ind)];
1787 */
1788
1789#ifdef ALR_CHECK_EACH_BOUND
1790#ifdef DEBUG_DYNARR
1791 if (q == 1) // faster for this case
1792 return el[ind.acu(0)];
1793 else
1794 return el[calc_lin_ind(ind)];
1795#else
1796 if (q == 1)
1797 return el[ind.acu(0)];
1798 else
1799 return el.acu(calc_lin_ind(ind));
1800#endif
1801#else
1802 if (q == 1)
1803 return el[ind.acu(0)];
1804 else
1805 return el[calc_lin_ind(ind)];
1806#endif
1807 }
1808
1809 T& acp(const DynLinArr<long>& ind) // the same as above, but
1810 // the size of ind can be more than the number of indexes
1811 // (the rest is unused)
1812 {
1813 long q;
1814 if ((q = qel.get_qel()) > ind.get_qel()) {
1815 mcerr << "ERROR in DynArr::acp(const DynLinArr<long>& ind): "
1816 << "qel.get_qel()!= ind.get_qel()\n"
1817 << "qel.get_qel()=" << qel.get_qel()
1818 << " ind.get_qel()=" << ind.get_qel() << '\n';
1819 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1820 << '\n';
1821 spexit(mcerr);
1822 }
1823
1824#ifdef ALR_CHECK_EACH_BOUND
1825#ifdef DEBUG_DYNARR
1826 if (q == 1) // faster for this case
1827 return el[ind.acu(0)];
1828 else
1829 return el[calc_lin_ind(ind)];
1830#else
1831 if (q == 1)
1832 return el[ind.acu(0)];
1833 else
1834 return el.acu(calc_lin_ind(ind));
1835#endif
1836#else
1837 if (q == 1)
1838 return el[ind.acu(0)];
1839 else
1840 return el[calc_lin_ind(ind)];
1841#endif
1842 }
1843
1844 const T& acp(const DynLinArr<long>& ind) const {
1845 long q;
1846 if ((q = qel.get_qel()) > ind.get_qel()) {
1847 mcerr << "ERROR in DynArr::acp(const DynLinArr<long>& ind): "
1848 << "qel.get_qel()!= ind.get_qel()\n"
1849 << "qel.get_qel()=" << qel.get_qel()
1850 << " ind.get_qel()=" << ind.get_qel() << '\n';
1851 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1852 << '\n';
1853 spexit(mcerr);
1854 }
1855#ifdef ALR_CHECK_EACH_BOUND
1856#ifdef DEBUG_DYNARR
1857 if (q == 1) // faster for this case
1858 return el[ind.acu(0)];
1859 else
1860 return el[calc_lin_ind(ind)];
1861#else
1862 if (q == 1)
1863 return el[ind.acu(0)];
1864 else
1865 return el.acu(calc_lin_ind(ind));
1866#endif
1867#else
1868 if (q == 1)
1869 return el[ind.acu(0)];
1870 else
1871 return el[calc_lin_ind(ind)];
1872#endif
1873 }
1874
1875 T& acu(const DynLinArr<long>& ind) // unchecked
1876 {
1877 if (qel.get_qel() == 1)
1878 return el.acu(ind.acu(0));
1879 else
1880 return el.acu(calc_lin_ind(ind));
1881 }
1882 const T& acu(const DynLinArr<long>& ind) const // unchecked
1883 {
1884 if (qel.get_qel() == 1)
1885 return el.acu(ind.acu(0));
1886 else
1887 return el.acu(calc_lin_ind(ind));
1888 }
1889
1890 T& ac(long i1, long i2) // for 2-dimensional array
1891 {
1892 if (qel.get_qel() == 2) {
1893#ifdef ALR_CHECK_EACH_BOUND
1894 if (i1 >= 0 && i1 < qel.acu(0)) {
1895 if (i2 >= 0 && i2 < qel.acu(1)) {
1896#ifdef DEBUG_DYNARR
1897 return el[i1 * cum_qel.acu(0) + i2];
1898#else
1899 return el.acu(i1 * cum_qel.acu(0) + i2);
1900#endif
1901 } else {
1902 mcerr << "Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >= "
1903 "qel.acu(1)\n";
1904 Iprint2n(mcout, i2, qel[1]);
1905 }
1906 } else {
1907 mcerr << "Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >= "
1908 "qel.acu(0)\n";
1909 Iprint2n(mcout, i1, qel[0]);
1910 }
1911 } else {
1912 mcerr << "ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1913 << " qel.get_qel()=" << qel.get_qel() << '\n';
1914 }
1915 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1916 << '\n';
1917 spexit(mcerr);
1918 return el[0];
1919#else // for ifdef ALR_CHECK_EACH_BOUND
1920 return el[i1 * cum_qel.acu(0) + i2];
1921
1922#endif
1923 }
1924
1925 /*
1926 {
1927 if(qel.get_qel() != 2)
1928 { mcerr<<"ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1929 <<" qel.get_qel()=" <<qel.get_qel()<<'\n';
1930 mcerr<<"Type of T is (in internal notations) "<<typeid(T).name()<<'\n';
1931 spexit(mcerr); }
1932#ifdef ALR_CHECK_EACH_BOUND
1933 if(i1 < 0 || i1 >= qel.acu(0))
1934 {
1935 mcerr<<"Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >=
1936qel.acu(0)\n";
1937 Iprint2n(mcout, i1, qel[0]);
1938 spexit(mcerr);
1939 }
1940 if(i2 < 0 || i2 >= qel.acu(1))
1941 {
1942 mcerr<<"Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >=
1943qel.acu(1)\n";
1944 Iprint2n(mcout, i2, qel[1]);
1945 spexit(mcerr);
1946 }
1947#ifdef DEBUG_DYNARR
1948 return el[i1*cum_qel.acu(0) + i2];
1949#else
1950 return el.acu(i1*cum_qel.acu(0) + i2);
1951#endif
1952#else
1953 return el[i1*cum_qel.acu(0) + i2];
1954#endif
1955 }
1956 */
1957 const T& ac(long i1, long i2) const // for 2-dimensional array
1958 {
1959 if (qel.get_qel() == 2) {
1960#ifdef ALR_CHECK_EACH_BOUND
1961 if (i1 >= 0 && i1 < qel.acu(0)) {
1962 if (i2 >= 0 && i2 < qel.acu(1)) {
1963#ifdef DEBUG_DYNARR
1964 return el[i1 * cum_qel.acu(0) + i2];
1965#else
1966 return el.acu(i1 * cum_qel.acu(0) + i2);
1967#endif
1968 } else {
1969 mcerr << "Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >= "
1970 "qel.acu(1)\n";
1971 Iprint2n(mcout, i2, qel[1]);
1972 }
1973 } else {
1974 mcerr << "Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >= "
1975 "qel.acu(0)\n";
1976 Iprint2n(mcout, i1, qel[0]);
1977 }
1978 } else {
1979 mcerr << "ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1980 << " qel.get_qel()=" << qel.get_qel() << '\n';
1981 }
1982 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1983 << '\n';
1984 spexit(mcerr);
1985 return el[0];
1986#else // for ifdef ALR_CHECK_EACH_BOUND
1987 return el[i1 * cum_qel.acu(0) + i2];
1988
1989#endif
1990 }
1991 /*
1992 {
1993 if(qel.get_qel() != 2)
1994 { mcerr<<"ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1995 <<" qel.get_qel()=" <<qel.get_qel()<<'\n';
1996 mcerr<<"Type of T is (in internal notations) "<<typeid(T).name()<<'\n';
1997 spexit(mcerr); }
1998#ifdef ALR_CHECK_EACH_BOUND
1999 if(i1 < 0 || i1 >= qel.acu(0))
2000 {
2001 mcerr<<"Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >=
2002qel.acu(0)\n";
2003 Iprint2n(mcout, i1, qel[0]);
2004 spexit(mcerr);
2005 }
2006 if(i2 < 0 || i2 >= qel.acu(1))
2007 {
2008 mcerr<<"Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >=
2009qel.acu(1)\n";
2010 Iprint2n(mcout, i2, qel[1]);
2011 spexit(mcerr);
2012 }
2013#ifdef DEBUG_DYNARR
2014 return el.acu(i1*cum_qel.acu(0) + i2);
2015#else
2016 return el[i1*cum_qel.acu(0) + i2];
2017#endif
2018#else
2019 return el[i1*cum_qel.acu(0) + i2];
2020#endif
2021 //return el[i1*cum_qel[0] + i2];
2022 }
2023 */
2024 inline T& acu(long i1,
2025 long i2) // for 2-dimensional array, completely unchecked
2026 {
2027 return el.acu(i1 * cum_qel.acu(0) + i2);
2028 }
2029 inline const T& acu(long i1, long i2) const // for 2-dimensional array
2030 {
2031 return el.acu(i1 * cum_qel.acu(0) + i2);
2032 }
2033
2034 T& ac(long i1, long i2, long i3) // for 3-dimensional array
2035 {
2036 if (qel.get_qel() != 3) {
2037 mcerr << "ERROR in DynArr::ac(long i1, long i2, long i3): "
2038 "qel.get_qel()!= 3,"
2039 << " qel.get_qel()=" << qel.get_qel() << '\n';
2040 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2041 << '\n';
2042 spexit(mcerr);
2043 }
2044#ifdef ALR_CHECK_EACH_BOUND
2045 if (i1 < 0 || i1 >= qel.acu(0)) {
2046 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i1 < 0 || i1 "
2047 ">= qel.acu(0)\n";
2048 Iprint2n(mcout, i1, qel[0]);
2049 spexit(mcerr);
2050 }
2051 if (i2 < 0 || i2 >= qel.acu(1)) {
2052 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i2 < 0 || i2 "
2053 ">= qel.acu(1)\n";
2054 Iprint2n(mcout, i2, qel[1]);
2055 spexit(mcerr);
2056 }
2057 if (i3 < 0 || i3 >= qel.acu(2)) {
2058 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i3 < 0 || i3 "
2059 ">= qel.acu(2)\n";
2060 Iprint2n(mcout, i3, qel[2]);
2061 spexit(mcerr);
2062 }
2063#ifdef DEBUG_DYNARR
2064 return el.acu(i1 * cum_qel.acu(0) + i2 * cum_qel.acu(1) + i3);
2065#else
2066 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2067#endif
2068#else
2069 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2070#endif
2071 // return el[i1*cum_qel[0] + i2*cum_qel[1] + i3];
2072 }
2073
2074 const T& ac(long i1, long i2, long i3) const // for 3-dimensional array
2075 {
2076 if (qel.get_qel() != 3) {
2077 mcerr << "ERROR in DynArr::ac(long i1, long i2, long i3): "
2078 "qel.get_qel()!= 3,"
2079 << " qel.get_qel()=" << qel.get_qel() << '\n';
2080 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2081 << '\n';
2082 spexit(mcerr);
2083 }
2084#ifdef ALR_CHECK_EACH_BOUND
2085 if (i1 < 0 || i1 >= qel.acu(0)) {
2086 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i1 < 0 || i1 "
2087 ">= qel.acu(0)\n";
2088 Iprint2n(mcout, i1, qel[0]);
2089 spexit(mcerr);
2090 }
2091 if (i2 < 0 || i2 >= qel.acu(1)) {
2092 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i2 < 0 || i2 "
2093 ">= qel.acu(1)\n";
2094 Iprint2n(mcout, i2, qel[1]);
2095 spexit(mcerr);
2096 }
2097 if (i3 < 0 || i3 >= qel.acu(2)) {
2098 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i3 < 0 || i3 "
2099 ">= qel.acu(2)\n";
2100 Iprint2n(mcout, i3, qel[2]);
2101 spexit(mcerr);
2102 }
2103#ifdef DEBUG_DYNARR
2104 return el.acu(i1 * cum_qel.acu(0) + i2 * cum_qel.acu(1) + i3);
2105#else
2106 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2107#endif
2108#else
2109 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2110#endif
2111 // return el[i1*cum_qel[0] + i2*cum_qel[1] + i3];
2112 }
2113
2114 long get_qel_lin(void) const { return el.get_qel(); }
2115
2116 // access to array as linear array
2117 inline T& ac_lin(long n) {
2118 long qelln = el.get_qel();
2119#ifdef ALR_CHECK_BOUND
2120 if (n >= 0 && n < qelln) return el[n];
2121 mcerr << "ERROR in T& DynArr::ac_lin(long n): "
2122 << "n is out of bounds, n=" << n << " qelln=" << qelln << '\n';
2123 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2124 << '\n';
2125 spexit(mcerr);
2126 return el[0];
2127#else
2128 return el[n];
2129#endif
2130 }
2131 inline const T& ac_lin(long n) const {
2132 long qelln = el.get_qel();
2133#ifdef ALR_CHECK_BOUND
2134 if (n >= 0 && n < qelln) return el[n];
2135 mcerr << "ERROR in T& DynArr::ac_lin(long n): "
2136 << "n is out of bounds, n=" << n << " qelln=" << qelln << '\n';
2137 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2138 << '\n';
2139 spexit(mcerr);
2140 return el[0];
2141#else
2142 return el[n];
2143#endif
2144 }
2145 // access to array as linear array always without check
2146 inline T& acu_lin(long n) { return el[n]; }
2147 inline const T& acu_lin(long n) const { return el[n]; }
2148
2149 void assignAll(const T& val);
2150
2151 long get_qdim(void) const { return qel.get_qel(); }
2152 const DynLinArr<long>& get_qel(void) const { return qel; }
2153 const DynLinArr<T>& get_el(void) const { return el; }
2154
2155 // The following is mainly for debug (diagnostic print):
2156 const DynLinArr<long>& get_cum_qel(void) const { return cum_qel; }
2157
2158 // void put_qel(const DynLinArr<long>& fqel, T* val=NULL);
2159 void put_qel(T* val = NULL);
2160 // 25.10.2006: Today I do not understand these following comments.
2161 // They looks like simple copy from these in DynLinArr.
2162 // creates array with size fqel
2163 // If old array existed, then
2164 // If it was less than fqel, it all is copied to new array
2165 // and the other elements are either remains not inited
2166 // or assignned *val.
2167 // else its fqel part is copyed to new array.
2168
2169 void clear(void) {
2170 qel.clear();
2171 cum_qel.clear();
2172 el.clear();
2173 }
2174
2175 int confirm_ind(const DynLinArr<long>& ind) { return gconfirm_ind(qel, ind); }
2177 return gconfirm_ind_ext(qel, ind);
2178 }
2180
2181 // Apply any function of one argument (of type T) to each element.
2182 template <class P>
2183 friend void apply1(DynArr<P>& ar, void (*fun)(P& f));
2184
2185 // Apply any function of two arguments
2186 // (first of which is of type T and the second is of type of address
2187 // of another function (possibly apply1) to each element.
2188 template <class P, class X>
2189 friend void apply2(DynArr<P>& ar, void (*fun1)(P& f, void (*fun21)(X& f)),
2190 void (*fun2)(X& f));
2191
2192 void check(void) const {
2193 qel.check();
2194 cum_qel.check();
2195 el.check();
2196 }
2197 int get_s_non_emplty(void) const {
2198 long q = qel.get_qel();
2199 if (q == 0) return 0;
2200 long n;
2201 for (n = 0; n < q; n++) {
2202 if (qel[n] <= 0) return 0;
2203 }
2204 return 1;
2205 }
2206 virtual DynArr* copy() const { return new DynArr(*this); }
2207 virtual ~DynArr() {}
2208
2209 private:
2210 mutable DynLinArr<long> qel;
2211 // Linear array with number of elements by each dimension
2212 mutable DynLinArr<long> cum_qel;
2213 // "cumulative qel": each element contains product
2214 // of next elements of qel.
2215 // The last element is always 1.
2216 // Used for fast search of proper element in el.
2217
2218 mutable DynLinArr<T> el;
2219 // Contains all elements.
2220 // The last index varies faster.
2221
2222 long calc_lin_ind(const DynLinArr<long>& ind) const {
2223 long i = 0;
2224 long n;
2225 long qdim1 = qel.get_qel() - 1;
2226 /*
2227 // This check is not necessary by two reasons
2228 // 1. The checks of this condition are made in calling functions.
2229 // 2. The correct condition is not != but >.
2230 if(qdim1 != ind.get_qel() - 1)
2231 {
2232 mcerr<<"ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& ind)
2233const\n";
2234 mcerr<<"qdim1 != ind.get_qel() - 1\n";
2235 Iprint2n(mcerr, qdim1, (ind.get_qel() - 1));
2236 spexit(mcerr);
2237 }
2238 */
2239 for (n = 0; n < qdim1; n++) {
2240#ifdef ALR_CHECK_EACH_BOUND
2241#ifdef DEBUG_DYNARR
2242 if (ind[n] < 0 || ind[n] >= qel[n]) {
2243 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& "
2244 "ind) const\n";
2245 mcerr << "ind[n] < 0 || ind[n] >= qel[n]\n";
2246 Iprint3n(mcout, n, ind[n], qel[n]);
2247 Iprintn(mcout, qel);
2248 spexit(mcerr);
2249 }
2250#else
2251 if (ind.acu(n) < 0 || ind.acu(n) >= qel.acu(n)) {
2252 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& "
2253 "ind) const\n";
2254 mcerr << "ind.acu(n) < 0 || ind.acu(n) >= qel.acu(n)\n";
2255 Iprint3n(mcout, n, ind[n], qel[n]);
2256 Iprintn(mcout, qel);
2257 spexit(mcerr);
2258 }
2259#endif
2260#endif
2261 i += ind[n] * cum_qel[n];
2262 }
2263#ifdef ALR_CHECK_EACH_BOUND
2264#ifdef DEBUG_DYNARR
2265 if (ind[qdim1] < 0 || ind[qdim1] >= qel[qdim1]) {
2266 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& ind) "
2267 "const\n";
2268 mcerr << "ind[qdim1] < 0 || ind[qdim1] >= qel[qdim1]\n";
2269 Iprint3n(mcout, n, ind[qdim1], qel[qdim1]);
2270 Iprintn(mcout, qel);
2271 spexit(mcerr);
2272 }
2273#else
2274 if (ind.acu(qdim1) < 0 || ind.acu(qdim1) >= qel.acu(qdim1)) {
2275 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& ind) "
2276 "const\n";
2277 mcerr << "ind.acu(qdim1) < 0 || ind.acu(qdim1) >= qel.acu(qdim1)\n";
2278 Iprint3n(mcout, n, ind[qdim1], qel[qdim1]);
2279 Iprintn(mcout, qel);
2280 spexit(mcerr);
2281 }
2282#endif
2283#endif
2284 i += ind[qdim1]; // the last index, for which multiplication by cum_qel
2285 // is not necessary.
2286 return i;
2287 }
2288};
2289
2290template <class T>
2292#ifdef DEBUG_DYNARR
2293 mcout << "DynArr<T>& DynArr<T>::operator=(const DynArr<T>& f)\n";
2294#endif
2295 if (this != &f) {
2296 // mcout<<"DynLinArr<T>& operator=(const DynLinArr<T>& f): long(el)="
2297 //<<long(el)<<'\n';
2298 check();
2299 f.check();
2300 qel = f.qel;
2301 cum_qel = f.cum_qel;
2302 el = f.el;
2303 }
2304 return *this;
2305}
2306
2307template <class T>
2308template <class D>
2310#ifdef DEBUG_DYNLINARR
2311 mcout << "DynArr<T>& DynArr<T>::operator=(const DynArr<D>& f)\n";
2312#endif
2313 if (this == &f) return *this;
2314 check();
2315 f.check();
2316 DynLinArr<long> fqel = f.get_qel();
2317 DynLinArr<long> fcum_qel = f.get_cum_qel();
2318 // for example, one of its elements.
2319 const long q = f.get_qel_lin();
2320 T* temp_el = (q > 0) ? (new T[q]) : (T*)NULL;
2321 for (long n = 0; n < q; n++) temp_el[n] = f.acu_lin(n);
2322 pass(q, fqel, fcum_qel, temp_el);
2323 return *this;
2324}
2325
2326template <class T>
2327void apply1(DynArr<T>& ar, void (*fun)(T& f)) {
2328 const long q = ar.el.get_qel();
2329 for (long n = 0; n < q; n++) (*fun)(ar.el[n]);
2330}
2331template <class T, class X>
2332void apply2(DynArr<T>& ar, void (*fun1)(T& f, void (*fun21)(X& f)),
2333 void (*fun2)(X& f)) {
2334 const long q = ar.el.get_qel();
2335 for (long n = 0; n < q; n++) (*fun1)(ar.el[n], fun2);
2336}
2337
2338int find_next_comb(const DynLinArr<long>& qel, DynLinArr<long>& f);
2339int find_prev_comb(const DynLinArr<long>& qel, DynLinArr<long>& f);
2340int find_next_comb_not_less(const DynLinArr<long>& qel, DynLinArr<long>& f);
2341
2342template <class T>
2344 public:
2346 : ncur(fdar->get_qdim()), dar((DynArr<T>*)fdar) {
2347 long n;
2348 long qdim1 = ncur.get_qel() - 1;
2349 if (qdim1 >= 0) {
2350 for (n = 0; n < qdim1; n++) ncur[n] = 0;
2351 ncur[qdim1] = -1;
2352 }
2353 }
2354 T* more(void) // Just next element. Why not "next", do not remember.
2355 {
2356 if (find_next_comb(dar->get_qel(), ncur))
2357 return &(dar->ac(ncur));
2358 else
2359 return NULL;
2360 }
2361
2362 T* current(void) // Element currently pointed by ncut.
2363 {
2364 long n;
2365 long qdim = ncur.get_qel();
2366 if (qdim <= 0) return NULL;
2367 for (n = 0; n < qdim; n++) {
2368 if (ncur[n] < 0 || ncur[n] >= dar->get_qel()[n]) return NULL;
2369 }
2370 return &(dar->ac(ncur));
2371 }
2372
2373 T* less(void) // Switch current to previous.
2374 // Again do not remember why not" prev"
2375 {
2376 if (find_prev_comb(dar->get_qel(), ncur))
2377 return &(dar->ac(ncur));
2378 else
2379 return NULL;
2380 }
2381
2382 const DynLinArr<long>& get_ncur(void) const { return ncur; }
2383
2384 private:
2385 DynLinArr<long> ncur;
2386 DynArr<T>* dar;
2387};
2388
2389extern DynLinArr<long> qel_communicat;
2390
2391template <class T>
2393 // by default val=NULL
2394{
2395 check();
2396 if (qel.get_qel() == 0) {
2397 *this = DynArr<T>(qel_communicat, val);
2398 return;
2399 }
2400
2401 DynArr<T> datemp(qel_communicat, val); // all init to val
2402 IterDynArr<T> iter(&datemp);
2403 T* at;
2404 while ((at = iter.more()) != NULL) {
2405 if (confirm_ind_ext(iter.get_ncur()))
2406 *at = acp(iter.get_ncur()); // change to old values where they were
2407 }
2408 *this = datemp;
2409}
2410
2411template <class T>
2412int operator==(const DynLinArr<T>& f1, const DynLinArr<T>& f2) {
2413 if (f1.get_qel() != f2.get_qel()) return 0;
2414 long q = f1.get_qel();
2415 long n;
2416 for (n = 0; n < q; n++) {
2417 if (!(f1.acu(n) == f2.acu(n))) return 0;
2418 }
2419 return 1;
2420}
2421
2422template <class T, class P>
2423int apeq_mant(const DynLinArr<T>& f1, const DynLinArr<T>& f2, P prec) {
2424 if (f1.get_qel() != f2.get_qel()) return 0;
2425 long q = f1.get_qel();
2426 long n;
2427 for (n = 0; n < q; n++) {
2428 if (!apeq_mant(f1.acu(n), f2.acu(n), prec)) return 0;
2429 }
2430 return 1;
2431}
2432
2433template <class T>
2434int operator!=(const DynLinArr<T>& f1, const DynLinArr<T>& f2) {
2435 if (f1 == f2)
2436 return 0;
2437 else
2438 return 1;
2439}
2440
2441template <class T>
2442int operator==(const DynArr<T>& f1, const DynArr<T>& f2) {
2443 if (f1.get_qel() != f2.get_qel()) return 0;
2444 if (f1.get_el() != f2.get_el()) return 0;
2445 return 1;
2446}
2447
2448template <class T, class P>
2449int apeq_mant(const DynArr<T>& f1, const DynArr<T>& f2, P prec) {
2450 if (f1.get_qel() != f2.get_qel()) return 0;
2451 if (!apeq_mant(f1.get_el(), f2.get_el(), prec)) return 0;
2452 return 1;
2453}
2454
2455template <class T>
2456int operator!=(const DynArr<T>& f1, const DynArr<T>& f2) {
2457 if (f1.get_qel() == f2.get_qel()) return 0;
2458 if (f1.get_el() == f2.get_el()) return 0;
2459 return 1;
2460}
2461
2462template <class T>
2463void DynArr<T>::assignAll(const T& val) {
2464 check();
2465 // try faster and simpler way (30.10.2006):
2466 el.assignAll(val);
2467 /*
2468 IterDynArr<T> iter(this);
2469 T* at;
2470 while( (at=iter.more()) != NULL )
2471 {
2472 *at=val;
2473 }
2474 */
2475}
2476
2477template <class T, class X>
2478void copy_DynArr(const DynArr<T>& s, DynArr<X>& d) {
2479 mfunnamep(
2480 "template<class T, class X> void copy_DynArr(const DynArr<T>& s, "
2481 "DynArr<X>& d)");
2482 s.check();
2483 d.check();
2484 d = DynArr<X>(s.get_qel(), NULL);
2485 IterDynArr<T> iter(&s);
2486 T* at;
2487 while ((at = iter.more()) != NULL) {
2488 const DynLinArr<long>& ncur = iter.get_ncur();
2489 d.ac(ncur) = *at;
2490 }
2491}
2492
2493// Convert types of elements from T to X.
2494template <class T, class X>
2496 mfunnamep(
2497 "template<class T, class X> void convert_DynArr(const DynArr<T>& "
2498 "s, DynArr<X>& d)");
2499 s.check();
2500 d.check();
2501 d = DynArr<X>(s.get_qel(), NULL);
2502 IterDynArr<T> iter(&s);
2503 T* at;
2504 while ((at = iter.more()) != NULL) {
2505 const DynLinArr<long>& ncur = iter.get_ncur();
2506 d.ac(ncur) = X(*at);
2507 }
2508}
2509
2510template <class T>
2512 check();
2513 DynArr<T> r(1, qel);
2514 long n;
2515 for (n = 0; n < qel; n++) {
2516 r.ac(0, n) = el[n];
2517 }
2518 return r;
2519}
2520template <class T>
2522 mfunnamep("template<class T> DynArr<T> DynArr<T>::top(void)");
2523 check();
2524 long qdim = get_qdim();
2525 check_econd11(qdim, != 2, mcerr);
2526 long n1, n2;
2527 DynArr<T> r(qel[1], qel[0]);
2528 for (n1 = 0; n1 < qel[0]; n1++) {
2529 for (n2 = 0; n2 < qel[1]; n2++) {
2530 r.ac(n2, n1) = ac(n1, n2);
2531 }
2532 }
2533 return r;
2534}
2535
2536template <class T>
2538 // mcout<<"template<class T> DynLinArr<T>::DynLinArr(const DynArr<T>& f):\n";
2539 f.check();
2540 long qdim = f.get_qdim();
2541 if (qdim != 1) {
2542 mcerr << "ERROR in DynLinArr<T>::DynLinArr(const DynArr<T>& f):\n"
2543 << "f.get_qdim() != 1, f.get_qdim()=" << f.get_qdim() << '\n';
2544 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2545 << '\n';
2546 spexit(mcerr);
2547 }
2548 const DynLinArr<long>& qelem = f.get_qel();
2549 qel = qelem[0];
2550 // mcout<<"qel="<<qel<<'\n';
2551 if (qel > 0) {
2552 el = new T[qel];
2553 for (long n = 0; n < qel; n++) el[n] = f.ac(n);
2554 } else
2555 el = NULL;
2556}
2557
2558template <class T>
2559DynLinArr<T>::DynLinArr(const DynArr<T>& f, int n_of_dim,
2560 // 0 - first dim) 1 - second dim)
2561 long roc_number)
2562 // takes only mentioned raw or column.
2563{
2564 f.check();
2565 long qdim = f.get_qdim();
2566 if (qdim != 2) {
2567 mcerr << "ERROR in DynLinArr<T>::DynLinArr(const DynArr<T>& f, int "
2568 "n_of_dim,long roc_number):\n"
2569 << "f.get_qdim() != 2, f.get_qdim()=" << f.get_qdim() << '\n';
2570 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2571 << '\n';
2572 spexit(mcerr);
2573 }
2574 const DynLinArr<long>& qelem = f.get_qel();
2575 if (n_of_dim == 0) {
2576 qel = qelem[1];
2577 } else {
2578 qel = qelem[0];
2579 }
2580 // mcout<<"qel="<<qel<<'\n';
2581 if (qel > 0) {
2582 el = new T[qel];
2583 long n;
2584 if (n_of_dim == 0) {
2585 for (n = 0; n < qel; n++) el[n] = f.ac(roc_number, n);
2586 } else {
2587 for (n = 0; n < qel; n++) el[n] = f.ac(n, roc_number);
2588 }
2589 }
2590}
2591
2592template <class T>
2593std::ostream& operator<<(std::ostream& file, const DynArr<T>& f) {
2594 // mfunnamep("template<class T> std::ostream& operator<<(std::ostream& file,
2595 // const DynArr<T>& f)");
2596 f.check();
2597 Ifile << "DynArr<T>: qdim=" << f.get_qdim() << '\n';
2598 indn.n += 2;
2599 if (s_short_output > 0) {
2600 Ifile << noindent << f.get_qel() << yesindent;
2601 } else {
2602 Ifile << "qel=" << noindent << f.get_qel() << yesindent;
2603 Ifile << "cum_qel=" << noindent << f.get_cum_qel() << yesindent;
2604 }
2605 if (f.get_s_non_emplty() == 1) {
2606 if (s_short_output == 0) {
2607 Ifile << "Content element by element:\n";
2608 Ifile << "(The first number is sequencial number, then there are "
2609 "indexes, the last is the element)\n";
2610 // DynArr<T>& ff(f);
2611 }
2612 long nseq = 0;
2613 IterDynArr<T> iter_f(&((DynArr<T>&)f));
2614 T* at;
2615 while ((at = iter_f.more()) != NULL) {
2616 std::ostringstream ost;
2617 if (s_short_output == 0) {
2618 // Ifile<<"ncur="<<noindent<<iter_f.get_ncur()<<yesindent;
2619 Ifile << "nseq=" << std::setw(5) << nseq << " ncur=";
2620 long n;
2621 for (n = 0; n < iter_f.get_ncur().get_qel(); n++) {
2622 file << ' ' << std::setw(5) << iter_f.get_ncur()[n];
2623 }
2624 ost << indn << " element=" << noindent << (*at) << yesindent;
2625 } else {
2626 ost << indn << noindent << (*at) << yesindent;
2627 }
2628 put_one_n(ost);
2629 file << ost.str();
2630 nseq++;
2631 }
2632 file << yesindent;
2633 } else {
2634 if (s_short_output == 0) {
2635 Ifile << "Content is empty.\n";
2636 }
2637 }
2638 indn.n -= 2;
2639 return file;
2640}
2641/*
2642template<class T>
2643void DybArr<T>::short_output(std::ostream& file)
2644{
2645 mfunnamep("template<class T> void DybArr<T>::short_output(std::ostream&
2646file))");
2647 f.check();
2648 Ifile<<"DynArr<T>: qdim="<<f.get_qdim()<<'\n';
2649 indn.n+=2;
2650 qel.short_output(file);
2651 if(f.get_s_non_emplty() == 1)
2652 {
2653 long nseq=0;
2654 IterDynArr<T> iter_f( &((DynArr<T>&) f));
2655 T* at;
2656 while( (at=iter_f.more()) != NULL )
2657 {
2658 std::ostringstream ost;
2659 ost<<indn<<noindent<<(*at)<<yesindent;
2660 put_one_n(ost);
2661 file<<ost.str();
2662 nseq++;
2663 }
2664 file<<yesindent;
2665 }
2666 indn.n-=2;
2667 return file;
2668}
2669*/
2670template <class T>
2671std::istream& operator>>(std::istream& file, DynArr<T>& f) {
2672 mfunnamep(
2673 "template<class T> istream& operator>>(istream& file, DynArr<T>& f)");
2674 definp_endpar dep(&file, 0, 1, 0, s_short_output);
2675 long qdim = 0;
2676 dep.s_short = 0;
2677 DEFINPAP(qdim);
2678 dep.s_short = s_short_output;
2679 check_econd11(qdim, < 0, mcerr);
2680 if (s_short_output == 0) {
2681 set_position("qel=DynLinArr<T>:", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2682 } else {
2683 set_position("DynLinArr<T>:", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2684 }
2685 DynLinArr<long> qel_loc;
2686 // mcout<<"now will read qel_loc\n";
2687 file >> qel_loc;
2688 // mcout<<"qel_loc is read\n";
2689 if (s_short_output == 0) {
2690 set_position("cum_qel=DynLinArr<T>:", *dep.istrm, dep.s_rewind,
2691 dep.s_req_sep);
2692 DynLinArr<long> cum_qel_loc;
2693 file >> cum_qel_loc; // this is in general unnecessary
2694 }
2695 if (qel_loc.get_qel() > 0) {
2696 f.pilfer(DynArr<T>(qel_loc, NULL));
2697 long nseq;
2698 long n;
2699 long qseq = qel_loc[0];
2700 for (n = 1; n < qel_loc.get_qel(); n++) {
2701 qseq *= qel_loc[n];
2702 }
2703 for (n = 0; n < qseq; n++) {
2704 if (s_short_output == 0) {
2705 DEFINPAP(nseq);
2706 check_econd12(nseq, !=, n, mcerr);
2707 DynLinArr<long> ncur(qel_loc.get_qel());
2708 set_position("ncur=", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2709 long m;
2710 for (m = 0; m < qel_loc.get_qel(); m++) {
2711 file >> ncur[m];
2712 }
2713 // T element;
2714 // DEFINPAP(element);
2715 // f.ac(ncur) = element;
2716 set_position("element=", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2717 }
2718 file >> f.ac_lin(n);
2719 }
2720 } else {
2721 if (s_short_output == 0) {
2722 // just pass to end
2723 set_position("Content is empty.", *dep.istrm, dep.s_rewind,
2724 dep.s_req_sep);
2725 }
2726 f.pilfer(DynArr<T>());
2727 }
2728 return file;
2729}
2730
2731/*
2732template<class T>
2733void DynArr<T>::short_read(istream& file)
2734{
2735 mfunnamep("template<class T> void DynArr<T>::short_read(istream& file)");
2736 definp_endpar dep(&file, 0, 1, 0);
2737 long qdim=0;
2738 DEFINPAP(qdim);
2739 check_econd11(qdim, < 0 , mcerr);
2740 DynLinArr<long> qel_loc;
2741 qel_loc.short_read(file);
2742 // generate cum
2743 if(qel_loc.get_qel() > 0 )
2744 {
2745 f.pilfer(DynArr<T>(qel_loc, NULL));
2746 long nseq;
2747 long n;
2748 long qseq=qel[0];
2749 for(n=1; n<el.get_qel(); n++)
2750 {
2751 qseq*=el[n];
2752 }
2753 for(n=0; n<qseq; n++)
2754 {
2755 file>>f.ac(ncur);
2756 }
2757 }
2758 else
2759 {
2760 // just pass to end
2761 set_position("Content is empty.",
2762 *dep.istrm, dep.s_rewind, dep.s_req_sep);
2763 }
2764 return file;
2765}
2766*/
2767
2768template <class T>
2769void print_DynArr(std::ostream& file, const DynArr<T>& f, int l) {
2770 // mfunnamep("template<class T> oid print_DynArr(std::ostream& file, const
2771 // DynArr<T>& f, int l)");
2772 f.check();
2773 // Ifile<<"DynArr<T>: qdim="<<f.get_qdim()
2774 // <<" qel="<<noindent<<f.get_qel()<<yesindent<<'\n';
2775 Ifile << "DynArr<T>: qdim=" << f.get_qdim() << '\n';
2776 indn.n += 2;
2777 Ifile << "qel=" << noindent << f.get_qel() << yesindent;
2778 Ifile << "cum_qel=" << noindent << f.get_cum_qel() << yesindent;
2779 Ifile << "Content element by element:\n";
2780 Ifile << "(The first number is sequencial number, then there are indexes, "
2781 "the last is the element)\n";
2782 // DynArr<T>& ff(f);
2783 long nseq = 0;
2784 IterDynArr<T> iter_f(&((DynArr<T>&)f));
2785 T* at;
2786 while ((at = iter_f.more()) != NULL) {
2787 // Ifile<<"ncur="<<noindent<<iter_f.get_ncur()<<yesindent;
2788 Ifile << "nseq=" << std::setw(5) << nseq << " ncur=";
2789 long n;
2790 for (n = 0; n < iter_f.get_ncur().get_qel(); n++) {
2791 file << ' ' << std::setw(5) << iter_f.get_ncur()[n];
2792 }
2793 // file<<'\n';
2794 // Ifile<<"element="<<noindent; at->print(file, l);
2795 // file<<yesindent<<'\n';
2796 std::ostringstream ost;
2797 ost << indn << " element=" << noindent;
2798 at->print(ost, l);
2799 ost << yesindent;
2800 put_one_n(ost);
2801 file << ost.str();
2802 }
2803 file << yesindent;
2804 indn.n -= 2;
2805}
2806
2807// New experimental approach.
2808// give the width of field, which is put in setw().
2809// Whether the array will be printed in single lines
2810// or by columns, is determined by whether 80 symbols are enough
2811void print_DynArr_int_w(std::ostream& file, const DynArr<int>& f, int w);
2812
2813void print_DynArr_float(std::ostream& file, const DynArr<float>& f);
2814void print_DynArr_double(std::ostream& file, const DynArr<double>& f);
2815// ^Identical functions
2816// See AbsArrD for similar function with DoubleAc
2817
2818#define Iprintda_double(file, name) \
2819 file << indn << #name << "=" << noindent; \
2820 print_DynArr_double(file, name);
2821// See AbsArrD for similar function with DoubleAc
2822
2823}
2824
2825#endif
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define mfunnamep(string)
Definition: FunNameStack.h:49
#define spexit(stream)
Definition: FunNameStack.h:256
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:163
IndexingProvider(DynArr< D > &farr, long fq_deref_ind, long fcurrent_pos)
Definition: AbsArr.h:1568
IndexingProvider< D > & operator[](long n)
Definition: AbsArr.h:1602
const IndexingProvider< D > & operator[](long n) const
Definition: AbsArr.h:1627
D & operator=(const D &f)
Definition: AbsArr.h:1585
const T & ac(long i1, long i2, long i3) const
Definition: AbsArr.h:2074
int confirm_ind(const DynLinArr< long > &ind)
Definition: AbsArr.h:2175
DynArr(long fqel1, long fqel2, long fqel3, T *val=NULL)
Definition: AbsArr.h:1442
const DynLinArr< T > & get_el(void) const
Definition: AbsArr.h:2153
void clear(void)
Definition: AbsArr.h:2169
const T & acp(const DynLinArr< long > &ind) const
Definition: AbsArr.h:1844
DynArr(const DynArr< T > &f)
Definition: AbsArr.h:1506
DynArr(const DynLinArr< long > &fqel, T *val)
Definition: AbsArr.h:1490
DynArr(long fqel, T val, ArgInterp_Val)
Definition: AbsArr.h:1383
T & ac(long i1, long i2)
Definition: AbsArr.h:1890
T & acu(long i1, long i2)
Definition: AbsArr.h:2024
const T & ac(const DynLinArr< long > &ind) const
Definition: AbsArr.h:1764
DynArr(long fqel, const T *ar, ArgInterp_Arr)
Definition: AbsArr.h:1394
T & acu(long i1)
Definition: AbsArr.h:1720
int confirm_ind_ext(const DynLinArr< long > &ind)
Definition: AbsArr.h:2176
IndexingProvider< T > operator[](long n)
Definition: AbsArr.h:1657
virtual DynArr * copy() const
Definition: AbsArr.h:2206
const DynLinArr< long > & get_cum_qel(void) const
Definition: AbsArr.h:2156
void check(void) const
Definition: AbsArr.h:2192
const T & ac(long i) const
Definition: AbsArr.h:1710
T & ac(long i)
Definition: AbsArr.h:1700
DynArr(const DynArr< T > &f, Pilfer)
Definition: AbsArr.h:1512
DynArr(long fqel1, long fqel2, long fqel3, long fqel4, T *val=NULL)
Definition: AbsArr.h:1456
const T & acu(long i1) const
Definition: AbsArr.h:1724
void pilfer(const DynArr< T > &f)
Definition: AbsArr.h:1519
DynArr< T > & operator=(const DynArr< T > &f)
Definition: AbsArr.h:2291
DynArr(long fqel1, long fqel2, T val, ArgInterp_Val)
Definition: AbsArr.h:1426
long get_qel_lin(void) const
Definition: AbsArr.h:2114
T & ac_lin(long n)
Definition: AbsArr.h:2117
const IndexingProvider< T > operator[](long n) const
Definition: AbsArr.h:1678
void assignAll(const T &val)
Definition: AbsArr.h:2463
const T & acu(const DynLinArr< long > &ind) const
Definition: AbsArr.h:1882
friend void apply2(DynArr< P > &ar, void(*fun1)(P &f, void(*fun21)(X &f)), void(*fun2)(X &f))
DynArr< T > & operator=(const DynArr< D > &f)
Definition: AbsArr.h:2309
const T & acu(long i1, long i2) const
Definition: AbsArr.h:2029
DynArr(void)
Definition: AbsArr.h:1370
const T & ac(long i1, long i2) const
Definition: AbsArr.h:1957
const DynLinArr< long > & get_qel(void) const
Definition: AbsArr.h:2152
friend void apply1(DynArr< P > &ar, void(*fun)(P &f))
DynArr(long fqel, T *val=NULL)
Definition: AbsArr.h:1372
DynArr(long fqel1, long fqel2, T *val=NULL)
Definition: AbsArr.h:1412
DynArr(const DynLinArr< long > &fqel, T val, ArgInterp_Val)
Definition: AbsArr.h:1476
DynArr< T > top(void)
Definition: AbsArr.h:2521
void put_qel(T *val=NULL)
Definition: AbsArr.h:2392
T & acu_lin(long n)
Definition: AbsArr.h:2146
T & ac(long i1, long i2, long i3)
Definition: AbsArr.h:2034
int get_s_non_emplty(void) const
Definition: AbsArr.h:2197
long get_qdim(void) const
Definition: AbsArr.h:2151
virtual ~DynArr()
Definition: AbsArr.h:2207
T & ac(const DynLinArr< long > &ind)
Definition: AbsArr.h:1730
void pass(long q, DynLinArr< long > fqel, DynLinArr< long > fcum_qel, T *fel)
Definition: AbsArr.h:1550
DynArr(const DynLinArr< T > &f)
Definition: AbsArr.h:1404
const T & acu_lin(long n) const
Definition: AbsArr.h:2147
T & acu(const DynLinArr< long > &ind)
Definition: AbsArr.h:1875
const T & ac_lin(long n) const
Definition: AbsArr.h:2131
T & acp(const DynLinArr< long > &ind)
Definition: AbsArr.h:1809
const T & last_el(void) const
Definition: AbsArr.h:269
DynLinArr(const DynLinArr< T > &f, Pilfer)
Definition: AbsArr.h:192
virtual DynLinArr * copy() const
Definition: AbsArr.h:417
void clear(void)
Definition: AbsArr.h:313
void sort_select_decreasing(DynLinArr< long > &sort_ind, long q_to_sort=0) const
Definition: AbsArr.h:806
DynLinArr(long fqel, const T *ar, ArgInterp_Arr)
Definition: AbsArr.h:146
long get_qel(void) const
Definition: AbsArr.h:283
void put_qel(long fqel)
Definition: AbsArr.h:527
DynLinArr< T > & operator=(const DynLinArr< D > &f)
Definition: AbsArr.h:494
T & acu(long n)
Definition: AbsArr.h:247
void sort(DynLinArr< long > &sort_ind, long q_to_sort=0) const
Definition: AbsArr.h:686
const T & acu(long n) const
Definition: AbsArr.h:251
void put_qel(long fqel, const T *val, ArgInterp_SingleAdr t)
Definition: AbsArr.h:569
DynLinArr(long fqel, const T &val)
Definition: AbsArr.h:126
void pilfer(const DynLinArr< T > &f)
Definition: AbsArr.h:315
friend void apply1(DynLinArr< P > &ar, void(*fun)(P &f))
void pass(long fqel, T *fel)
Definition: AbsArr.h:183
DynLinArr(const DynArr< T > &f)
Definition: AbsArr.h:2537
void increment(const T &val)
Definition: AbsArr.h:308
void sort(long q_to_sort=0)
Definition: AbsArr.h:625
void check(void) const
Definition: AbsArr.h:433
void increment(const T *val=NULL)
Definition: AbsArr.h:303
DynLinArr(const DynArr< T > &f, int n_of_dim, long roc_number)
Definition: AbsArr.h:2559
T & operator[](long n)
Definition: AbsArr.h:221
friend void apply2(DynLinArr< P > &ar, void(*fun1)(P &f, void(*fun21)(X &f)), void(*fun2)(X &f))
void put_qel(long fqel, const T &val)
Definition: AbsArr.h:300
DynLinArr & assignAll(const T &f)
Definition: AbsArr.h:207
DynLinArr< T > & operator=(const DynLinArr< T > &f)
Definition: AbsArr.h:468
void sort_select_increasing(DynLinArr< long > &sort_ind, long q_to_sort=0) const
Definition: AbsArr.h:742
const T & operator[](long n) const
Definition: AbsArr.h:234
T & last_el(void)
Definition: AbsArr.h:255
virtual ~DynLinArr()
Definition: AbsArr.h:406
DynLinArr(long fqel)
Definition: AbsArr.h:106
DynLinArr< T > & assignAll1(const X &f)
Definition: AbsArr.h:213
DynLinArr(const DynLinArr< T > &f)
Definition: AbsArr.h:516
DynArr< T > top(void)
Definition: AbsArr.h:2511
DynLinArr(void)
Definition: AbsArr.h:105
IterDynArr(const DynArr< T > *fdar)
Definition: AbsArr.h:2345
T * current(void)
Definition: AbsArr.h:2362
const DynLinArr< long > & get_ncur(void) const
Definition: AbsArr.h:2382
T * less(void)
Definition: AbsArr.h:2373
T * more(void)
Definition: AbsArr.h:2354
IterDynLinArr(DynLinArr< T > *fdar)
Definition: AbsArr.h:1259
T * less(void)
Definition: AbsArr.h:1273
T * current(void)
Definition: AbsArr.h:1267
T * more(void)
Definition: AbsArr.h:1260
long get_ncur(void)
Definition: AbsArr.h:1281
virtual void print(std::ostream &file, int l=1) const
Definition: AbsPtr.cpp:152
std::istream * istrm
Definition: definp.h:34
#define DEFINPAP(name)
Definition: definp.h:78
Definition: BGMesh.cpp:6
void print_DynArr_double(std::ostream &file, const DynArr< double > &f)
Definition: AbsArr.cpp:315
void print_DynLinArr(std::ostream &file, const DynLinArr< T > &f, int l)
Definition: AbsArr.h:1098
DynLinArr< T > merge(const DynLinArr< T > &fd1, long qfd1, const DynLinArr< T > &fd2, long qfd2)
Definition: AbsArr.h:1346
int s_short_output
Definition: prstream.cpp:25
void print_DynArr(std::ostream &file, const DynArr< T > &f, int l)
Definition: AbsArr.h:2769
std::istream & operator>>(std::istream &file, EqualStepCoorMesh< T > &f)
Definition: tline.h:229
std::ostream & noindent(std::ostream &f)
Definition: prstream.cpp:17
long max_qel_DynLinArr
Definition: AbsArr.cpp:17
void apply2(DynLinArr< T > &ar, void(*fun1)(T &f, void(*fun21)(X &f)), void(*fun2)(X &f))
Definition: AbsArr.h:427
void print_DynArr_float(std::ostream &file, const DynArr< float > &f)
Definition: AbsArr.cpp:367
void print_DynLinArr_int_double3(std::ostream &file, const DynLinArr< int > &iar, const DynLinArr< double > &dar1, const DynLinArr< double > &dar2, const DynLinArr< double > &dar3)
Definition: AbsArr.cpp:174
int operator!=(manip_absvol_treeid &tid1, manip_absvol_treeid &tid2)
Definition: volume.h:61
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:37
Pilfer
Definition: AbsPtr.h:184
@ steal
Definition: AbsPtr.h:185
int ifequal(const DynLinArr< T > &fd1, const DynLinArr< T > &fd2, long qfirst=-1)
Definition: AbsArr.h:1306
const int pq_arrelem_in_line
Definition: AbsArr.h:1177
void print_DynLinArr_long(std::ostream &file, const DynLinArr< long > &f)
Definition: AbsArr.cpp:37
void print_DynLinArr_int_double(std::ostream &file, const DynLinArr< int > &iar, const DynLinArr< double > &dar)
Definition: AbsArr.cpp:141
int find_prev_comb(const DynLinArr< long > &qel, DynLinArr< long > &f)
Definition: AbsArr.cpp:501
void print_DynLinArr_double2(std::ostream &file, const DynLinArr< double > &f1, const DynLinArr< double > &f2)
Definition: AbsArr.cpp:97
int gconfirm_ind_ext(const DynLinArr< long > &qel, const DynLinArr< long > &ind)
Definition: AbsArr.cpp:433
void put_one_n(std::ostringstream &ost)
Definition: String.h:73
void print_DynLinArr_float(std::ostream &file, const DynLinArr< float > &f)
Definition: AbsArr.cpp:57
int operator==(const circumf &f1, const circumf &f2)
Definition: circumf.cpp:34
void apply1(DynLinArr< T > &ar, void(*fun)(T &f))
Definition: AbsArr.h:422
void copy_DynLinArr(const T &s, X &d)
Definition: AbsArr.h:1215
long append(const T &t, DynLinArr< T > &dla, long &qael, T *tempt=NULL, long new_qel=0)
Definition: AbsArr.h:951
long set_position(const std::string &word, std::istream &istrm, int s_rewind, int s_req_sep)
Definition: definp.cpp:23
int gconfirm_ind(const DynLinArr< long > &qel, const DynLinArr< long > &ind)
Definition: AbsArr.cpp:418
void print_DynLinArr_double(std::ostream &file, const DynLinArr< double > &f)
Definition: AbsArr.cpp:77
void print_DynArr_int_w(std::ostream &file, const DynArr< int > &f, int w)
Definition: AbsArr.cpp:225
void convert_DynLinArr(const T &s, X &d)
Definition: AbsArr.h:1229
void print_adr_DynLinArr(std::ostream &file, const DynLinArr< T > &f, int l, long q)
Definition: AbsArr.h:1148
int find_next_comb(const DynLinArr< long > &qel, DynLinArr< long > &f)
Definition: AbsArr.cpp:450
int find_next_comb_not_less(const DynLinArr< long > &qel, DynLinArr< long > &f)
Definition: AbsArr.cpp:483
void definp_any_par(T &inp, const std::string &word, const definp_endpar &dep, int fs_short=0)
Definition: definp.h:55
void assignAll_1(DynLinArr< T > &f, const T1 &ft)
Definition: AbsArr.h:1248
void convert_DynArr(const DynArr< T > &s, DynArr< X > &d)
Definition: AbsArr.h:2495
int apeq_mant(const T &x1, const T &x2, T prec)
Definition: minmax.h:55
indentation indn
Definition: prstream.cpp:15
void copy_DynArr(const DynArr< T > &s, DynArr< X > &d)
Definition: AbsArr.h:2478
void print_DynLinArr_int(std::ostream &file, const DynLinArr< int > &f)
Definition: AbsArr.cpp:19
std::ostream & yesindent(std::ostream &f)
Definition: prstream.cpp:21
DynLinArr< long > qel_communicat
Definition: AbsArr.cpp:519
void put_qel_1(DynLinArr< T > &f, long fq)
Definition: AbsArr.h:1239
#define mcout
Definition: prstream.h:126
#define Iprint3n(file, name1, name2, name3)
Definition: prstream.h:232
#define Ifile
Definition: prstream.h:195
#define mcerr
Definition: prstream.h:128
#define Iprintn(file, name)
Definition: prstream.h:204
#define Iprint2n(file, name1, name2)
Definition: prstream.h:219