Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/general/array.hpp
3206 views
1
#ifndef FILE_ARRAY
2
#define FILE_ARRAY
3
4
/**************************************************************************/
5
/* File: array.hpp */
6
/* Author: Joachim Schoeberl */
7
/* Date: 01. Jun. 95 */
8
/**************************************************************************/
9
10
11
12
13
// template <class T, int B1, int B2> class IndirectArray;
14
15
16
17
/**
18
A simple array container.
19
Array represented by size and data-pointer.
20
No memory allocation and deallocation, must be provided by user.
21
Helper functions for printing.
22
Optional range check by macro RANGE_CHECK
23
*/
24
25
template <class T, int BASE = 0>
26
class FlatArray
27
{
28
protected:
29
/// the size
30
int size;
31
/// the data
32
T * data;
33
public:
34
35
/// provide size and memory
36
FlatArray (int asize, T * adata)
37
: size(asize), data(adata) { ; }
38
39
/// the size
40
int Size() const { return size; }
41
42
int Begin() const { return BASE; }
43
int End() const { return size+BASE; }
44
45
/*
46
/// access array.
47
T & operator[] (int i)
48
{
49
#ifdef DEBUG
50
if (i-BASE < 0 || i-BASE >= size)
51
cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl;
52
#endif
53
54
return data[i-BASE];
55
}
56
*/
57
58
/// Access array. BASE-based
59
T & operator[] (int i) const
60
{
61
#ifdef DEBUG
62
if (i-BASE < 0 || i-BASE >= size)
63
cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl;
64
#endif
65
66
return data[i-BASE];
67
}
68
69
/*
70
template <int B2>
71
IndirectArray<T, BASE, B2> operator[] (const FlatArray<int, B2> & ind)
72
{ return IndirectArray<T, BASE, B2> (*this, ind); }
73
*/
74
75
/// Access array, one-based (old fashioned)
76
T & Elem (int i)
77
{
78
#ifdef DEBUG
79
if (i < 1 || i > size)
80
cout << "ARRAY<" << typeid(T).name()
81
<< ">::Elem out of range, i = " << i
82
<< ", s = " << size << endl;
83
#endif
84
85
return ((T*)data)[i-1];
86
}
87
88
/// Access array, one-based (old fashioned)
89
const T & Get (int i) const
90
{
91
#ifdef DEBUG
92
if (i < 1 || i > size)
93
cout << "ARRAY<" << typeid(T).name() << ">::Get out of range, i = " << i
94
<< ", s = " << size << endl;
95
#endif
96
97
return ((const T*)data)[i-1];
98
}
99
100
/// Access array, one-based (old fashioned)
101
void Set (int i, const T & el)
102
{
103
#ifdef DEBUG
104
if (i < 1 || i > size)
105
cout << "ARRAY<" << typeid(T).name() << ">::Set out of range, i = " << i
106
<< ", s = " << size << endl;
107
#endif
108
109
((T*)data)[i-1] = el;
110
}
111
112
113
114
/// access first element
115
T & First () const
116
{
117
return data[0];
118
}
119
120
121
/// access last element. check by macro CHECK_RANGE
122
T & Last () const
123
{
124
return data[size-1];
125
}
126
127
/// Fill array with value val
128
FlatArray & operator= (const T & val)
129
{
130
for (int i = 0; i < size; i++)
131
data[i] = val;
132
return *this;
133
}
134
135
/// takes range starting from position start of end-start elements
136
const FlatArray<T> Range (int start, int end)
137
{
138
return FlatArray<T> (end-start, data+start);
139
}
140
141
/// first position of element elem, returns -1 if element not contained in array
142
int Pos(const T & elem) const
143
{
144
int pos = -1;
145
for(int i=0; pos==-1 && i < this->size; i++)
146
if(elem == data[i]) pos = i;
147
return pos;
148
}
149
150
/// does the array contain element elem ?
151
bool Contains(const T & elem) const
152
{
153
return ( Pos(elem) >= 0 );
154
}
155
};
156
157
158
159
// print array
160
template <class T, int BASE>
161
inline ostream & operator<< (ostream & s, const FlatArray<T,BASE> & a)
162
{
163
for (int i = a.Begin(); i < a.End(); i++)
164
s << i << ": " << a[i] << endl;
165
return s;
166
}
167
168
169
170
/**
171
Dynamic array container.
172
173
ARRAY<T> is an automatically increasing array container.
174
The allocated memory doubles on overflow.
175
Either the container takes care of memory allocation and deallocation,
176
or the user provides one block of data.
177
*/
178
template <class T, int BASE = 0>
179
class ARRAY : public FlatArray<T, BASE>
180
{
181
protected:
182
/// physical size of array
183
int allocsize;
184
/// memory is responsibility of container
185
bool ownmem;
186
187
public:
188
189
/// Generate array of logical and physical size asize
190
explicit ARRAY(int asize = 0)
191
: FlatArray<T, BASE> (asize, asize ? new T[asize] : 0)
192
{
193
allocsize = asize;
194
ownmem = 1;
195
}
196
197
/// Generate array in user data
198
ARRAY(int asize, T* adata)
199
: FlatArray<T, BASE> (asize, adata)
200
{
201
allocsize = asize;
202
ownmem = 0;
203
}
204
205
/// array copy
206
explicit ARRAY (const ARRAY<T> & a2)
207
: FlatArray<T, BASE> (a2.Size(), a2.Size() ? new T[a2.Size()] : 0)
208
{
209
allocsize = this->size;
210
ownmem = 1;
211
for (int i = BASE; i < this->size+BASE; i++)
212
(*this)[i] = a2[i];
213
}
214
215
216
217
/// if responsible, deletes memory
218
~ARRAY()
219
{
220
if (ownmem)
221
delete [] this->data;
222
}
223
224
/// Change logical size. If necessary, do reallocation. Keeps contents.
225
void SetSize(int nsize)
226
{
227
if (nsize > allocsize)
228
ReSize (nsize);
229
this->size = nsize;
230
}
231
232
/// Change physical size. Keeps logical size. Keeps contents.
233
void SetAllocSize (int nallocsize)
234
{
235
if (nallocsize > allocsize)
236
ReSize (nallocsize);
237
}
238
239
240
/// Add element at end of array. reallocation if necessary.
241
int Append (const T & el)
242
{
243
if (this->size == allocsize)
244
ReSize (this->size+1);
245
this->data[this->size] = el;
246
this->size++;
247
return this->size;
248
}
249
250
template <typename T2, int B2>
251
void Append (FlatArray<T2, B2> a2)
252
{
253
if (this->size+a2.Size() > allocsize)
254
ReSize (this->size+a2.Size());
255
for (int i = 0; i < a2.Size(); i++)
256
this->data[this->size+i] = a2[i+B2];
257
this->size += a2.Size();
258
}
259
260
261
/*
262
template <int B1, int B2>
263
void Append (const IndirectArray<T,B1,B2> & a2)
264
{
265
if (this->size+a2.Size() > allocsize)
266
ReSize (this->size+a2.Size());
267
for (int i = 0; i < a2.Size(); i++)
268
this->data[this->size+i] = a2[i+B2];
269
this->size += a2.Size();
270
}
271
*/
272
273
/// Delete element i (0-based). Move last element to position i.
274
void Delete (int i)
275
{
276
#ifdef CHECK_ARRAY_RANGE
277
RangeCheck (i+1);
278
#endif
279
280
this->data[i] = this->data[this->size-1];
281
this->size--;
282
// DeleteElement (i+1);
283
}
284
285
286
/// Delete element i (1-based). Move last element to position i.
287
void DeleteElement (int i)
288
{
289
#ifdef CHECK_ARRAY_RANGE
290
RangeCheck (i);
291
#endif
292
293
this->data[i-1] = this->data[this->size-1];
294
this->size--;
295
}
296
297
/// Delete last element.
298
void DeleteLast ()
299
{
300
this->size--;
301
}
302
303
/// Deallocate memory
304
void DeleteAll ()
305
{
306
if (ownmem)
307
delete [] this->data;
308
this->data = 0;
309
this->size = allocsize = 0;
310
}
311
312
/// Fill array with val
313
ARRAY & operator= (const T & val)
314
{
315
FlatArray<T, BASE>::operator= (val);
316
return *this;
317
}
318
319
/// array copy
320
ARRAY & operator= (const ARRAY & a2)
321
{
322
SetSize (a2.Size());
323
for (int i = BASE; i < this->size+BASE; i++)
324
(*this)[i] = a2[i];
325
return *this;
326
}
327
328
/// array copy
329
ARRAY & operator= (const FlatArray<T> & a2)
330
{
331
SetSize (a2.Size());
332
for (int i = BASE; i < this->size+BASE; i++)
333
(*this)[i] = a2[i];
334
return *this;
335
}
336
337
338
private:
339
340
/// resize array, at least to size minsize. copy contents
341
void ReSize (int minsize)
342
{
343
int nsize = 2 * allocsize;
344
if (nsize < minsize) nsize = minsize;
345
346
if (this->data)
347
{
348
T * p = new T[nsize];
349
350
int mins = (nsize < this->size) ? nsize : this->size;
351
memcpy (p, this->data, mins * sizeof(T));
352
353
if (ownmem)
354
delete [] this->data;
355
ownmem = 1;
356
this->data = p;
357
}
358
else
359
{
360
this->data = new T[nsize];
361
ownmem = 1;
362
}
363
364
allocsize = nsize;
365
}
366
};
367
368
369
370
template <class T, int S>
371
class ArrayMem : public ARRAY<T>
372
{
373
// T mem[S]; // Intel C++ calls dummy constructor
374
// char mem[S*sizeof(T)];
375
double mem[(S*sizeof(T)+7) / 8];
376
public:
377
/// Generate array of logical and physical size asize
378
explicit ArrayMem(int asize = 0)
379
: ARRAY<T> (S, static_cast<T*> (static_cast<void*>(&mem[0])))
380
{
381
this->SetSize (asize);
382
}
383
384
ArrayMem & operator= (const T & val)
385
{
386
ARRAY<T>::operator= (val);
387
return *this;
388
}
389
};
390
391
392
393
394
395
/*
396
template <class T, int B1, int B2>
397
class IndirectArray
398
{
399
const FlatArray<T, B1> & array;
400
const FlatArray<int, B2> & ia;
401
402
public:
403
IndirectArray (const FlatArray<T,B1> & aa, const FlatArray<int, B2> & aia)
404
: array(aa), ia(aia) { ; }
405
int Size() const { return ia.Size(); }
406
const T & operator[] (int i) const { return array[ia[i]]; }
407
};
408
*/
409
410
411
412
413
414
415
416
417
418
419
///
420
template <class T, int BASE = 0>
421
class MoveableArray
422
{
423
int size;
424
int allocsize;
425
MoveableMem<T> data;
426
427
public:
428
429
MoveableArray()
430
{
431
size = allocsize = 0;
432
data.SetName ("MoveableArray");
433
}
434
435
MoveableArray(int asize)
436
: size(asize), allocsize(asize), data(asize)
437
{ ; }
438
439
~MoveableArray () { ; }
440
441
int Size() const { return size; }
442
443
void SetSize(int nsize)
444
{
445
if (nsize > allocsize)
446
{
447
data.ReAlloc (nsize);
448
allocsize = nsize;
449
}
450
size = nsize;
451
}
452
453
void SetAllocSize (int nallocsize)
454
{
455
data.ReAlloc (nallocsize);
456
allocsize = nallocsize;
457
}
458
459
///
460
T & operator[] (int i)
461
{ return ((T*)data)[i-BASE]; }
462
463
///
464
const T & operator[] (int i) const
465
{ return ((const T*)data)[i-BASE]; }
466
467
///
468
T & Elem (int i)
469
{ return ((T*)data)[i-1]; }
470
471
///
472
const T & Get (int i) const
473
{ return ((const T*)data)[i-1]; }
474
475
///
476
void Set (int i, const T & el)
477
{ ((T*)data)[i-1] = el; }
478
479
///
480
T & Last ()
481
{ return ((T*)data)[size-1]; }
482
483
///
484
const T & Last () const
485
{ return ((const T*)data)[size-1]; }
486
487
///
488
int Append (const T & el)
489
{
490
if (size == allocsize)
491
{
492
SetAllocSize (2*allocsize+1);
493
}
494
((T*)data)[size] = el;
495
size++;
496
return size;
497
}
498
499
///
500
void Delete (int i)
501
{
502
DeleteElement (i+1);
503
}
504
505
///
506
void DeleteElement (int i)
507
{
508
((T*)data)[i-1] = ((T*)data)[size-1];
509
size--;
510
}
511
512
///
513
void DeleteLast ()
514
{ size--; }
515
516
///
517
void DeleteAll ()
518
{
519
size = allocsize = 0;
520
data.Free();
521
}
522
523
///
524
void PrintMemInfo (ostream & ost) const
525
{
526
ost << Size() << " elements of size " << sizeof(T) << " = "
527
<< Size() * sizeof(T) << endl;
528
}
529
530
MoveableArray & operator= (const T & el)
531
{
532
for (int i = 0; i < size; i++)
533
((T*)data)[i] = el;
534
return *this;
535
}
536
537
538
MoveableArray & Copy (const MoveableArray & a2)
539
{
540
SetSize (a2.Size());
541
for (int i = 0; i < this->size; i++)
542
data[i] = a2.data[i];
543
return *this;
544
}
545
546
/// array copy
547
MoveableArray & operator= (const MoveableArray & a2)
548
{
549
return Copy(a2);
550
}
551
552
553
void SetName (const char * aname)
554
{
555
data.SetName(aname);
556
}
557
private:
558
///
559
//MoveableArray & operator= (MoveableArray &); //???
560
///
561
//MoveableArray (const MoveableArray &); //???
562
};
563
564
565
template <class T>
566
inline ostream & operator<< (ostream & ost, MoveableArray<T> & a)
567
{
568
for (int i = 0; i < a.Size(); i++)
569
ost << i << ": " << a[i] << endl;
570
return ost;
571
}
572
573
574
/// bubble sort array
575
template <class T>
576
inline void BubbleSort (const FlatArray<T> & data)
577
{
578
T hv;
579
for (int i = 0; i < data.Size(); i++)
580
for (int j = i+1; j < data.Size(); j++)
581
if (data[i] > data[j])
582
{
583
hv = data[i];
584
data[i] = data[j];
585
data[j] = hv;
586
}
587
}
588
/// bubble sort array
589
template <class T, class S>
590
inline void BubbleSort (FlatArray<T> & data, FlatArray<S> & slave)
591
{
592
T hv;
593
S hvs;
594
for (int i = 0; i < data.Size(); i++)
595
for (int j = i+1; j < data.Size(); j++)
596
if (data[i] > data[j])
597
{
598
hv = data[i];
599
data[i] = data[j];
600
data[j] = hv;
601
602
hvs = slave[i];
603
slave[i] = slave[j];
604
slave[j] = hvs;
605
}
606
}
607
608
609
template <class T>
610
void Intersection (const FlatArray<T> & in1, const FlatArray<T> & in2,
611
ARRAY<T> & out)
612
{
613
out.SetSize(0);
614
for(int i=0; i<in1.Size(); i++)
615
if(in2.Contains(in1[i]))
616
out.Append(in1[i]);
617
}
618
template <class T>
619
void Intersection (const FlatArray<T> & in1, const FlatArray<T> & in2, const FlatArray<T> & in3,
620
ARRAY<T> & out)
621
{
622
out.SetSize(0);
623
for(int i=0; i<in1.Size(); i++)
624
if(in2.Contains(in1[i]) && in3.Contains(in1[i]))
625
out.Append(in1[i]);
626
}
627
628
629
630
631
#endif
632
633
634