netgen/libsrc/general/ngarray.hpp

813 lines
18 KiB
C++
Raw Normal View History

2019-07-09 13:41:40 +05:00
#ifndef NGARRAY_HPP_INCLUDED
#define NGARRAY_HPP_INCLUDED
2009-01-13 04:40:13 +05:00
/**************************************************************************/
2019-07-09 13:41:40 +05:00
/* File: ngarray.hpp */
2009-01-13 04:40:13 +05:00
/* 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)); }
2019-08-09 21:09:59 +05:00
T_Range Modify (int inc_begin, int inc_end) const
{ return T_Range(first+inc_begin, next+inc_end); }
2014-12-02 18:23:36 +05:00
ArrayRangeIterator<T> begin() const { return first; }
ArrayRangeIterator<T> end() const { return next; }
};
template <typename T, int BASE = 0, typename TIND = int>
2019-07-09 13:40:35 +05:00
class NgFlatArray;
2014-12-02 18:23:36 +05:00
template <typename T, int BASE, typename TIND>
class ArrayIterator
{
2019-07-09 13:40:35 +05:00
NgFlatArray<T,BASE,TIND> ar;
2014-12-02 18:23:36 +05:00
TIND ind;
public:
2019-07-09 13:40:35 +05:00
ArrayIterator (NgFlatArray<T,BASE,TIND> aar, TIND ai) : ar(aar), ind(ai) { ; }
2014-12-02 18:23:36 +05:00
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.
2019-07-09 13:39:16 +05:00
NgArray represented by size and data-pointer.
2009-10-28 05:04:19 +05:00
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>
2019-07-09 13:40:35 +05:00
class NgFlatArray
2009-10-28 05:04:19 +05:00
{
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;
using index_type = TIND;
2009-10-28 05:04:19 +05:00
/// provide size and memory
2019-07-09 13:40:35 +05:00
NgFlatArray (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); }
// 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
[[deprecated("Use *Range().begin() instead")]]
auto Begin() const { return *Range().begin(); }
[[deprecated("Use *Range().end() instead")]]
auto End() const { return *Range().end(); }
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>
2019-07-09 13:40:35 +05:00
IndirectArray<NgFlatArray, NgFlatArray<T2,B2> > operator[] (const NgFlatArray<T2,B2> & ia) const
2013-04-03 02:26:21 +06:00
{
2019-07-09 13:40:35 +05:00
return IndirectArray<NgFlatArray, NgFlatArray<T2,B2> > (*this, ia);
2013-04-03 02:26:21 +06:00
}
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)
2019-07-09 13:39:16 +05:00
cout << "NgArray<" << typeid(T).name()
2009-10-28 05:04:19 +05:00
<< ">::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)
2019-08-09 21:09:59 +05:00
// [[deprecated("Use operator[] instead")]]
2009-10-28 05:04:19 +05:00
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)
2019-07-09 13:39:16 +05:00
cout << "NgArray<" << typeid(T).name() << ">::Get out of range, i = " << i
2009-10-28 05:04:19 +05:00
<< ", 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)
2019-07-09 13:39:16 +05:00
cout << "NgArray<" << typeid(T).name() << ">::Set out of range, i = " << i
2009-10-28 05:04:19 +05:00
<< ", 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
2019-07-09 13:40:35 +05:00
NgFlatArray & operator= (const T & val)
2009-10-28 05:04:19 +05:00
{
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
2019-07-09 13:40:35 +05:00
const NgFlatArray<T> Range (TIND start, TIND end)
2009-10-28 05:04:19 +05:00
{
2019-07-09 13:40:35 +05:00
return NgFlatArray<T> (end-start, data+start);
2009-10-28 05:04:19 +05:00
}
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>
2019-07-09 13:40:35 +05:00
inline ostream & operator<< (ostream & s, const NgFlatArray<T,BASE,TIND> & a)
2009-01-13 04:40:13 +05:00
{
// for (TIND i = a.Begin(); i < a.End(); i++)
for (auto i : a.Range())
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.
2019-07-09 13:39:16 +05:00
NgArray<T> is an automatically increasing array container.
2009-10-28 05:04:19 +05:00
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>
2019-07-09 13:40:35 +05:00
class NgArray : public NgFlatArray<T, BASE, TIND>
2009-10-28 05:04:19 +05:00
{
protected:
2019-07-09 13:40:35 +05:00
using NgFlatArray<T,BASE,TIND>::size;
using NgFlatArray<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
2019-07-09 13:39:16 +05:00
explicit NgArray()
2019-07-09 13:40:35 +05:00
: NgFlatArray<T, BASE, TIND> (0, NULL)
2012-06-13 15:07:11 +06:00
{
allocsize = 0;
ownmem = 1;
}
2019-07-09 13:39:16 +05:00
explicit NgArray(size_t asize)
2019-07-09 13:40:35 +05:00
: NgFlatArray<T, BASE, TIND> (asize, asize ? new T[asize] : nullptr)
2009-10-28 05:04:19 +05:00
{
allocsize = asize;
2019-04-16 19:04:22 +05:00
ownmem = (asize == 0) ? 0 : 1;
2009-10-28 05:04:19 +05:00
}
/// Generate array in user data
2019-07-09 13:39:16 +05:00
NgArray(TIND asize, T* adata)
2019-07-09 13:40:35 +05:00
: NgFlatArray<T, BASE, TIND> (asize, adata)
2009-10-28 05:04:19 +05:00
{
allocsize = asize;
ownmem = 0;
}
/// array copy
2019-07-09 13:39:16 +05:00
explicit NgArray (const NgArray<T,BASE,TIND> & a2)
2019-07-09 13:40:35 +05:00
: NgFlatArray<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
2019-07-09 13:39:16 +05:00
NgArray (NgArray && a2)
2019-07-09 13:40:35 +05:00
: NgFlatArray<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
2019-07-09 13:39:16 +05:00
~NgArray()
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
}
/// 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
}
2019-07-29 02:22:47 +05:00
void SetSize0()
{
size = 0;
}
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>
2019-07-09 13:40:35 +05:00
void Append (NgFlatArray<T2, B2> a2)
2009-10-28 05:04:19 +05:00
{
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
2019-07-09 13:39:16 +05:00
NgArray & operator= (const T & val)
2009-10-28 05:04:19 +05:00
{
2019-07-09 13:40:35 +05:00
NgFlatArray<T, BASE, TIND>::operator= (val);
2009-10-28 05:04:19 +05:00
return *this;
}
/// array copy
2019-07-09 13:39:16 +05:00
NgArray & operator= (const NgArray & a2)
2009-10-28 05:04:19 +05:00
{
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
2019-07-09 13:40:35 +05:00
NgArray & operator= (const NgFlatArray<T> & a2)
2009-10-28 05:04:19 +05:00
{
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;
}
2019-07-09 13:39:16 +05:00
NgArray & operator= (NgArray && a2)
{
ngcore::Swap (data, a2.data);
ngcore::Swap (size, a2.size);
ngcore::Swap (allocsize, a2.allocsize);
ngcore::Swap (ownmem, a2.ownmem);
return *this;
}
2018-06-08 19:28:51 +05:00
T * Release()
{
ownmem = false;
return data;
}
2018-11-29 22:35:30 +05:00
// Only provide this function if T is archivable
template<typename T2=T>
auto DoArchive(Archive& archive) -> typename std::enable_if<is_archivable<T2>, void>::type
2018-11-29 22:35:30 +05:00
{
if(archive.Output())
archive << size;
else
{
size_t s;
archive & s;
SetSize(s);
}
archive.Do(data, size);
}
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;
2019-07-10 15:57:19 +05:00
if constexpr(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]);
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>
2019-07-09 21:00:12 +05:00
class NgArrayMem : public NgArray<T>
2009-01-13 04:40:13 +05:00
{
2019-07-09 13:39:16 +05:00
using NgArray<T>::size;
using NgArray<T>::data;
using NgArray<T>::ownmem;
2011-01-11 01:18:01 +05:00
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
2019-07-09 21:00:12 +05:00
explicit NgArrayMem(size_t asize = 0)
2019-07-09 13:39:16 +05:00
: NgArray<T> (S, static_cast<T*> (static_cast<void*>(&mem[0])))
2009-10-28 05:04:19 +05:00
{
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
2019-07-09 21:00:12 +05:00
NgArrayMem & operator= (const T & val)
2009-10-28 05:04:19 +05:00
{
2019-07-09 13:39:16 +05:00
NgArray<T>::operator= (val);
2009-10-28 05:04:19 +05:00
return *this;
}
2010-07-19 18:00:52 +06:00
/// array copy
2019-07-09 21:00:12 +05:00
NgArrayMem & operator= (const NgFlatArray<T> & a2)
2010-07-19 18:00:52 +06:00
{
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
{
2019-07-09 13:40:35 +05:00
const NgFlatArray<T, B1> & array;
const NgFlatArray<int, B2> & ia;
2013-04-03 02:26:21 +06:00
public:
2019-07-09 13:40:35 +05:00
IndirectArray (const NgFlatArray<T,B1> & aa, const NgFlatArray<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(); }
2019-08-09 21:09:59 +05:00
[[deprecated("Use *Range().begin() instead")]]
2013-04-03 02:26:21 +06:00
int Begin() const { return ia.Begin(); }
2019-08-09 21:09:59 +05:00
[[deprecated("Use *Range().end() instead")]]
2013-04-03 02:26:21 +06:00
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]]; }
auto Range() const { return ia.Range(); }
2019-08-09 21:09:59 +05:00
// auto begin() const { return ia.begin(); }
// auto end() const { return ia.end(); }
2013-04-03 02:26:21 +06:00
};
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>
2019-07-09 13:40:35 +05:00
inline void BubbleSort (const NgFlatArray<T> & data)
2009-10-28 05:04:19 +05:00
{
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>
2019-07-09 13:40:35 +05:00
inline void BubbleSort (NgFlatArray<T> & data, NgFlatArray<S> & slave)
2009-10-28 05:04:19 +05:00
{
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>
2019-07-09 13:40:35 +05:00
void QuickSortRec (NgFlatArray<T> & data,
NgFlatArray<S> & slave,
2009-10-28 05:22:10 +05:00
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)
{
ngcore::Swap (data[i], data[j]);
ngcore::Swap (slave[i], slave[j]);
2009-10-28 05:04:19 +05:00
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>
2019-07-09 13:40:35 +05:00
void QuickSort (NgFlatArray<T> & data, NgFlatArray<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>
2019-07-09 13:40:35 +05:00
void Intersection (const NgFlatArray<T> & in1, const NgFlatArray<T> & in2,
2019-07-09 13:39:16 +05:00
NgArray<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>
2019-07-09 13:40:35 +05:00
void Intersection (const NgFlatArray<T> & in1, const NgFlatArray<T> & in2, const NgFlatArray<T> & in3,
2019-07-09 13:39:16 +05:00
NgArray<T> & out)
2009-10-28 05:04:19 +05:00
{
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
}
2009-07-20 14:36:36 +06:00
}
2009-01-13 04:40:13 +05:00
2019-07-09 13:41:40 +05:00
#endif // NGARRAY_HPP_INCLUDED
2009-01-13 04:40:13 +05:00