- C3d primo salvataggio.
This commit is contained in:
Dario Sassi
2019-10-28 07:56:44 +00:00
parent 847ab021f3
commit 2067718d64
417 changed files with 170761 additions and 0 deletions
+358
View File
@@ -0,0 +1,358 @@
////////////////////////////////////////////////////////////////////////////////
/**
\file
\brief \ru Упорядоченный одномерный массив объектов.
\en Ordered one-dimensional array of objects. \~
*/
////////////////////////////////////////////////////////////////////////////////
#ifndef __TEMPL_CSS_ARRAY_H
#define __TEMPL_CSS_ARRAY_H
#include <templ_ss_array.h>
#include <utility>
FORVARD_DECL_TEMPLATE_TYPENAME( class CSSArray );
FORVARD_DECL_TEMPLATE_TYPENAME( void q_sort( CSSArray<Type> & arr, SArray<Type> * del ) );
FORVARD_DECL_TEMPLATE_TYPENAME( reader & CALL_DECLARATION operator >> ( reader & in, CSSArray<Type> & ref ) );
FORVARD_DECL_TEMPLATE_TYPENAME( writer & CALL_DECLARATION operator << ( writer & out, const CSSArray<Type> & ref ) );
//------------------------------------------------------------------------------
/** \brief \ru Упорядоченный одномерный массив.
\en Ordered one-dimensional array. \~
\details \ru Упорядоченный одномерный массив объектов. \n
У объектов массива должны быть операторы "==" и "<".
Имеется возможность добавлять несортированные данные через функцию AddNoSort,
но при первом обращении к функциям Add и Find произойдет сортировка
Одинаковые объекты не добавляются.
\en Ordered one-dimensional array of objects. \n
Elements of the array should have operators "==" and "<".
The unsorted data can be added by the function 'AddNoSort',
but the sorting starts after the first call of functions Add and Find.
The similar objects are not added. \~
\ingroup Base_Tools_Containers
*/
// ---
template <class Type>
class CSSArray : protected SSArray<Type> {
bool m_sort; ///< \ru Признак сортированности массива. \en Attribute of an array being sorted.
public:
/// \ru Конструктор. \en Constructor.
CSSArray( size_t maxCnt = 0, uint16 delt = 1 )
: SSArray<Type>( maxCnt, delt )
, m_sort( true )
{}
/// \ru Конструктор копирования. \en Copy constructor.
CSSArray( const CSSArray<Type> & other )
: SSArray<Type>( other )
, m_sort( other.m_sort )
{}
/// \ru Конструктор копирования. \en Copy constructor.
CSSArray( const SArray<Type> & other, SArray<Type> * del = NULL )
: SSArray<Type>( other )
, m_sort( false )
{
::q_sort( *this, del );
}
/// \ru Конструктор копирования. \en Copy constructor.
CSSArray( const SArray< std::pair<Type,Type> > & other, bool addFirst, SArray<Type> * del = NULL )
: SSArray<Type>( other.Count(), 1 )
, m_sort( false )
{
if ( addFirst ) {
for ( size_t k = 0, cnt = other.Count(); k < cnt; k++ )
AddNoSort( other[k].first );
}
else {
for ( size_t k = 0, cnt = other.Count(); k < cnt; k++ )
AddNoSort( other[k].second );
}
::q_sort( *this, del );
}
using SSArray<Type>::Flush;
using SSArray<Type>::HardFlush;
using SSArray<Type>::Adjust;
using SSArray<Type>::operator[];
using SSArray<Type>::Remove;
using SSArray<Type>::RemoveInd;
using SSArray<Type>::Count;
using SSArray<Type>::MaxIndex;
using SSArray<Type>::GetAddr;
using SSArray<Type>::GetEndAddr;
using SSArray<Type>::Reserve;
using SSArray<Type>::SetSize;
using SSArray<Type>::SetMaxDelta;
using SSArray<Type>::empty;
using SSArray<Type>::size;
using SSArray<Type>::reserve;
using SSArray<Type>::clear;
using SSArray<Type>::begin;
void AddNoSort( const Type & ent ) { SSArray<Type>::AddSimple( ent ); m_sort = false; } ///< \ru Добавить элемент без сортировки. \en Add element without sorting.
Type * Add ( const Type & ); ///< \ru Добавить элемент с упорядочиванием по массиву. \en Add element with sorting.
Type * Add ( const Type &, size_t & indexEnt ); ///< \ru Добавить элемент с упорядочиванием по массиву, возвращает индекс. \en Add element with sorting by array, returns index of the element.
size_t Find( const Type & ); ///< \ru Найти элемент в упорядоченном массиве. \en Find an element in ordered array.
void Sort( SArray<Type> * del = NULL ); ///< \ru Выполнить сортировку элементов массива. \en Sort elements of array.
size_t RemoveObj( const Type & delObject ); ///< \ru Удалить элемент из массива. \en Delete an element from array.
void SetNoSort() { m_sort = false; } ///< \ru Сбросить флаг сортированности. \en Reset the flag of being sorted.
void AddArray( const CSSArray<Type> & arr, bool doSort ); ///< \ru Добавить массив. \en Add array
void AddArray( const SArray<Type> & arr, bool doSort ); ///< \ru Добавить массив. \en Add array
bool IsSorted() const {return m_sort; } ///< \ru Вернуть вризнак сортированности массива. \en Return an attribute of an array being sorted.
TEMPLATE_FRIEND void q_sort TEMPLATE_SUFFIX ( CSSArray<Type> & arr, SArray<Type> * del );
TEMPLATE_FRIEND reader & CALL_DECLARATION operator >> TEMPLATE_SUFFIX ( reader & in, CSSArray<Type> & ref );
TEMPLATE_FRIEND writer & CALL_DECLARATION operator << TEMPLATE_SUFFIX ( writer & out, const CSSArray<Type> & ref );
// Intel Compiler 12 // KNOWN_OBJECTS_RW_REF_OPERATORS( CSSArray<Type> )
};
//-------------------------------------------------------------------------------
// \ru добавление объекта в массив \en adding an object to array
// ---
template <class Type>
inline Type * CSSArray<Type>::Add( const Type & el ) {
::q_sort( *this, (SArray<Type> *)NULL );
return SSArray<Type>::Add( el );
}
//-------------------------------------------------------------------------------
// \ru добавление объекта в массив \en adding an object to array
// ---
template <class Type>
inline Type * CSSArray<Type>::Add( const Type & el, size_t & indexEl ) {
::q_sort( *this, (SArray<Type> *)NULL );
return SSArray<Type>::Add( el, indexEl );
}
//-------------------------------------------------------------------------------
// \ru добавление массива \en adding of an array
// ---
template <class Type>
inline void CSSArray<Type>::AddArray( const CSSArray<Type> & arr, bool doSort )
{
if ( this != &arr ) {
m_sort = false;
(*this) += arr;
if ( doSort )
::q_sort( *this, (SArray<Type> *)NULL );
}
}
//-------------------------------------------------------------------------------
// \ru добавление массива \en adding of an array
// ---
template <class Type>
inline void CSSArray<Type>::AddArray( const SArray<Type> & arr, bool doSort )
{
if ( this != &arr ) {
m_sort = false;
(*this) += arr;
if ( doSort )
::q_sort( *this, (SArray<Type> *)NULL );
}
}
//-------------------------------------------------------------------------------
// \ru поиск объека в массиве \en search of an element in array
// ---
template <class Type>
inline size_t CSSArray<Type>::Find( const Type & el ) {
::q_sort( *this, (SArray<Type> *)NULL );
return SSArray<Type>::Find( el );
}
//------------------------------------------------------------------------------
//
// ---
template <class Type>
inline void CSSArray<Type>::Sort( SArray<Type> * del ) {
::q_sort( *this, del );
}
//------------------------------------------------------------------------------
// \ru удалить элемент из массива \en delete an element from array
// ---
template <class Type>
inline size_t CSSArray<Type>::RemoveObj( const Type & delObject ) {
size_t ind = Find( delObject );
if ( ind != SYS_MAX_T )
RemoveInd( ind );
return ind;
}
//-----------------------------------------------------------------------------
// \ru Н.Вирт "Алгоритмы и структуры данных" 2е издание, Санкт-Петербург, 2001г., стр.111 \en see N.Wirth "Algorithms and Data Structures"
// ---
template <class Type>
void q_sort_r( CSSArray<Type> & arr, size_t minInd = SYS_MAX_T, size_t maxInd = SYS_MAX_T )
{
if ( arr.Count() > 1 ) {
if ( minInd == SYS_MAX_T ) minInd = 0;
if ( maxInd == SYS_MAX_T || maxInd > (size_t)arr.MaxIndex() )
maxInd = (size_t)arr.MaxIndex(); // \ru проверено count > 0 \en chacked that count > 0
size_t i = minInd, j = maxInd; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and <
size_t im = (i + j)/2; // \ru OV_x64 приводить к знаковому значению будем только в операторах > и < \en OV_x64 cast to signed value only in operators > and <
Type * middle = (Type *)new char[sizeof(Type)];
::memcpy( middle, &arr[im], sizeof( Type ) );
Type * buff = (Type *)new char[sizeof(Type)];
do {
while( arr[i] < *middle ) i++;
while( *middle < arr[j] ) j--;
if ( (ptrdiff_t)i <= (ptrdiff_t)j ) {
if ( i != j ) {
Type * wi = &arr[i];
Type * wj = &arr[j];
::memcpy( buff, wi, sizeof( Type ) );
::memcpy( wi, wj, sizeof( Type ) );
::memcpy( wj, buff, sizeof( Type ) );
}
i++;
j--;
}
} while( !((ptrdiff_t)i > (ptrdiff_t)j) );
delete [] (char*)buff;
delete [] (char*)middle;
if ( (ptrdiff_t)minInd < (ptrdiff_t)j )
q_sort_r( arr, minInd, j );
if ( (ptrdiff_t)i < (ptrdiff_t)maxInd )
q_sort_r( arr, i, maxInd );
}
}
//-----------------------------------------------------------------------------
// \ru Аналог q_sort_r без рекурсии. Не требует выделения/освобождения памяти на каждой итерации.
// \en Analog of q_sort_r without recursion. Not require memory allocation/deallocation at each iteration.
// \param arr[out] - \ru Указатель на начало сортируемого участка массива. \en Pointer to the beginning of the array part being sorted.
// \param minIndex[in] - \ru Индекс первого элемента в сортируемом участке массива. \en Index of the first element in the array part being sorted.
// \param maxIndex[in] - \ru Индекс последнего элемента в сортируемом участке массива. \en Index of the last element in the array part being sorted.
// ---
template <class Type>
void q_sort_r2( Type * arr, size_t minIndex, size_t maxIndex )
{
ptrdiff_t rangeSize = (ptrdiff_t)maxIndex - (ptrdiff_t)minIndex;
if ( rangeSize == 1 ) {
if ( arr[maxIndex] < arr[minIndex] ) {
Type * buff = ( Type * )new char[sizeof( Type )];
Type * w0 = &arr[minIndex];
Type * w1 = &arr[maxIndex];
::memcpy( buff, w1, sizeof( Type ) );
::memcpy( w1, w0, sizeof( Type ) );
::memcpy( w0, buff, sizeof( Type ) );
delete[]( char* )buff;
}
}
else if ( rangeSize > 1 ) {
c3d::NumbersPair iterStack[30];
int stackCount = -1;
ptrdiff_t minInd = minIndex, maxInd = maxIndex;
ptrdiff_t i = minInd, j = maxInd;
ptrdiff_t im = 0;
Type * middle = ( Type * )new char[sizeof( Type )];
Type * buff = ( Type * )new char[sizeof( Type )];
for ( ;; ) {
i = minInd, j = maxInd;
im = ( i + j ) / 2;
::memcpy( middle, &arr[im], sizeof( Type ) );
do {
while ( arr[i] < *middle ) i++;
while ( *middle < arr[j] ) j--;
if ( i <= j ) {
if ( i != j ) {
Type * wi = &arr[i];
Type * wj = &arr[j];
::memcpy( buff, wi, sizeof( Type ) );
::memcpy( wi, wj, sizeof( Type ) );
::memcpy( wj, buff, sizeof( Type ) );
}
i++;
j--;
}
} while ( !( i > j ) );
if ( j - minInd > maxInd - i ) {
if ( minInd < j ) {
iterStack[++stackCount].first = minInd;
iterStack[stackCount].second = j;
}
if ( i < maxInd ) {
minInd = i;
continue;
}
}
else {
if ( i < maxInd ) {
iterStack[++stackCount].first = i;
iterStack[stackCount].second = maxInd;
}
if ( minInd < j ) {
maxInd = j;
continue;
}
}
if ( stackCount < 0 )
break; // \ru Все подмассивы обработаны. \en All subarrays are done.
minInd = iterStack[stackCount].first;
maxInd = iterStack[stackCount--].second;
}
delete[]( char* )buff;
delete[]( char* )middle;
}
}
//-----------------------------------------------------------------------------
//
// ---
template <class Type>
void q_sort( CSSArray<Type> & arr, SArray<Type> * del )
{
if ( !arr.m_sort ) {
if ( arr.Count() ) {
q_sort_r2<Type>( arr.begin(), 0, arr.Count() - 1 ); // C3D-1211
//q_sort_r( arr );
// \ru удаление одинаковых \en deletion of similar objects
for ( ptrdiff_t i = arr.MaxIndex(); i >= 1; i-- ) { // OV_x64 maxIndex >= 0
if ( arr[i] == arr[i-1] ) {
if ( del )
del->Add( arr[i] );
arr.RemoveInd( i );
}
}
}
arr.m_sort = true;
}
}
#endif // __TEMPL_CSS_ARRAY_H