netgen/libsrc/general/array.hpp

803 lines
17 KiB
C++
Raw Normal View History

2009-01-25 17:35:25 +05:00
#ifndef FILE_Array
#define FILE_Array
2009-01-13 04:40:13 +05:00
/**************************************************************************/
/* File: array.hpp */
/* Author: Joachim Schoeberl */
/* Date: 01. Jun. 95 */
/**************************************************************************/
2009-07-20 14:36:36 +06:00
namespace netgen
{
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
// template <class T, int B1, int B2> class IndirectArray;
2013-04-03 02:26:21 +06:00
template <class TA1, class TA2> class IndirectArray;
2009-01-13 04:40:13 +05:00
2014-12-02 18:23:36 +05:00
template <typename TSIZE>
class ArrayRangeIterator
{
TSIZE ind;
public:
ArrayRangeIterator (TSIZE ai) : ind(ai) { ; }
ArrayRangeIterator operator++ (int) { return ind++; }
ArrayRangeIterator operator++ () { return ++ind; }
TSIZE operator*() const { return ind; }
bool operator != (ArrayRangeIterator d2) { return ind != d2.ind; }
};
2018-01-08 20:45:53 +05:00
/// a range of integers
2014-12-02 18:23:36 +05:00
template <typename T>
class T_Range
{
T first, next;
public:
T_Range (T f, T n) : first(f), next(n) {;}
T Size() const { return next-first; }
T operator[] (T i) const { return first+i; }
bool Contains (T i) const { return ((i >= first) && (i < next)); }
ArrayRangeIterator<T> begin() const { return first; }
ArrayRangeIterator<T> end() const { return next; }
};
template <typename T, int BASE = 0, typename TIND = int>
class FlatArray;
template <typename T, int BASE, typename TIND>
class ArrayIterator
{
FlatArray<T,BASE,TIND> ar;
TIND ind;
public:
ArrayIterator (FlatArray<T,BASE,TIND> aar, TIND ai) : ar(aar), ind(ai) { ; }
ArrayIterator operator++ (int) { return ArrayIterator(ar, ind++); }
ArrayIterator operator++ () { return ArrayIterator(ar, ++ind); }
T operator*() const { return ar[ind]; }
T & operator*() { return ar[ind]; }
bool operator != (ArrayIterator d2) { return ind != d2.ind; }
2016-11-15 22:12:51 +05:00
bool operator == (ArrayIterator d2) { return ind == d2.ind; }
2014-12-02 18:23:36 +05:00
};
2009-10-28 05:04:19 +05:00
/**
A simple array container.
Array represented by size and data-pointer.
No memory allocation and deallocation, must be provided by user.
Helper functions for printing.
Optional range check by macro RANGE_CHECK
2009-01-13 04:40:13 +05:00
*/
2014-12-02 18:23:36 +05:00
template <typename T, int BASE, typename TIND>
2009-10-28 05:04:19 +05:00
class FlatArray
{
protected:
/// the size
2018-03-15 23:01:20 +05:00
size_t size;
2009-10-28 05:04:19 +05:00
/// the data
T * data;
public:
2013-04-03 02:26:21 +06:00
typedef T TELEM;
2009-10-28 05:04:19 +05:00
/// provide size and memory
2018-03-15 23:01:20 +05:00
FlatArray (size_t asize, T * adata)
2009-10-28 05:04:19 +05:00
: size(asize), data(adata) { ; }
/// the size
2018-03-15 23:01:20 +05:00
size_t Size() const { return size; }
2009-10-28 05:04:19 +05:00
2014-12-02 18:23:36 +05:00
ArrayIterator<T,BASE,TIND> begin() const
{ return ArrayIterator<T,BASE,TIND> (*this, BASE); }
ArrayIterator<T,BASE,TIND> end() const
{ return ArrayIterator<T,BASE,TIND> (*this, BASE+size); }
2013-04-03 02:26:21 +06:00
TIND Begin() const { return TIND(BASE); }
TIND End() const { return TIND(size+BASE); }
2014-12-02 18:23:36 +05:00
T_Range<TIND> Range() const { return T_Range<TIND>(BASE, size+BASE); }
2009-10-28 05:04:19 +05:00
/// Access array. BASE-based
2013-04-03 02:26:21 +06:00
T & operator[] (TIND i) const
2009-10-28 05:04:19 +05:00
{
2009-01-13 04:40:13 +05:00
#ifdef DEBUG
2009-10-28 05:04:19 +05:00
if (i-BASE < 0 || i-BASE >= size)
cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl;
2009-01-13 04:40:13 +05:00
#endif
2009-10-28 05:04:19 +05:00
return data[i-BASE];
}
2009-01-13 04:40:13 +05:00
2013-04-03 02:26:21 +06:00
template <typename T2, int B2>
IndirectArray<FlatArray, FlatArray<T2,B2> > operator[] (const FlatArray<T2,B2> & ia) const
{
return IndirectArray<FlatArray, FlatArray<T2,B2> > (*this, ia);
}
2009-10-28 05:04:19 +05:00
/// Access array, one-based (old fashioned)
T & Elem (int i)
{
2009-01-13 04:40:13 +05:00
#ifdef DEBUG
2009-10-28 05:04:19 +05:00
if (i < 1 || i > size)
cout << "Array<" << typeid(T).name()
<< ">::Elem out of range, i = " << i
<< ", s = " << size << endl;
2009-01-13 04:40:13 +05:00
#endif
2009-10-28 05:04:19 +05:00
return ((T*)data)[i-1];
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// Access array, one-based (old fashioned)
const T & Get (int i) const
{
2009-01-13 04:40:13 +05:00
#ifdef DEBUG
2009-10-28 05:04:19 +05:00
if (i < 1 || i > size)
cout << "Array<" << typeid(T).name() << ">::Get out of range, i = " << i
<< ", s = " << size << endl;
2009-01-13 04:40:13 +05:00
#endif
2009-10-28 05:04:19 +05:00
return ((const T*)data)[i-1];
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// Access array, one-based (old fashioned)
void Set (int i, const T & el)
{
2009-01-13 04:40:13 +05:00
#ifdef DEBUG
2009-10-28 05:04:19 +05:00
if (i < 1 || i > size)
cout << "Array<" << typeid(T).name() << ">::Set out of range, i = " << i
<< ", s = " << size << endl;
2009-01-13 04:40:13 +05:00
#endif
2009-10-28 05:04:19 +05:00
((T*)data)[i-1] = el;
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// access first element
T & First () const
{
return data[0];
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// access last element. check by macro CHECK_RANGE
T & Last () const
{
return data[size-1];
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// Fill array with value val
FlatArray & operator= (const T & val)
{
for (int i = 0; i < size; i++)
data[i] = val;
return *this;
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// takes range starting from position start of end-start elements
2013-04-03 02:26:21 +06:00
const FlatArray<T> Range (TIND start, TIND end)
2009-10-28 05:04:19 +05:00
{
return FlatArray<T> (end-start, data+start);
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// first position of element elem, returns -1 if element not contained in array
2013-04-03 02:26:21 +06:00
TIND Pos(const T & elem) const
2009-10-28 05:04:19 +05:00
{
2013-04-03 02:26:21 +06:00
TIND pos = -1;
for(TIND i=0; pos==-1 && i < this->size; i++)
2009-10-28 05:04:19 +05:00
if(elem == data[i]) pos = i;
return pos;
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// does the array contain element elem ?
bool Contains(const T & elem) const
{
return ( Pos(elem) >= 0 );
}
};
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
// print array
2013-04-03 02:26:21 +06:00
template <typename T, int BASE, typename TIND>
inline ostream & operator<< (ostream & s, const FlatArray<T,BASE,TIND> & a)
2009-01-13 04:40:13 +05:00
{
2013-04-03 02:26:21 +06:00
for (TIND i = a.Begin(); i < a.End(); i++)
2009-10-28 05:04:19 +05:00
s << i << ": " << a[i] << endl;
return s;
2009-01-13 04:40:13 +05:00
}
2009-10-28 05:04:19 +05:00
/**
Dynamic array container.
Array<T> is an automatically increasing array container.
The allocated memory doubles on overflow.
Either the container takes care of memory allocation and deallocation,
or the user provides one block of data.
*/
2013-04-03 02:26:21 +06:00
template <class T, int BASE = 0, typename TIND = int>
class Array : public FlatArray<T, BASE, TIND>
2009-10-28 05:04:19 +05:00
{
protected:
2013-04-03 02:26:21 +06:00
using FlatArray<T,BASE,TIND>::size;
using FlatArray<T,BASE,TIND>::data;
2011-01-11 01:18:01 +05:00
2009-10-28 05:04:19 +05:00
/// physical size of array
2018-03-15 23:01:20 +05:00
size_t allocsize;
2009-10-28 05:04:19 +05:00
/// memory is responsibility of container
bool ownmem;
public:
/// Generate array of logical and physical size asize
2012-06-13 15:07:11 +06:00
explicit Array()
2013-04-03 02:26:21 +06:00
: FlatArray<T, BASE, TIND> (0, NULL)
2012-06-13 15:07:11 +06:00
{
allocsize = 0;
ownmem = 1;
}
2018-03-15 23:01:20 +05:00
explicit Array(size_t asize)
2013-04-03 02:26:21 +06:00
: FlatArray<T, BASE, TIND> (asize, new T[asize])
2009-10-28 05:04:19 +05:00
{
allocsize = asize;
ownmem = 1;
}
/// Generate array in user data
2013-04-03 02:26:21 +06:00
Array(TIND asize, T* adata)
: FlatArray<T, BASE, TIND> (asize, adata)
2009-10-28 05:04:19 +05:00
{
allocsize = asize;
ownmem = 0;
}
/// array copy
2013-04-03 02:26:21 +06:00
explicit Array (const Array<T,BASE,TIND> & a2)
: FlatArray<T, BASE, TIND> (a2.Size(), a2.Size() ? new T[a2.Size()] : 0)
2009-10-28 05:04:19 +05:00
{
2011-01-11 01:18:01 +05:00
allocsize = size;
2009-10-28 05:04:19 +05:00
ownmem = 1;
2013-04-03 02:26:21 +06:00
for (TIND i = BASE; i < size+BASE; i++)
2009-10-28 05:04:19 +05:00
(*this)[i] = a2[i];
}
/// array move
Array (Array && a2)
: FlatArray<T,BASE,TIND> (a2.size, a2.data), allocsize(a2.allocsize), ownmem(a2.ownmem)
{
a2.size = 0;
a2.data = nullptr;
a2.allocsize = 0;
a2.ownmem = false;
}
2009-10-28 05:04:19 +05:00
/// if responsible, deletes memory
~Array()
{
if (ownmem)
2011-01-11 01:18:01 +05:00
delete [] data;
2009-10-28 05:04:19 +05:00
}
/// Change logical size. If necessary, do reallocation. Keeps contents.
2018-03-15 23:01:20 +05:00
void SetSize(size_t nsize)
2009-10-28 05:04:19 +05:00
{
if (nsize > allocsize)
ReSize (nsize);
2011-01-11 01:18:01 +05:00
size = nsize;
2009-10-28 05:04:19 +05:00
}
/// Change physical size. Keeps logical size. Keeps contents.
2018-03-15 23:01:20 +05:00
void SetAllocSize (size_t nallocsize)
2009-10-28 05:04:19 +05:00
{
if (nallocsize > allocsize)
ReSize (nallocsize);
}
/// Add element at end of array. reallocation if necessary.
void Append (const T & el)
2009-10-28 05:04:19 +05:00
{
2011-01-11 01:18:01 +05:00
if (size == allocsize)
ReSize (size+1);
data[size] = el;
size++;
// return size;
2009-10-28 05:04:19 +05:00
}
template <typename T2, int B2>
void Append (FlatArray<T2, B2> a2)
{
2011-01-11 01:18:01 +05:00
if (size+a2.Size() > allocsize)
ReSize (size+a2.Size());
2009-10-28 05:04:19 +05:00
for (int i = 0; i < a2.Size(); i++)
2011-01-11 01:18:01 +05:00
data[size+i] = a2[i+B2];
size += a2.Size();
2009-10-28 05:04:19 +05:00
}
/// Delete element i (0-based). Move last element to position i.
2013-04-03 02:26:21 +06:00
void Delete (TIND i)
2009-10-28 05:04:19 +05:00
{
2009-01-25 17:35:25 +05:00
#ifdef CHECK_Array_RANGE
2009-10-28 05:04:19 +05:00
RangeCheck (i+1);
2009-01-13 04:40:13 +05:00
#endif
data[i] = std::move(data[size-1]);
2011-01-11 01:18:01 +05:00
size--;
2009-10-28 05:04:19 +05:00
// DeleteElement (i+1);
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/// Delete element i (1-based). Move last element to position i.
2013-04-03 02:26:21 +06:00
void DeleteElement (TIND i)
2009-10-28 05:04:19 +05:00
{
2009-01-25 17:35:25 +05:00
#ifdef CHECK_Array_RANGE
2009-10-28 05:04:19 +05:00
RangeCheck (i);
2009-01-13 04:40:13 +05:00
#endif
data[i-1] = std::move(data[size-1]);
2011-01-11 01:18:01 +05:00
size--;
2009-10-28 05:04:19 +05:00
}
/// Delete last element.
void DeleteLast ()
{
2011-01-11 01:18:01 +05:00
size--;
2009-10-28 05:04:19 +05:00
}
/// Deallocate memory
void DeleteAll ()
{
if (ownmem)
2011-01-11 01:18:01 +05:00
delete [] data;
data = 0;
size = allocsize = 0;
2009-10-28 05:04:19 +05:00
}
/// Fill array with val
Array & operator= (const T & val)
{
2013-04-03 02:26:21 +06:00
FlatArray<T, BASE, TIND>::operator= (val);
2009-10-28 05:04:19 +05:00
return *this;
}
/// array copy
Array & operator= (const Array & a2)
{
SetSize (a2.Size());
2013-04-03 02:26:21 +06:00
for (TIND i (BASE); i < size+BASE; i++)
2009-10-28 05:04:19 +05:00
(*this)[i] = a2[i];
return *this;
}
/// array copy
Array & operator= (const FlatArray<T> & a2)
{
SetSize (a2.Size());
2013-04-03 02:26:21 +06:00
for (TIND i = BASE; i < size+BASE; i++)
2009-10-28 05:04:19 +05:00
(*this)[i] = a2[i];
return *this;
}
Array & operator= (Array && a2)
{
Swap (data, a2.data);
Swap (size, a2.size);
Swap (allocsize, a2.allocsize);
Swap (ownmem, a2.ownmem);
return *this;
}
2009-10-28 05:04:19 +05:00
private:
/// resize array, at least to size minsize. copy contents
2018-03-15 23:01:20 +05:00
void ReSize (size_t minsize)
2009-10-28 05:04:19 +05:00
{
2018-03-15 23:01:20 +05:00
size_t nsize = 2 * allocsize;
2009-10-28 05:04:19 +05:00
if (nsize < minsize) nsize = minsize;
2011-01-11 01:18:01 +05:00
if (data)
2009-10-28 05:04:19 +05:00
{
T * p = new T[nsize];
2009-01-13 04:40:13 +05:00
2018-03-15 23:01:20 +05:00
size_t mins = (nsize < size) ? nsize : size;
// memcpy (p, data, mins * sizeof(T));
#if defined(__GNUG__) && __GNUC__ < 5 && !defined(__clang__)
for (size_t i = 0; i < mins; i++) p[i] = move(data[i]);
#else
if (std::is_trivially_copyable<T>::value)
memcpy (p, data, sizeof(T)*mins);
else
for (size_t i = 0; i < mins; i++) p[i] = move(data[i]);
#endif
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
if (ownmem)
2011-01-11 01:18:01 +05:00
delete [] data;
2009-10-28 05:04:19 +05:00
ownmem = 1;
2011-01-11 01:18:01 +05:00
data = p;
2009-10-28 05:04:19 +05:00
}
else
{
2011-01-11 01:18:01 +05:00
data = new T[nsize];
2009-10-28 05:04:19 +05:00
ownmem = 1;
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
allocsize = nsize;
}
};
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
template <class T, int S>
class ArrayMem : public Array<T>
2009-01-13 04:40:13 +05:00
{
2011-01-11 01:18:01 +05:00
using Array<T>::size;
using Array<T>::data;
using Array<T>::ownmem;
T mem[S]; // Intel C++ calls dummy constructor
2009-10-28 05:04:19 +05:00
// char mem[S*sizeof(T)];
// double mem[(S*sizeof(T)+7) / 8];
2009-10-28 05:04:19 +05:00
public:
/// Generate array of logical and physical size asize
2018-03-15 23:01:20 +05:00
explicit ArrayMem(size_t asize = 0)
2009-10-28 05:04:19 +05:00
: Array<T> (S, static_cast<T*> (static_cast<void*>(&mem[0])))
{
2011-01-11 01:18:01 +05:00
size = asize;
2009-10-28 05:04:19 +05:00
if (asize > S)
{
2011-01-11 01:18:01 +05:00
data = new T[asize];
ownmem = 1;
2009-10-28 05:04:19 +05:00
}
2011-01-11 01:18:01 +05:00
// SetSize (asize);
2009-10-28 05:04:19 +05:00
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
ArrayMem & operator= (const T & val)
{
Array<T>::operator= (val);
return *this;
}
2010-07-19 18:00:52 +06:00
/// array copy
ArrayMem & operator= (const FlatArray<T> & a2)
{
2012-05-24 17:12:37 +06:00
this->SetSize (a2.Size());
2018-03-15 23:01:20 +05:00
for (size_t i = 0; i < size; i++)
2010-07-19 18:00:52 +06:00
(*this)[i] = a2[i];
return *this;
}
2009-10-28 05:04:19 +05:00
};
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
/*
2013-04-03 02:26:21 +06:00
template <class T, int B1, int B2>
class IndirectArray
{
2009-10-28 05:04:19 +05:00
const FlatArray<T, B1> & array;
const FlatArray<int, B2> & ia;
2013-04-03 02:26:21 +06:00
public:
2009-10-28 05:04:19 +05:00
IndirectArray (const FlatArray<T,B1> & aa, const FlatArray<int, B2> & aia)
2009-01-13 04:40:13 +05:00
: array(aa), ia(aia) { ; }
2009-10-28 05:04:19 +05:00
int Size() const { return ia.Size(); }
const T & operator[] (int i) const { return array[ia[i]]; }
2013-04-03 02:26:21 +06:00
};
2009-10-28 05:04:19 +05:00
*/
2009-01-13 04:40:13 +05:00
2013-04-03 02:26:21 +06:00
template <class TA1, class TA2>
class IndirectArray
{
const TA1 & array;
const TA2 & ia;
public:
IndirectArray (const TA1 & aa, const TA2 & aia)
: array(aa), ia(aia) { ; }
int Size() const { return ia.Size(); }
int Begin() const { return ia.Begin(); }
int End() const { return ia.End(); }
2009-01-13 04:40:13 +05:00
2013-04-03 02:26:21 +06:00
const typename TA1::TELEM & operator[] (int i) const { return array[ia[i]]; }
};
2009-01-13 04:40:13 +05:00
2013-04-03 02:26:21 +06:00
template <typename T1, typename T2>
inline ostream & operator<< (ostream & s, const IndirectArray<T1,T2> & ia)
{
for (int i = ia.Begin(); i < ia.End(); i++)
s << i << ": " << ia[i] << endl;
return s;
}
2009-01-13 04:40:13 +05:00
2013-04-03 02:26:21 +06:00
/*
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
///
template <class T, int BASE = 0>
class MoveableArray
{
int size;
int allocsize;
DynamicMem<T> data;
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
public:
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
MoveableArray()
{
size = allocsize = 0;
data.SetName ("MoveableArray");
}
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
MoveableArray(int asize)
: size(asize), allocsize(asize), data(asize)
{ ; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
~MoveableArray () { ; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
int Size() const { return size; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
void SetSize(int nsize)
{
if (nsize > allocsize)
{
data.ReAlloc (nsize);
allocsize = nsize;
}
size = nsize;
}
void SetAllocSize (int nallocsize)
{
data.ReAlloc (nallocsize);
allocsize = nallocsize;
}
///
T & operator[] (int i)
{ return ((T*)data)[i-BASE]; }
///
const T & operator[] (int i) const
{ return ((const T*)data)[i-BASE]; }
///
T & Elem (int i)
{ return ((T*)data)[i-1]; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
///
const T & Get (int i) const
{ return ((const T*)data)[i-1]; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
///
void Set (int i, const T & el)
{ ((T*)data)[i-1] = el; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
///
T & Last ()
{ return ((T*)data)[size-1]; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
///
const T & Last () const
{ return ((const T*)data)[size-1]; }
2009-01-13 04:40:13 +05:00
2009-10-28 05:04:19 +05:00
///
int Append (const T & el)
{
if (size == allocsize)
{
SetAllocSize (2*allocsize+1);
}
((T*)data)[size] = el;
size++;
return size;
}
///
void Delete (int i)
{
DeleteElement (i+1);
}
///
void DeleteElement (int i)
{
((T*)data)[i-1] = ((T*)data)[size-1];
size--;
}
///
void DeleteLast ()
{ size--; }
///
void DeleteAll ()
{
size = allocsize = 0;
data.Free();
}
///
void PrintMemInfo (ostream & ost) const
{
ost << Size() << " elements of size " << sizeof(T) << " = "
<< Size() * sizeof(T) << endl;
}
MoveableArray & operator= (const T & el)
{
for (int i = 0; i < size; i++)
((T*)data)[i] = el;
return *this;
}
MoveableArray & Copy (const MoveableArray & a2)
{
SetSize (a2.Size());
for (int i = 0; i < this->size; i++)
data[i] = a2.data[i];
return *this;
}
/// array copy
MoveableArray & operator= (const MoveableArray & a2)
{
return Copy(a2);
}
void SetName (const char * aname)
{
data.SetName(aname);
}
private:
///
//MoveableArray & operator= (MoveableArray &); //???
///
//MoveableArray (const MoveableArray &); //???
};
template <class T>
inline ostream & operator<< (ostream & ost, MoveableArray<T> & a)
{
for (int i = 0; i < a.Size(); i++)
ost << i << ": " << a[i] << endl;
return ost;
}
2013-04-03 02:26:21 +06:00
*/
2009-10-28 05:04:19 +05:00
/// bubble sort array
template <class T>
inline void BubbleSort (const FlatArray<T> & data)
{
for (int i = 0; i < data.Size(); i++)
for (int j = i+1; j < data.Size(); j++)
if (data[i] > data[j])
{
T hv = data[i];
data[i] = data[j];
data[j] = hv;
}
}
/// bubble sort array
template <class T, class S>
inline void BubbleSort (FlatArray<T> & data, FlatArray<S> & slave)
{
for (int i = 0; i < data.Size(); i++)
for (int j = i+1; j < data.Size(); j++)
if (data[i] > data[j])
{
T hv = data[i];
data[i] = data[j];
data[j] = hv;
2010-07-19 18:00:52 +06:00
2009-10-28 05:04:19 +05:00
S hvs = slave[i];
slave[i] = slave[j];
slave[j] = hvs;
}
}
template <class T, class S>
2009-10-28 05:22:10 +05:00
void QuickSortRec (FlatArray<T> & data,
FlatArray<S> & slave,
int left, int right)
2009-10-28 05:04:19 +05:00
{
int i = left;
int j = right;
T midval = data[(left+right)/2];
do
2009-01-13 04:40:13 +05:00
{
2009-10-28 05:04:19 +05:00
while (data[i] < midval) i++;
while (midval < data[j]) j--;
if (i <= j)
{
Swap (data[i], data[j]);
Swap (slave[i], slave[j]);
i++; j--;
}
2009-01-13 04:40:13 +05:00
}
2009-10-28 05:04:19 +05:00
while (i <= j);
2009-10-28 05:22:10 +05:00
if (left < j) QuickSortRec (data, slave, left, j);
if (i < right) QuickSortRec (data, slave, i, right);
2009-01-13 04:40:13 +05:00
}
2009-10-28 05:04:19 +05:00
template <class T, class S>
2009-10-28 05:22:10 +05:00
void QuickSort (FlatArray<T> & data, FlatArray<S> & slave)
2009-01-13 04:40:13 +05:00
{
2016-02-28 10:05:19 +05:00
if (data.Size() > 1)
QuickSortRec (data, slave, 0, data.Size()-1);
2009-01-13 04:40:13 +05:00
}
2009-10-28 05:04:19 +05:00
template <class T>
void Intersection (const FlatArray<T> & in1, const FlatArray<T> & in2,
Array<T> & out)
2009-01-13 04:40:13 +05:00
{
2009-10-28 05:04:19 +05:00
out.SetSize(0);
for(int i=0; i<in1.Size(); i++)
if(in2.Contains(in1[i]))
out.Append(in1[i]);
}
template <class T>
void Intersection (const FlatArray<T> & in1, const FlatArray<T> & in2, const FlatArray<T> & in3,
Array<T> & out)
{
out.SetSize(0);
for(int i=0; i<in1.Size(); i++)
if(in2.Contains(in1[i]) && in3.Contains(in1[i]))
out.Append(in1[i]);
2009-01-13 04:40:13 +05:00
}
2018-04-27 11:36:06 +05:00
template <typename T, int BASE, typename TIND>
ngstd::Archive & operator & (ngstd::Archive & archive, Array<T,BASE,TIND> & a)
{
if (archive.Output())
archive << a.Size();
else
{
size_t size;
archive & size;
a.SetSize (size);
}
/*
for (auto & ai : a)
archive & ai;
*/
archive.Do (&a[BASE], a.Size());
return archive;
}
2009-07-20 14:36:36 +06:00
}
2009-01-13 04:40:13 +05:00
#endif