Path: blob/devel/ElmerGUI/netgen/libsrc/general/array.hpp
3206 views
#ifndef FILE_ARRAY1#define FILE_ARRAY23/**************************************************************************/4/* File: array.hpp */5/* Author: Joachim Schoeberl */6/* Date: 01. Jun. 95 */7/**************************************************************************/89101112// template <class T, int B1, int B2> class IndirectArray;13141516/**17A simple array container.18Array represented by size and data-pointer.19No memory allocation and deallocation, must be provided by user.20Helper functions for printing.21Optional range check by macro RANGE_CHECK22*/2324template <class T, int BASE = 0>25class FlatArray26{27protected:28/// the size29int size;30/// the data31T * data;32public:3334/// provide size and memory35FlatArray (int asize, T * adata)36: size(asize), data(adata) { ; }3738/// the size39int Size() const { return size; }4041int Begin() const { return BASE; }42int End() const { return size+BASE; }4344/*45/// access array.46T & operator[] (int i)47{48#ifdef DEBUG49if (i-BASE < 0 || i-BASE >= size)50cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl;51#endif5253return data[i-BASE];54}55*/5657/// Access array. BASE-based58T & operator[] (int i) const59{60#ifdef DEBUG61if (i-BASE < 0 || i-BASE >= size)62cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl;63#endif6465return data[i-BASE];66}6768/*69template <int B2>70IndirectArray<T, BASE, B2> operator[] (const FlatArray<int, B2> & ind)71{ return IndirectArray<T, BASE, B2> (*this, ind); }72*/7374/// Access array, one-based (old fashioned)75T & Elem (int i)76{77#ifdef DEBUG78if (i < 1 || i > size)79cout << "ARRAY<" << typeid(T).name()80<< ">::Elem out of range, i = " << i81<< ", s = " << size << endl;82#endif8384return ((T*)data)[i-1];85}8687/// Access array, one-based (old fashioned)88const T & Get (int i) const89{90#ifdef DEBUG91if (i < 1 || i > size)92cout << "ARRAY<" << typeid(T).name() << ">::Get out of range, i = " << i93<< ", s = " << size << endl;94#endif9596return ((const T*)data)[i-1];97}9899/// Access array, one-based (old fashioned)100void Set (int i, const T & el)101{102#ifdef DEBUG103if (i < 1 || i > size)104cout << "ARRAY<" << typeid(T).name() << ">::Set out of range, i = " << i105<< ", s = " << size << endl;106#endif107108((T*)data)[i-1] = el;109}110111112113/// access first element114T & First () const115{116return data[0];117}118119120/// access last element. check by macro CHECK_RANGE121T & Last () const122{123return data[size-1];124}125126/// Fill array with value val127FlatArray & operator= (const T & val)128{129for (int i = 0; i < size; i++)130data[i] = val;131return *this;132}133134/// takes range starting from position start of end-start elements135const FlatArray<T> Range (int start, int end)136{137return FlatArray<T> (end-start, data+start);138}139140/// first position of element elem, returns -1 if element not contained in array141int Pos(const T & elem) const142{143int pos = -1;144for(int i=0; pos==-1 && i < this->size; i++)145if(elem == data[i]) pos = i;146return pos;147}148149/// does the array contain element elem ?150bool Contains(const T & elem) const151{152return ( Pos(elem) >= 0 );153}154};155156157158// print array159template <class T, int BASE>160inline ostream & operator<< (ostream & s, const FlatArray<T,BASE> & a)161{162for (int i = a.Begin(); i < a.End(); i++)163s << i << ": " << a[i] << endl;164return s;165}166167168169/**170Dynamic array container.171172ARRAY<T> is an automatically increasing array container.173The allocated memory doubles on overflow.174Either the container takes care of memory allocation and deallocation,175or the user provides one block of data.176*/177template <class T, int BASE = 0>178class ARRAY : public FlatArray<T, BASE>179{180protected:181/// physical size of array182int allocsize;183/// memory is responsibility of container184bool ownmem;185186public:187188/// Generate array of logical and physical size asize189explicit ARRAY(int asize = 0)190: FlatArray<T, BASE> (asize, asize ? new T[asize] : 0)191{192allocsize = asize;193ownmem = 1;194}195196/// Generate array in user data197ARRAY(int asize, T* adata)198: FlatArray<T, BASE> (asize, adata)199{200allocsize = asize;201ownmem = 0;202}203204/// array copy205explicit ARRAY (const ARRAY<T> & a2)206: FlatArray<T, BASE> (a2.Size(), a2.Size() ? new T[a2.Size()] : 0)207{208allocsize = this->size;209ownmem = 1;210for (int i = BASE; i < this->size+BASE; i++)211(*this)[i] = a2[i];212}213214215216/// if responsible, deletes memory217~ARRAY()218{219if (ownmem)220delete [] this->data;221}222223/// Change logical size. If necessary, do reallocation. Keeps contents.224void SetSize(int nsize)225{226if (nsize > allocsize)227ReSize (nsize);228this->size = nsize;229}230231/// Change physical size. Keeps logical size. Keeps contents.232void SetAllocSize (int nallocsize)233{234if (nallocsize > allocsize)235ReSize (nallocsize);236}237238239/// Add element at end of array. reallocation if necessary.240int Append (const T & el)241{242if (this->size == allocsize)243ReSize (this->size+1);244this->data[this->size] = el;245this->size++;246return this->size;247}248249template <typename T2, int B2>250void Append (FlatArray<T2, B2> a2)251{252if (this->size+a2.Size() > allocsize)253ReSize (this->size+a2.Size());254for (int i = 0; i < a2.Size(); i++)255this->data[this->size+i] = a2[i+B2];256this->size += a2.Size();257}258259260/*261template <int B1, int B2>262void Append (const IndirectArray<T,B1,B2> & a2)263{264if (this->size+a2.Size() > allocsize)265ReSize (this->size+a2.Size());266for (int i = 0; i < a2.Size(); i++)267this->data[this->size+i] = a2[i+B2];268this->size += a2.Size();269}270*/271272/// Delete element i (0-based). Move last element to position i.273void Delete (int i)274{275#ifdef CHECK_ARRAY_RANGE276RangeCheck (i+1);277#endif278279this->data[i] = this->data[this->size-1];280this->size--;281// DeleteElement (i+1);282}283284285/// Delete element i (1-based). Move last element to position i.286void DeleteElement (int i)287{288#ifdef CHECK_ARRAY_RANGE289RangeCheck (i);290#endif291292this->data[i-1] = this->data[this->size-1];293this->size--;294}295296/// Delete last element.297void DeleteLast ()298{299this->size--;300}301302/// Deallocate memory303void DeleteAll ()304{305if (ownmem)306delete [] this->data;307this->data = 0;308this->size = allocsize = 0;309}310311/// Fill array with val312ARRAY & operator= (const T & val)313{314FlatArray<T, BASE>::operator= (val);315return *this;316}317318/// array copy319ARRAY & operator= (const ARRAY & a2)320{321SetSize (a2.Size());322for (int i = BASE; i < this->size+BASE; i++)323(*this)[i] = a2[i];324return *this;325}326327/// array copy328ARRAY & operator= (const FlatArray<T> & a2)329{330SetSize (a2.Size());331for (int i = BASE; i < this->size+BASE; i++)332(*this)[i] = a2[i];333return *this;334}335336337private:338339/// resize array, at least to size minsize. copy contents340void ReSize (int minsize)341{342int nsize = 2 * allocsize;343if (nsize < minsize) nsize = minsize;344345if (this->data)346{347T * p = new T[nsize];348349int mins = (nsize < this->size) ? nsize : this->size;350memcpy (p, this->data, mins * sizeof(T));351352if (ownmem)353delete [] this->data;354ownmem = 1;355this->data = p;356}357else358{359this->data = new T[nsize];360ownmem = 1;361}362363allocsize = nsize;364}365};366367368369template <class T, int S>370class ArrayMem : public ARRAY<T>371{372// T mem[S]; // Intel C++ calls dummy constructor373// char mem[S*sizeof(T)];374double mem[(S*sizeof(T)+7) / 8];375public:376/// Generate array of logical and physical size asize377explicit ArrayMem(int asize = 0)378: ARRAY<T> (S, static_cast<T*> (static_cast<void*>(&mem[0])))379{380this->SetSize (asize);381}382383ArrayMem & operator= (const T & val)384{385ARRAY<T>::operator= (val);386return *this;387}388};389390391392393394/*395template <class T, int B1, int B2>396class IndirectArray397{398const FlatArray<T, B1> & array;399const FlatArray<int, B2> & ia;400401public:402IndirectArray (const FlatArray<T,B1> & aa, const FlatArray<int, B2> & aia)403: array(aa), ia(aia) { ; }404int Size() const { return ia.Size(); }405const T & operator[] (int i) const { return array[ia[i]]; }406};407*/408409410411412413414415416417418///419template <class T, int BASE = 0>420class MoveableArray421{422int size;423int allocsize;424MoveableMem<T> data;425426public:427428MoveableArray()429{430size = allocsize = 0;431data.SetName ("MoveableArray");432}433434MoveableArray(int asize)435: size(asize), allocsize(asize), data(asize)436{ ; }437438~MoveableArray () { ; }439440int Size() const { return size; }441442void SetSize(int nsize)443{444if (nsize > allocsize)445{446data.ReAlloc (nsize);447allocsize = nsize;448}449size = nsize;450}451452void SetAllocSize (int nallocsize)453{454data.ReAlloc (nallocsize);455allocsize = nallocsize;456}457458///459T & operator[] (int i)460{ return ((T*)data)[i-BASE]; }461462///463const T & operator[] (int i) const464{ return ((const T*)data)[i-BASE]; }465466///467T & Elem (int i)468{ return ((T*)data)[i-1]; }469470///471const T & Get (int i) const472{ return ((const T*)data)[i-1]; }473474///475void Set (int i, const T & el)476{ ((T*)data)[i-1] = el; }477478///479T & Last ()480{ return ((T*)data)[size-1]; }481482///483const T & Last () const484{ return ((const T*)data)[size-1]; }485486///487int Append (const T & el)488{489if (size == allocsize)490{491SetAllocSize (2*allocsize+1);492}493((T*)data)[size] = el;494size++;495return size;496}497498///499void Delete (int i)500{501DeleteElement (i+1);502}503504///505void DeleteElement (int i)506{507((T*)data)[i-1] = ((T*)data)[size-1];508size--;509}510511///512void DeleteLast ()513{ size--; }514515///516void DeleteAll ()517{518size = allocsize = 0;519data.Free();520}521522///523void PrintMemInfo (ostream & ost) const524{525ost << Size() << " elements of size " << sizeof(T) << " = "526<< Size() * sizeof(T) << endl;527}528529MoveableArray & operator= (const T & el)530{531for (int i = 0; i < size; i++)532((T*)data)[i] = el;533return *this;534}535536537MoveableArray & Copy (const MoveableArray & a2)538{539SetSize (a2.Size());540for (int i = 0; i < this->size; i++)541data[i] = a2.data[i];542return *this;543}544545/// array copy546MoveableArray & operator= (const MoveableArray & a2)547{548return Copy(a2);549}550551552void SetName (const char * aname)553{554data.SetName(aname);555}556private:557///558//MoveableArray & operator= (MoveableArray &); //???559///560//MoveableArray (const MoveableArray &); //???561};562563564template <class T>565inline ostream & operator<< (ostream & ost, MoveableArray<T> & a)566{567for (int i = 0; i < a.Size(); i++)568ost << i << ": " << a[i] << endl;569return ost;570}571572573/// bubble sort array574template <class T>575inline void BubbleSort (const FlatArray<T> & data)576{577T hv;578for (int i = 0; i < data.Size(); i++)579for (int j = i+1; j < data.Size(); j++)580if (data[i] > data[j])581{582hv = data[i];583data[i] = data[j];584data[j] = hv;585}586}587/// bubble sort array588template <class T, class S>589inline void BubbleSort (FlatArray<T> & data, FlatArray<S> & slave)590{591T hv;592S hvs;593for (int i = 0; i < data.Size(); i++)594for (int j = i+1; j < data.Size(); j++)595if (data[i] > data[j])596{597hv = data[i];598data[i] = data[j];599data[j] = hv;600601hvs = slave[i];602slave[i] = slave[j];603slave[j] = hvs;604}605}606607608template <class T>609void Intersection (const FlatArray<T> & in1, const FlatArray<T> & in2,610ARRAY<T> & out)611{612out.SetSize(0);613for(int i=0; i<in1.Size(); i++)614if(in2.Contains(in1[i]))615out.Append(in1[i]);616}617template <class T>618void Intersection (const FlatArray<T> & in1, const FlatArray<T> & in2, const FlatArray<T> & in3,619ARRAY<T> & out)620{621out.SetSize(0);622for(int i=0; i<in1.Size(); i++)623if(in2.Contains(in1[i]) && in3.Contains(in1[i]))624out.Append(in1[i]);625}626627628629630#endif631632633634