@@ -105,36 +105,84 @@ class PIDeque {
public :
typedef bool ( * CompareFunc ) ( const T & , const T & ) ;
//! \~\brief
//! \~english Constructs an empty array.
//! \~russian Создает пустой массив.
inline PIDeque ( ) : pid_data ( 0 ) , pid_size ( 0 ) , pid_rsize ( 0 ) , pid_start ( 0 ) {
PIINTROSPECTION_CONTAINER_NEW ( T , sizeof ( T ) )
}
//! \~\brief
//! \~english Copy constructor.
//! \~russian Копирующий конструктор.
inline PIDeque ( const PIDeque < T > & other ) : pid_data ( 0 ) , pid_size ( 0 ) , pid_rsize ( 0 ) , pid_start ( 0 ) {
PIINTROSPECTION_CONTAINER_NEW ( T , sizeof ( T ) )
alloc_forward ( other . pid_size ) ;
newT ( pid_data + pid_start , other . pid_data + other . pid_start , pid_size ) ;
}
//! \~\brief
//! \~english Contructs array from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Создает массив из
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
//! \~\details
//! \~\code
//! PIDeque <int> v{1,2,3};
//! piCout << v; // {1, 2, 3}
//! \endcode
inline PIDeque ( std : : initializer_list < T > init_list ) : pid_data ( 0 ) , pid_size ( 0 ) , pid_rsize ( 0 ) , pid_start ( 0 ) {
PIINTROSPECTION_CONTAINER_NEW ( T , sizeof ( T ) )
alloc_forward ( init_list . size ( ) ) ;
newT ( pid_data , init_list . begin ( ) , init_list . size ( ) ) ;
}
//! \~\brief
//! \~english Contructs array from raw `data`.
//! This constructor reserve `size` and copy from `data` pointer.
//! \~russian Создает массив из указателя на данные `data` и размер `size`.
//! Т о есть выделяет память для `size` элементов и копирует данные из указателя `data`.
inline PIDeque ( const T * data , size_t size ) : pid_data ( 0 ) , pid_size ( 0 ) , pid_rsize ( 0 ) , pid_start ( 0 ) {
PIINTROSPECTION_CONTAINER_NEW ( T , sizeof ( T ) )
alloc_forward ( size ) ;
newT ( pid_data + pid_start , data , pid_size ) ;
}
inline PIDeque ( size_t pid_size , const T & f = T ( ) ) : pid_data ( 0 ) , pid_size ( 0 ) , pid_rsize ( 0 ) , pid_start ( 0 ) {
//! \~\brief
//! \~english Contructs array with size `size` filled elements `e`.
//! \~russian Создает массив из `size` элементов заполненных `e`.
inline PIDeque ( size_t pid_size , const T & e = T ( ) ) : pid_data ( 0 ) , pid_size ( 0 ) , pid_rsize ( 0 ) , pid_start ( 0 ) {
PIINTROSPECTION_CONTAINER_NEW ( T , sizeof ( T ) )
resize ( pid_size , f ) ;
resize ( pid_size , e ) ;
}
//! \~\brief
//! \~english Contructs array with size `size` and elements created by function `f(size_t i)`.
//! \~russian Создает массив из `size` элементов созданных функцией `f(size_t i)`.
//! \~\details
//! \~english Can use
//! [Lambda expressions](https://en.cppreference.com/w/cpp/language/lambda)
//! as constructor argument.
//! \~russian Позволяет передавать
//! [Лямбда-выражения](https://ru.cppreference.com/w/cpp/language/lambda)
//! для создания элементов в конструкторе.
//! \~\code
//! PIDeque <int> v(5, [](size_t i){return i*2;});
//! piCout << v; // {0, 2, 4, 6, 8}
//! \endcode
inline PIDeque ( size_t piv_size , std : : function < T ( size_t i ) > f ) : pid_data ( 0 ) , pid_size ( 0 ) , pid_rsize ( 0 ) , pid_start ( 0 ) {
PIINTROSPECTION_CONTAINER_NEW ( T , sizeof ( T ) )
resize ( piv_size , f ) ;
}
//! \~\brief
//! \~english Move constructor.
//! \~russian Перемещающий конструктор.
inline PIDeque ( PIDeque < T > & & other ) : pid_data ( other . pid_data ) , pid_size ( other . pid_size ) , pid_rsize ( other . pid_rsize ) , pid_start ( other . pid_start ) {
PIINTROSPECTION_CONTAINER_NEW ( T , sizeof ( T ) )
other . _reset ( ) ;
}
inline virtual ~ PIDeque ( ) {
PIINTROSPECTION_CONTAINER_DELETE ( T )
PIINTROSPECTION_CONTAINER_FREE ( T , ( pid_rsize ) )
@@ -143,6 +191,9 @@ public:
_reset ( ) ;
}
//! \~\brief
//! \~english Assign operator.
//! \~russian Оператор присваивания.
inline PIDeque < T > & operator = ( const PIDeque < T > & other ) {
if ( this = = & other ) return * this ;
deleteT ( pid_data + pid_start , pid_size ) ;
@@ -151,18 +202,14 @@ public:
return * this ;
}
//! \~\brief
//! \~english Assign move operator.
//! \~russian Оператор перемещающего присваивания.
inline PIDeque < T > & operator = ( PIDeque < T > & & other ) {
swap ( other ) ;
return * this ;
}
typedef T value_type ;
enum ReshapeOrder {
byRow ,
byColumn
} ;
class iterator {
friend class PIDeque < T > ;
private :
@@ -178,34 +225,94 @@ public:
inline iterator ( ) : parent ( 0 ) , pos ( 0 ) { }
inline T & operator * ( ) { return ( * parent ) [ pos ] ; }
inline const T & operator * ( ) const { return ( * parent ) [ pos ] ; }
inline T & operator - > ( ) { return ( * parent ) [ pos ] ; }
inline const T & operator - > ( ) const { return ( * parent ) [ pos ] ; }
inline T & operator * ( ) {
return ( * parent ) [ pos ] ;
}
inline const T & operator * ( ) const {
return ( * parent ) [ pos ] ;
}
inline T & operator - > ( ) {
return ( * parent ) [ pos ] ;
}
inline const T & operator - > ( ) const {
return ( * parent ) [ pos ] ;
}
inline iterator & operator + + ( ) { + + pos ; return * this ; }
inline iterator & operator + + ( int ) { const auto tmp = * this ; + + * this ; return tmp ; }
inline iterator & operator - - ( ) { - - pos ; return * this ; }
inline iterator & operator - - ( int ) { const auto tmp = * this ; - - * this ; return tmp ; }
inline iterator & operator + + ( ) {
+ + pos ;
return * this ;
}
inline iterator & operator + + ( int ) {
const auto tmp = * this ;
+ + * this ;
return tmp ;
}
inline iterator & operator - - ( ) {
- - pos ;
return * this ;
}
inline iterator & operator - - ( int ) {
const auto tmp = * this ;
- - * this ;
return tmp ;
}
inline iterator & operator + = ( const iterator & it ) { pos + = it . pos ; return * this ; }
inline iterator & operator + = ( size_t p ) { pos + = p ; return * this ; }
inline iterator & operator - = ( const iterator & it ) { pos - = it . pos ; return * this ; }
inline iterator & operator - = ( size_t p ) { pos - = p ; return * this ; }
inline iterator & operator + = ( const iterator & it ) {
pos + = it . pos ;
return * this ;
}
inline iterator & operator + = ( size_t p ) {
pos + = p ;
return * this ;
}
inline iterator & operator - = ( const iterator & it ) {
pos - = it . pos ;
return * this ;
}
inline iterator & operator - = ( size_t p ) {
pos - = p ;
return * this ;
}
friend inline iterator operator - ( const iterator & it , size_t p ) { auto tmp = it ; tmp - = p ; return tmp ; }
friend inline itera tor operator - ( size_t p , const iterator & it ) { return it - p ; }
friend inline std : : ptrdiff_t operator - ( const iterator & it1 , const iterator & it2 ) { return it1 . pos - it2 . pos ; }
friend inline iterator operator - ( const iterator & it , size_t p ) {
au to tmp = it ;
tmp - = p ;
return tmp ;
}
friend inline iterator operator - ( size_t p , const iterator & it ) {
return it - p ;
}
friend inline std : : ptrdiff_t operator - ( const iterator & it1 , const iterator & it2 ) {
return it1 . pos - it2 . pos ;
}
friend inline iterator operator + ( const iterator & it , size_t p ) { auto tmp = it ; tmp + = p ; return tmp ; }
friend inline itera tor operator + ( size_t p , const iterator & it ) { return it + p ; }
friend inline iterator operator + ( const iterator & it , size_t p ) {
au to tmp = it ;
tmp + = p ;
return tmp ;
}
friend inline iterator operator + ( size_t p , const iterator & it ) {
return it + p ;
}
inline bool operator = = ( const iterator & it ) const { return ( pos = = it . pos ) ; }
inline bool operator ! = ( const iterator & it ) const { return ( pos ! = it . pos ) ; }
friend inline bool operator < ( const iterator & it1 , const iterator & it2 ) { return it1 . pos < it2 . pos ; }
friend inline bool operator < = ( const iterator & it1 , const iterator & it2 ) { return it1 . pos < = it2 . pos ; }
friend inline bool operator > ( const iterator & it1 , const iterator & it2 ) { return it1 . pos > it2 . pos ; }
friend inline bool operator > = ( const iterator & it1 , const iterator & it2 ) { return it1 . pos > = it2 . pos ; }
inline bool operator = = ( const iterator & it ) const {
return ( pos = = it . pos ) ;
}
inline bool operator ! = ( const iterator & it ) const {
return ( pos ! = it . pos ) ;
}
friend inline bool operator < ( const iterator & it1 , const iterator & it2 ) {
return it1 . pos < it2 . pos ;
}
friend inline bool operator < = ( const iterator & it1 , const iterator & it2 ) {
return it1 . pos < = it2 . pos ;
}
friend inline bool operator > ( const iterator & it1 , const iterator & it2 ) {
return it1 . pos > it2 . pos ;
}
friend inline bool operator > = ( const iterator & it1 , const iterator & it2 ) {
return it1 . pos > = it2 . pos ;
}
} ;
class const_iterator {
@@ -223,32 +330,88 @@ public:
inline const_iterator ( ) : parent ( 0 ) , pos ( 0 ) { }
inline const T & operator * ( ) const { return ( * parent ) [ pos ] ; }
inline const T & operator - > ( ) const { return ( * parent ) [ pos ] ; }
inline const T & operator * ( ) const {
return ( * parent ) [ pos ] ;
}
inline const T & operator - > ( ) const {
return ( * parent ) [ pos ] ;
}
inline const_iterator & operator + + ( ) { + + pos ; return * this ; }
inline const_iterator & operator + + ( int ) { const auto tmp = * this ; + + * this ; return tmp ; }
inline const_iterator & operator - - ( ) { - - pos ; return * this ; }
inline const_iterator & operator - - ( int ) { const auto tmp = * this ; - - * this ; return tmp ; }
inline const_iterator & operator + + ( ) {
+ + pos ;
return * this ;
}
inline const_iterator & operator + + ( int ) {
const auto tmp = * this ;
+ + * this ;
return tmp ;
}
inline const_iterator & operator - - ( ) {
- - pos ;
return * this ;
}
inline const_iterator & operator - - ( int ) {
const auto tmp = * this ;
- - * this ;
return tmp ;
}
inline const_iterator & operator + = ( const const_iterator & it ) { pos + = it . pos ; return * this ; }
inline const_iterator & operator + = ( size_t p ) { pos + = p ; return * this ; }
inline const_iterator & operator - = ( const const_iterator & it ) { pos - = it . pos ; return * this ; }
inline const_iterator & operator - = ( size_t p ) { pos - = p ; return * this ; }
inline const_iterator & operator + = ( const const_iterator & it ) {
pos + = it . pos ;
return * this ;
}
inline const_iterator & operator + = ( size_t p ) {
pos + = p ;
return * this ;
}
inline const_iterator & operator - = ( const const_iterator & it ) {
pos - = it . pos ;
return * this ;
}
inline const_iterator & operator - = ( size_t p ) {
pos - = p ;
return * this ;
}
friend inline const_iterator operator - ( const const_iterator & it , size_t p ) { auto tmp = it ; tmp - = p ; return tmp ; }
friend inline const_itera tor operator - ( size_t p , const const_iterator & it ) { return it - p ; }
friend inline std : : ptrdiff_t operator - ( const const_iterator & it1 , const const_iterator & it2 ) { return it1 . pos - it2 . pos ; }
friend inline const_iterator operator - ( const const_iterator & it , size_t p ) {
au to tmp = it ;
tmp - = p ;
return tmp ;
}
friend inline const_iterator operator - ( size_t p , const const_iterator & it ) {
return it - p ;
}
friend inline std : : ptrdiff_t operator - ( const const_iterator & it1 , const const_iterator & it2 ) {
return it1 . pos - it2 . pos ;
}
friend inline const_iterator operator + ( const const_iterator & it , size_t p ) { auto tmp = it ; tmp + = p ; return tmp ; }
friend inline const_itera tor operator + ( size_t p , const const_iterator & it ) { return it + p ; }
friend inline const_iterator operator + ( const const_iterator & it , size_t p ) {
au to tmp = it ;
tmp + = p ;
return tmp ;
}
friend inline const_iterator operator + ( size_t p , const const_iterator & it ) {
return it + p ;
}
inline bool operator = = ( const const_iterator & it ) const { return ( pos = = it . pos ) ; }
inline bool operator ! = ( const const_iterator & it ) const { return ( pos ! = it . pos ) ; }
friend inline bool operator < ( const const_iterator & it1 , const const_iterator & it2 ) { return it1 . pos < it2 . pos ; }
friend inline bool operator < = ( const const_iterator & it1 , const const_iterator & it2 ) { return it1 . pos < = it2 . pos ; }
friend inline bool operator > ( const const_iterator & it1 , const const_iterator & it2 ) { return it1 . pos > it2 . pos ; }
friend inline bool operator > = ( const const_iterator & it1 , const const_iterator & it2 ) { return it1 . pos > = it2 . pos ; }
inline bool operator = = ( const const_iterator & it ) const {
return ( pos = = it . pos ) ;
}
inline bool operator ! = ( const const_iterator & it ) const {
return ( pos ! = it . pos ) ;
}
friend inline bool operator < ( const const_iterator & it1 , const const_iterator & it2 ) {
return it1 . pos < it2 . pos ;
}
friend inline bool operator < = ( const const_iterator & it1 , const const_iterator & it2 ) {
return it1 . pos < = it2 . pos ;
}
friend inline bool operator > ( const const_iterator & it1 , const const_iterator & it2 ) {
return it1 . pos > it2 . pos ;
}
friend inline bool operator > = ( const const_iterator & it1 , const const_iterator & it2 ) {
return it1 . pos > = it2 . pos ;
}
} ;
class reverse_iterator {
@@ -266,34 +429,94 @@ public:
inline reverse_iterator ( ) : parent ( 0 ) , pos ( 0 ) { }
inline T & operator * ( ) { return ( * parent ) [ pos ] ; }
inline const T & operator * ( ) const { return ( * parent ) [ pos ] ; }
inline T & operator - > ( ) { return ( * parent ) [ pos ] ; }
inline const T & operator - > ( ) const { return ( * parent ) [ pos ] ; }
inline T & operator * ( ) {
return ( * parent ) [ pos ] ;
}
inline const T & operator * ( ) const {
return ( * parent ) [ pos ] ;
}
inline T & operator - > ( ) {
return ( * parent ) [ pos ] ;
}
inline const T & operator - > ( ) const {
return ( * parent ) [ pos ] ;
}
inline reverse_iterator & operator + + ( ) { - - pos ; return * this ; }
inline reverse_iterator & operator + + ( int ) { const auto tmp = * this ; - - * this ; return tmp ; }
inline reverse_iterator & operator - - ( ) { + + pos ; return * this ; }
inline reverse_iterator & operator - - ( int ) { const auto tmp = * this ; + + * this ; return tmp ; }
inline reverse_iterator & operator + + ( ) {
- - pos ;
return * this ;
}
inline reverse_iterator & operator + + ( int ) {
const auto tmp = * this ;
- - * this ;
return tmp ;
}
inline reverse_iterator & operator - - ( ) {
+ + pos ;
return * this ;
}
inline reverse_iterator & operator - - ( int ) {
const auto tmp = * this ;
+ + * this ;
return tmp ;
}
inline reverse_iterator & operator + = ( const reverse_iterator & it ) { pos - = it . pos ; return * this ; }
inline reverse_iterator & operator + = ( size_t p ) { pos - = p ; return * this ; }
inline reverse_iterator & operator - = ( const reverse_iterator & it ) { pos + = it . pos ; return * this ; }
inline reverse_iterator & operator - = ( size_t p ) { pos + = p ; return * this ; }
inline reverse_iterator & operator + = ( const reverse_iterator & it ) {
pos - = it . pos ;
return * this ;
}
inline reverse_iterator & operator + = ( size_t p ) {
pos - = p ;
return * this ;
}
inline reverse_iterator & operator - = ( const reverse_iterator & it ) {
pos + = it . pos ;
return * this ;
}
inline reverse_iterator & operator - = ( size_t p ) {
pos + = p ;
return * this ;
}
friend inline reverse_iterator operator - ( const reverse_iterator & it , size_t p ) { auto tmp = it ; tmp - = p ; return tmp ; }
friend inline reverse_itera tor operator - ( size_t p , const reverse_iterator & it ) { return it - p ; }
friend inline std : : ptrdiff_t operator - ( const reverse_iterator & it1 , const reverse_iterator & it2 ) { return it2 . pos - it1 . pos ; }
friend inline reverse_iterator operator - ( const reverse_iterator & it , size_t p ) {
au to tmp = it ;
tmp - = p ;
return tmp ;
}
friend inline reverse_iterator operator - ( size_t p , const reverse_iterator & it ) {
return it - p ;
}
friend inline std : : ptrdiff_t operator - ( const reverse_iterator & it1 , const reverse_iterator & it2 ) {
return it2 . pos - it1 . pos ;
}
friend inline reverse_iterator operator + ( const reverse_iterator & it , size_t p ) { auto tmp = it ; tmp + = p ; return tmp ; }
friend inline reverse_itera tor operator + ( size_t p , const reverse_iterator & it ) { return it + p ; }
friend inline reverse_iterator operator + ( const reverse_iterator & it , size_t p ) {
au to tmp = it ;
tmp + = p ;
return tmp ;
}
friend inline reverse_iterator operator + ( size_t p , const reverse_iterator & it ) {
return it + p ;
}
inline bool operator = = ( const reverse_iterator & it ) const { return ( pos = = it . pos ) ; }
inline bool operator ! = ( const reverse_iterator & it ) const { return ( pos ! = it . pos ) ; }
friend inline bool operator < ( const reverse_iterator & it1 , const reverse_iterator & it2 ) { return it1 . pos < it2 . pos ; }
friend inline bool operator < = ( const reverse_iterator & it1 , const reverse_iterator & it2 ) { return it1 . pos < = it2 . pos ; }
friend inline bool operator > ( const reverse_iterator & it1 , const reverse_iterator & it2 ) { return it1 . pos > it2 . pos ; }
friend inline bool operator > = ( const reverse_iterator & it1 , const reverse_iterator & it2 ) { return it1 . pos > = it2 . pos ; }
inline bool operator = = ( const reverse_iterator & it ) const {
return ( pos = = it . pos ) ;
}
inline bool operator ! = ( const reverse_iterator & it ) const {
return ( pos ! = it . pos ) ;
}
friend inline bool operator < ( const reverse_iterator & it1 , const reverse_iterator & it2 ) {
return it1 . pos < it2 . pos ;
}
friend inline bool operator < = ( const reverse_iterator & it1 , const reverse_iterator & it2 ) {
return it1 . pos < = it2 . pos ;
}
friend inline bool operator > ( const reverse_iterator & it1 , const reverse_iterator & it2 ) {
return it1 . pos > it2 . pos ;
}
friend inline bool operator > = ( const reverse_iterator & it1 , const reverse_iterator & it2 ) {
return it1 . pos > = it2 . pos ;
}
} ;
class const_reverse_iterator {
@@ -310,56 +533,273 @@ public:
typedef std : : random_access_iterator_tag iterator_category ;
inline const_reverse_iterator ( ) : parent ( 0 ) , pos ( 0 ) { }
inline const T & operator * ( ) const { return ( * parent ) [ pos ] ; }
inline const T & operator - > ( ) const { return ( * parent ) [ pos ] ; }
inline const T & operator * ( ) const {
return ( * parent ) [ pos ] ;
}
inline const T & operator - > ( ) const {
return ( * parent ) [ pos ] ;
}
inline const_reverse_iterator & operator + + ( ) { - - pos ; return * this ; }
inline const_reverse_iterator & operator + + ( int ) { const auto tmp = * this ; - - * this ; return tmp ; }
inline const_reverse_iterator & operator - - ( ) { + + pos ; return * this ; }
inline const_reverse_iterator & operator - - ( int ) { const auto tmp = * this ; + + * this ; return tmp ; }
inline const_reverse_iterator & operator + + ( ) {
- - pos ;
return * this ;
}
inline const_reverse_iterator & operator + + ( int ) {
const auto tmp = * this ;
- - * this ;
return tmp ;
}
inline const_reverse_iterator & operator - - ( ) {
+ + pos ;
return * this ;
}
inline const_reverse_iterator & operator - - ( int ) {
const auto tmp = * this ;
+ + * this ;
return tmp ;
}
inline const_reverse_iterator & operator + = ( const const_reverse_iterator & it ) { pos - = it . pos ; return * this ; }
inline const_reverse_iterator & operator + = ( size_t p ) { pos - = p ; return * this ; }
inline const_reverse_iterator & operator - = ( const const_reverse_iterator & it ) { pos + = it . pos ; return * this ; }
inline const_reverse_iterator & operator - = ( size_t p ) { pos + = p ; return * this ; }
inline const_reverse_iterator & operator + = ( const const_reverse_iterator & it ) {
pos - = it . pos ;
return * this ;
}
inline const_reverse_iterator & operator + = ( size_t p ) {
pos - = p ;
return * this ;
}
inline const_reverse_iterator & operator - = ( const const_reverse_iterator & it ) {
pos + = it . pos ;
return * this ;
}
inline const_reverse_iterator & operator - = ( size_t p ) {
pos + = p ;
return * this ;
}
friend inline const_reverse_iterator operator - ( const const_reverse_iterator & it , size_t p ) { auto tmp = it ; tmp - = p ; return tmp ; }
friend inline const_reverse_itera tor operator - ( size_t p , const const_reverse_iterator & it ) { return it - p ; }
friend inline std : : ptrdiff_t operator - ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) { return it2 . pos - it1 . pos ; }
friend inline const_reverse_iterator operator - ( const const_reverse_iterator & it , size_t p ) {
au to tmp = it ;
tmp - = p ;
return tmp ;
}
friend inline const_reverse_iterator operator - ( size_t p , const const_reverse_iterator & it ) {
return it - p ;
}
friend inline std : : ptrdiff_t operator - ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) {
return it2 . pos - it1 . pos ;
}
friend inline const_reverse_iterator operator + ( const const_reverse_iterator & it , size_t p ) { auto tmp = it ; tmp + = p ; return tmp ; }
friend inline const_reverse_itera tor operator + ( size_t p , const const_reverse_iterator & it ) { return it + p ; }
friend inline const_reverse_iterator operator + ( const const_reverse_iterator & it , size_t p ) {
au to tmp = it ;
tmp + = p ;
return tmp ;
}
friend inline const_reverse_iterator operator + ( size_t p , const const_reverse_iterator & it ) {
return it + p ;
}
inline bool operator = = ( const const_reverse_iterator & it ) const { return ( pos = = it . pos ) ; }
inline bool operator ! = ( const const_reverse_iterator & it ) const { return ( pos ! = it . pos ) ; }
friend inline bool operator < ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) { return it1 . pos < it2 . pos ; }
friend inline bool operator < = ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) { return it1 . pos < = it2 . pos ; }
friend inline bool operator > ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) { return it1 . pos > it2 . pos ; }
friend inline bool operator > = ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) { return it1 . pos > = it2 . pos ; }
inline bool operator = = ( const const_reverse_iterator & it ) const {
return ( pos = = it . pos ) ;
}
inline bool operator ! = ( const const_reverse_iterator & it ) const {
return ( pos ! = it . pos ) ;
}
friend inline bool operator < ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) {
return it1 . pos < it2 . pos ;
}
friend inline bool operator < = ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) {
return it1 . pos < = it2 . pos ;
}
friend inline bool operator > ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) {
return it1 . pos > it2 . pos ;
}
friend inline bool operator > = ( const const_reverse_iterator & it1 , const const_reverse_iterator & it2 ) {
return it1 . pos > = it2 . pos ;
}
} ;
inline iterator begin ( ) { return iterator ( this , 0 ) ; }
inline iterator end ( ) { return iterator ( this , pid_size ) ; }
inline const_iterator begin ( ) const { return const_iterator ( this , 0 ) ; }
inline const_iterator end ( ) const { return const_iterator ( this , pid_size ) ; }
inline reverse_iterator rbegin ( ) { return reverse_iterator ( this , pid_size - 1 ) ; }
inline reverse_iterator rend ( ) { return reverse_iterator ( this , - 1 ) ; }
inline const_reverse_iterator rbegin ( ) const { return const_reverse_iterator ( this , pid_size - 1 ) ; }
inline const_reverse_iterator rend ( ) const { return const_reverse_iterator ( this , - 1 ) ; }
inline size_t size ( ) const { return pid_size ; }
inline ssize_t size_s ( ) const { return pid_size ; }
inline size_t length ( ) const { return pid_size ; }
inline size_t capacity ( ) const { return pid_rsize ; }
inline size_t _start ( ) const { return pid_start ; }
inline bool isEmpty ( ) const { return ( pid_size = = 0 ) ; }
inline bool isNotEmpty ( ) const { return ( pid_size > 0 ) ; }
//! \~\brief
//! \~english Iterator to the first element.
//! \~russian Итератор на первый элемент.
//! \~\details 
//!
//! \~english If the array is empty, the returned iterator is equal to \a end().
//! \~russian Если массив - пуст, возвращаемый итератор будет равен \a end().
//! \~\return \ref stl_iterators
//! \~\sa \a end(), \a rbegin(), \a rend()
inline iterator begin ( ) {
return iterator ( this , 0 ) ;
}
//! \~\brief
//! \~english Iterator to the element following the last element.
//! \~russian Итератор на элемент, следующий за последним элементом.
//! \~\details 
//!
//! \~english This element acts as a placeholder;
//! attempting to access it results in undefined behavior.
//! \~russian Этот элемент существует лишь условно,
//! попытка доступа к нему приведёт к выходу за разрешенную память.
//! \~\return \ref stl_iterators
//! \~\sa \a begin(), \a rbegin(), \a rend()
inline iterator end ( ) {
return iterator ( this , pid_size ) ;
}
inline const_iterator begin ( ) const {
return const_iterator ( this , 0 ) ;
}
inline const_iterator end ( ) const {
return const_iterator ( this , pid_size ) ;
}
//! \~\brief
//! \~english Returns a reverse iterator to the first element of the reversed array.
//! \~russian Обратный итератор на первый элемент.
//! \~\details 
//!
//! \~english It corresponds to the last element of the non-reversed array.
//! If the array is empty, the returned iterator is equal to \a rend().
//! \~russian Итератор для прохода массива в обратном порядке.
//! Указывает на последний элемент.
//! Если массив пустой, то совпадает с итератором \a rend().
//! \~\return \ref stl_iterators
//! \~\sa \a rend(), \a begin(), \a end()
inline reverse_iterator rbegin ( ) {
return reverse_iterator ( this , pid_size - 1 ) ;
}
//! \~\brief
//! \~english Returns a reverse iterator to the element
//! following the last element of the reversed array.
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
//! \~\details 
//!
//! \~english It corresponds to the element preceding the first element of the non-reversed array.
//! This element acts as a placeholder, attempting to access it results in undefined behavior.
//! \~russian Итератор для прохода массива в обратном порядке.
//! Указывает на элемент, предшествующий первому элементу.
//! Этот элемент существует лишь условно,
//! попытка доступа к нему приведёт к выходу за разрешенную память.
//! \~\return \ref stl_iterators
//! \~\sa \a rbegin(), \a begin(), \a end()
inline reverse_iterator rend ( ) {
return reverse_iterator ( this , - 1 ) ;
}
inline const_reverse_iterator rbegin ( ) const {
return const_reverse_iterator ( this , pid_size - 1 ) ;
}
inline const_reverse_iterator rend ( ) const {
return const_reverse_iterator ( this , - 1 ) ;
}
//! \~\brief
//! \~english Number of elements in the container.
//! \~russian Количество элементов массива.
//! \~\sa \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline size_t size ( ) const {
return pid_size ;
}
//! \~\brief
//! \~english Number of elements in the container as signed value.
//! \~russian Количество элементов массива в виде знакового числа.
//! \~\sa \a size(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline ssize_t size_s ( ) const {
return pid_size ;
}
//! \~\brief
//! \~english Same as \a size().
//! \~russian Синоним \a size().
//! \~\sa \a size(), \a size_s(), \a capacity(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline size_t length ( ) const {
return pid_size ;
}
//! \~\brief
//! \~english Number of elements that the container has currently allocated space for.
//! \~russian Количество элементов, для которого сейчас выделена память контейнером.
//! \~\details
//! \~english To find out the actual number of items, use the function \a size().
//! \~russian Чтобы узнать фактическое количество элементов используйте функцию \a size().
//! \~\sa \a reserve(), \a size(), \a size_s()
inline size_t capacity ( ) const {
return pid_rsize ;
}
inline size_t _start ( ) const {
return pid_start ;
}
//! \~\brief
//! \~english Checks if the container has no elements.
//! \~russian Проверяет пуст ли контейнер.
//! \~\return
//! \~english **true** if the container is empty, **false** otherwise
//! \~russian **true** если контейнер пуст, **false** иначе.
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline bool isEmpty ( ) const {
return ( pid_size = = 0 ) ;
}
//! \~\brief
//! \~english Checks if the container has elements.
//! \~russian Проверяет не пуст ли контейнер.
//! \~\return
//! \~english **true** if the container is not empty, **false** otherwise
//! \~russian **true** если контейнер не пуст, **false** иначе.
//! \~\sa \a size(), \a size_s(), \a isEmpty(), \a isNotEmpty(), \a resize(), \a reserve()
inline bool isNotEmpty ( ) const {
return ( pid_size > 0 ) ;
}
//! \~\brief
//! \~english Tests whether at least one element in the array
//! passes the test implemented by the provided function `test`.
//! \~russian Проверяет, удовлетворяет ли какой-либо элемент массива условию,
//! заданному в передаваемой функции `test`.
//! \~\return
//! \~english **true** if, in the array,
//! it finds an element for which the provided function returns **true**;
//! otherwise it returns **false**. Always returns **false** if is empty.
//! \~russian **true** если хотя бы для одного элемента
//! передаваемая функция возвращает **true**, в остальных случаях **false**.
//! Метод возвращает **false** при любом условии для пустого массива.
//! \~\details
//! \~\code
//! PIDeque<int> v{1, 2, 8, 9};
//! piCout << v.any([](int e){return e % 2 == 0;}); // true
//! piCout << v.any([](int e){return e == 3;}); // false
//! \endcode
//! \~\sa \a every(), \a contains(), \a etries(), \a forEach()
inline bool any ( std : : function < bool ( const T & e ) > test ) const {
for ( ssize_t i = pid_start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( test ( pid_data [ i ] ) ) return true ;
}
return false ;
}
//! \~\brief
//! \~english Tests whether all elements in the array passes the test
//! implemented by the provided function `test`.
//! \~russian Проверяет, удовлетворяют ли все элементы массива условию,
//! заданному в передаваемой функции `test`.
//! \~\return
//! \~english **true** if, in the array,
//! it finds an element for which the provided function returns **true**;
//! otherwise it returns **false**. Always returns **true** if is empty.
//! \~russian **true** если для всех элементов передаваемая функция возвращает **true**,
//! в остальных случаях **false**.
//! Метод возвращает **true** при любом условии для пустого массива.
//! \~\details
//! \~\code
//! PIDeque<int> v{1, 2, 8, 9};
//! piCout << v.every([](int e){return e % 2 == 0;}); // false
//! piCout << v.every([](int e){return e > 0;}); // true
//! \endcode
//! \~\sa \a any(), \a contains(), \a entries(), \a forEach()
inline bool every ( std : : function < bool ( const T & e ) > test ) const {
for ( ssize_t i = pid_start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( ! test ( pid_data [ i ] ) ) return false ;
@@ -367,64 +807,248 @@ public:
return true ;
}
//! \brief
//! \~english Full access to element by `index`.
//! \~russian Полный доступ к элементу по индексу `index`.
//! \~\details
//! \~english Element index starts from `0`.
//! Element index must be in range from `0` to `size()-1`.
//! Otherwise will be undefined behavior.
//! \~russian Индекс элемента считается от `0`.
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
//! \~\code
//! PIDeque<int> v{1, 2, 8, 9};
//! piCout << v[2]; // 8
//! v[2] = 5;
//! piCout << v; // {1, 2, 5, 9}
//! \endcode
//! \~\sa \a at()
inline T & operator [ ] ( size_t index ) {
return pid_data [ pid_start + index ] ;
}
inline const T & operator [ ] ( size_t index ) const {
return pid_data [ pid_start + index ] ;
}
inline T & operator [ ] ( size_t index ) { return pid_data [ pid_start + index ] ; }
inline const T & operator [ ] ( size_t index ) const { return pid_data [ pid_start + index ] ; }
inline const T & at ( size_t index ) const { return pid_data [ pid_start + index ] ; }
inline T & back ( ) { return pid_data [ pid_start + pid_size - 1 ] ; }
inline const T & back ( ) const { return pid_data [ pid_start + pid_size - 1 ] ; }
inline T & front ( ) { return pid_data [ pid_start ] ; }
inline const T & front ( ) const { return pid_data [ pid_start ] ; }
//! \brief
//! \~english Read only access to element by `index`.
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
//! \~\details
//! \~english Element index starts from `0`.
//! Element index must be in range from `0` to `size()-1`.
//! Otherwise will be undefined behavior.
//! \~russian Индекс элемента считается от `0`.
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
inline const T & at ( size_t index ) const {
return pid_data [ pid_start + index ] ;
}
//! \brief
//! \~english Last element.
//! \~russian Последний элемент массива.
//! \~\details
//! \~english Returns a reference to the last item in the array.
//! This function assumes that the array isn't empty.
//! Otherwise will be undefined behavior.
//! \~russian Возвращает ссылку на последний элемент в массиве.
//! Эта функция предполагает, что массив не пустой.
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
inline T & back ( ) {
return pid_data [ pid_start + pid_size - 1 ] ;
}
inline const T & back ( ) const {
return pid_data [ pid_start + pid_size - 1 ] ;
}
//! \brief
//! \~english Last element.
//! \~russian Первый элемент массива.
//! \~\details
//! \~english Returns a reference to the last item in the array.
//! This function assumes that the array isn't empty.
//! Otherwise will be undefined behavior.
//! \~russian Возвращает ссылку на пенрвый элемент в массиве.
//! Эта функция предполагает, что массив не пустой.
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
inline T & front ( ) {
return pid_data [ pid_start ] ;
}
inline const T & front ( ) const {
return pid_data [ pid_start ] ;
}
//! \brief
//! \~english Compare operator with array `v`.
//! \~russian Оператор сравнения с массивом `v`.
inline bool operator = = ( const PIDeque < T > & v ) const {
if ( pid_size ! = v . pid_size ) return false ;
for ( size_t i = 0 ; i < pid_size ; + + i ) {
if ( v [ i ] ! = ( * this ) [ i ] ) {
return false ;
}
if ( v [ i ] ! = ( * this ) [ i ] ) return false ;
}
return true ;
}
inline bool operator ! = ( const PIDeque < T > & v ) const { return ! ( * this = = v ) ; }
inline bool operator < ( const PIDeque < T > & v ) const {
if ( pid_size ! = v . pid_size ) return pid_size < v . pid_size ;
for ( size_t i = 0 ; i < pid_size ; + + i ) {
if ( ( * this ) [ i ] ! = v [ i ] ) return ( * this ) [ i ] < v [ i ] ;
}
return false ;
}
inline bool operator > ( const PIDeque < T > & v ) const {
if ( pid_size ! = v . pid_size ) return pid_size > v . pid_size ;
for ( size_t i = 0 ; i < pid_size ; + + i ) {
if ( ( * this ) [ i ] ! = v [ i ] ) return ( * this ) [ i ] > v [ i ] ;
}
return false ;
}
inline bool contains ( const T & e ) const {
for ( ssize_t i = pid_start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( e = = pid_data [ i ] ) {
return true ;
}
//! \brief
//! \~english Compare operator with array `v`.
//! \~russian Оператор сравнения с массивом `v`.
inline bool operator ! = ( const PIDeque < T > & v ) const {
return ! ( * this = = v ) ;
}
//! \~\brief
//! \~english Tests if element `e` exists in the array.
//! \~russian Проверяет наличие элемента `e` в массиве.
//! \~\details
//! \~english Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! **false** is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается **false**, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\code
//! PIDeque<int> v{1, 2, 3, 4};
//! piCout << v.contains(3); // true
//! piCout << v.contains(5); // false
//! piCout << v.contains(3, 3); // false
//! piCout << v.contains(3, -2); // true
//! piCout << v.contains(3, -99); // true
//! \endcode
//! \~\return
//! \~english **true** if the array contains an occurrence of element `e`,
//! otherwise it returns **false**.
//! \~russian **true** если элемент `e` присутствует в массиве,
//! в остальных случаях **false**.
//! \~\sa \a every(), \a any(), \a etries(), \a forEach()
inline bool contains ( const T & e , ssize_t start = 0 ) const {
if ( start < 0 ) {
start = pid_size + start ;
if ( start < 0 ) start = 0 ;
}
for ( ssize_t i = pid_start + start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( e = = pid_data [ i ] ) return true ;
}
return false ;
}
//! \~\brief
//! \~english Count elements equal `e` in the array.
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
//! \~\details
//! \~english Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! 0 is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается 0, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\code
//! PIDeque<int> v{2, 2, 4, 2, 6};
//! piCout << v.entries(2); // 3
//! piCout << v.entries(2, 2); // 1
//! piCout << v.entries(2, -4); // 2
//! \endcode
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexOf()
inline int etries ( const T & e , size_t start = 0 ) const {
int ec = 0 ;
if ( start > = pid_size ) return ec ;
if ( start < 0 ) {
start = pid_size + start ;
if ( start < 0 ) start = 0 ;
}
for ( ssize_t i = pid_start + start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( e = = pid_data [ i ] ) + + ec ;
}
return ec ;
}
//! \~\brief
//! \~english Count elements in the array passes the test implemented by the provided function `test`.
//! \~russian Подсчитывает количество элементов в массиве,
//! проходящих по условию, заданному в передаваемой функции `test`.
//! \~\details
//! \~english Overloaded function.
//! Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! 0 is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Перегруженная функция.
//! Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается 0, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\sa \a every(), \a any(), \a contains(), \a forEach(), \a indexWhere()
inline int etries ( std : : function < bool ( const T & e ) > test , size_t start = 0 ) const {
int ec = 0 ;
if ( start > = pid_size ) return ec ;
if ( start < 0 ) {
start = pid_size + start ;
if ( start < 0 ) start = 0 ;
}
for ( ssize_t i = pid_start + start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( test ( pid_data [ i ] ) ) + + ec ;
}
return ec ;
}
//! \~\brief
//! \~english Returns the first index at which a given element `e`
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает первый индекс, по которому данный элемент `e`
//! может быть найден в массиве или `-1`, если такого индекса нет.
//! \~\details
//! \~english Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! `-1` is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается `-1`, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\code
//! PIDeque<int> v{2, 5, 9};
//! piCout << v.indexOf(2); // 0
//! piCout << v.indexOf(7); // -1
//! piCout << v.indexOf(9, 2); // 2
//! piCout << v.indexOf(2, -1); // -1
//! piCout << v.indexOf(2, -3); // 0
//! \endcode
//! \~\sa \a indexWhere(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
inline ssize_t indexOf ( const T & e , size_t start = 0 ) const {
if ( start > = pid_size ) return - 1 ;
if ( start < 0 ) {
start = pid_size + start ;
if ( start < 0 ) start = 0 ;
}
for ( ssize_t i = pid_start + start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( e = = pid_data [ i ] ) {
return i - pid_start ;
@@ -432,8 +1056,41 @@ public:
}
return - 1 ;
}
//! \~\brief
//! \~english Returns the first index passes the test implemented by the provided function `test`,
//! or `-1` if it is not present.
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает первый индекс элемента проходящего по условию,
//! заданному в передаваемой функции `test`, или `-1`, если таких элементов нет.
//! \~\details
//! \~english Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! `-1` is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается `-1`, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\code
//! PIDeque<PIString> v{"do", "re", "mi", "re"};
//! piCout << v.indexWhere([](const PIString & s){return s.startsWith('r');}); // 1
//! piCout << v.indexWhere([](const PIString & s){return s.startsWith('r');}, 2); // 3
//! piCout << v.indexWhere([](const PIString & s){return s.startsWith('k');}); // -1
//! \endcode
//! \~\sa \a indexOf(), \a lastIndexOf(), \a lastIndexWhere(), \a contains()
inline ssize_t indexWhere ( std : : function < bool ( const T & e ) > test , size_t start = 0 ) const {
if ( start > = pid_size ) return - 1 ;
if ( start < 0 ) {
start = pid_size + start ;
if ( start < 0 ) start = 0 ;
}
for ( ssize_t i = pid_start + start ; i < pid_start + ( ssize_t ) pid_size ; + + i ) {
if ( test ( pid_data [ i ] ) ) {
return i - pid_start ;
@@ -441,9 +1098,45 @@ public:
}
return - 1 ;
}
//! \~\brief
//! \~english Returns the last index at which a given element `e`
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает последний индекс, по которому данный элемент `e`
//! может быть найден в массиве или `-1`, если такого индекса нет.
//! \~\details
//! \~english Optional argument `start` - the position in this array
//! at which to start searching backwards.
//! If the index is greater than or equal to the array's size,
//! causes the whole array to be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Therefore, if calculated index less than 0,
//! the array is not searched, and the method returns `-1`.
//! Note: if the provided index is negative,
//! the array is still searched from back to front.
//! Default: -1 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс
//! c которого начинать поиск в обратном направлении.
//! Если индекс больше или равен длине массива, просматривается весь массив.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от конца к началу.
//! Если рассчитанный индекс оказывается меньше 0, массив даже не просматривается.
//! Значение по умолчанию равно `-1`, что равно индексу последнего элемента
//! и означает, что просматривается весь массив.
//! \~\code
//! PIDeque<int> v{2, 5, 9, 2};
//! piCout << v.lastIndexOf(2); // 3
//! piCout << v.lastIndexOf(7); // -1
//! piCout << v.lastIndexOf(2, 2); // 0
//! piCout << v.lastIndexOf(2, -3); // 0
//! piCout << v.lastIndexOf(2, -300); // -1
//! piCout << v.lastIndexOf(2, 300); // 3
//! \endcode
//! \~\sa \a indexOf(), \a indexWhere(), \a lastIndexWhere(), \a contains()
inline ssize_t lastIndexOf ( const T & e , ssize_t start = - 1 ) const {
if ( start < 0 ) start = pid_size - 1 ;
else start = piMin < ssize_t > ( pid_size - 1 , start ) ;
if ( start > = size_s ( ) ) start = pid_size - 1 ;
if ( start < 0 ) start = pid_size + start ;
for ( ssize_t i = pid_start + start ; i > = pid_start ; - - i ) {
if ( e = = pid_data [ i ] ) {
return i - pid_start ;
@@ -451,9 +1144,36 @@ public:
}
return - 1 ;
}
//! \~\brief
//! \~english Returns the last index passes the test implemented by the provided function `test`,
//! or `-1` if it is not present.
//! \~russian Возвращает последний индекс элемента проходящего по условию,
//! заданному в передаваемой функции `test`, или `-1`, если таких элементов нет.
//! \~\details
//! \~english Optional argument `start` - the position in this array
//! at which to start searching backwards.
//! If the index is greater than or equal to the array's size,
//! causes the whole array to be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Therefore, if calculated index less than 0,
//! the array is not searched, and the method returns `-1`.
//! Note: if the provided index is negative,
//! the array is still searched from back to front.
//! Default: -1 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс
//! c которого начинать поиск в обратном направлении.
//! Если индекс больше или равен длине массива, просматривается весь массив.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от конца к началу.
//! Если рассчитанный индекс оказывается меньше 0, массив даже не просматривается.
//! Значение по умолчанию равно `-1`, что равно индексу последнего элемента
//! и означает, что просматривается весь массив.
//! \~\sa \a indexOf(), \a lastIndexOf(), \a indexWhere(), \a contains()
inline ssize_t lastIndexWhere ( std : : function < bool ( const T & e ) > test , ssize_t start = - 1 ) const {
if ( start < 0 ) start = pid_size - 1 ;
else start = piMin < ssize_t > ( pid_size - 1 , start ) ;
if ( start > = size_s ( ) ) start = pid_size - 1 ;
if ( start < 0 ) start = pid_size + start ;
for ( ssize_t i = pid_start + start ; i > = pid_start ; - - i ) {
if ( test ( pid_data [ i ] ) ) {
return i - pid_start ;
@@ -462,15 +1182,76 @@ public:
return - 1 ;
}
inline T * data ( size_t index = 0 ) { return & ( pid_data [ pid_start + index ] ) ; }
inline const T * data ( size_t index = 0 ) const { return & ( pid_data [ pid_start + index ] ) ; }
//! \~\brief
//! \~english Pointer to array
//! \~russian Указатель на память массива
//! \~\details
//! \~english Optional argument `index` the position in this array,
//! where is pointer. Default: start of array.
//! \~russian Опциональный аргумент `index` указывает на индекс c которого брать указатель.
//! По умолчанию указывает на начало массива.
//! \~\code
//! PIDeque<int> v{2, 5, 9, 2};
//! int a[2] = {12, 13};
//! memcpy(vec.data(1), carr, 2 * sizeof(int));
//! piCout << v; // {2, 12, 13, 2}
//! \endcode
inline T * data ( size_t index = 0 ) {
return & ( pid_data [ pid_start + index ] ) ;
}
//! \~\brief
//! \~english Read only pointer to array
//! \~russian Указатель на память массива только для чтения.
//! \~\details
//! \~english The pointer can be used to access and modify the items in the array.
//! The pointer remains valid as long as the array isn't reallocated.
//! Optional argument `index` the position in this array,
//! where is pointer. Default: start of array.
//! \~russian Указатель можно использовать для доступа и изменения элементов в массиве.
//! Указатель остается действительным только до тех пор, пока массив не будет перераспределен.
//! Опциональный аргумент `index` указывает на индекс c которого брать указатель.
//! По умолчанию указывает на начало массива.
//! \~\code
//! PIDeque<int> v{1, 3, 5};
//! int a[3];
//! memcpy(a, v.data(), a.size() * sizeof(int));
//! piCout << a[0] << a[1] << a[2]; // 1 3 5
//! \endcode
inline const T * data ( size_t index = 0 ) const {
return & ( pid_data [ pid_start + index ] ) ;
}
//! \~\brief
//! \~english Creates sub-array of this array.
//! \~russian Создает подмассив, то есть кусок из текущего массива.
//! \~english
//! \param index - index of this array where sub-array starts
//! \param count - sub-array size
//! \~russian
//! \param index - индекс в текущем массиве, откуда начинётся подмассив
//! \param count - размер подмассива
//! \~\details
//! \~english
//! Index must be in range from `0` to `size()-1`.
//! If sub-array size more than this array size, than ends early.
//! \~russian
//! Индекс начала должен лежать в диапазоне от `0` до `size()-1`.
//! Если заданный размер подмассива превышает размер текущего массива,
//! то вернется подмассив меншего размера (`size()-index-1`).
PIDeque < T > getRange ( size_t index , size_t count ) const {
if ( index > = pid_size | | count = = 0 ) return PIDeque < T > ( ) ;
if ( index + count > pid_size ) count = pid_size - index ;
return PIDeque ( & ( pid_data [ pid_start + index ] ) , count ) ;
}
//! \~\brief
//! \~english Clear array, remove all elements.
//! \~russian Очищает массив, удаляет все элементы.
//! \~\details
//! \~english Note: reserved memory will not be released.
//! \~russian Замечание: зарезервированная память не освободится.
//! \~\sa \a resize()
template < typename T1 = T , typename std : : enable_if <
! std : : is_trivially_copyable < T1 > : : value
, int > : : type = 0 >
@@ -488,14 +1269,35 @@ public:
return * this ;
}
inline PIDeque < T > & fill ( const T & f = T ( ) ) {
//! \~\brief
//! \~english Assigns element 'e' to all items in the array.
//! \~russian Заполняет весь массив копиями элемента 'e'.
//! \~\details
//! \code
//! PIDeque<int> v{1, 3, 5};
//! v.fill(7);
//! piCout << v; // {7, 7, 7}
//! \endcode
//! \~\sa \a resize()
inline PIDeque < T > & fill ( const T & e = T ( ) ) {
deleteT ( pid_data + pid_start , pid_size ) ;
PIINTROSPECTION_CONTAINER_USED ( T , pid_size )
for ( size_t i = pid_start ; i < pid_start + pid_size ; + + i ) {
elementNew ( pid_data + i , f ) ;
elementNew ( pid_data + i , e ) ;
}
return * this ;
}
//! \~\brief
//! \~english Assigns result of function 'f(size_t i)' to all items in the array.
//! \~russian Заполняет весь массив результатом вызова функции 'f(size_t i)'.
//! \~\details
//! \code
//! PIDeque<int> v{1, 3, 5};
//! v.fill([](size_t i){return i*2;});
//! piCout << v; // {0, 2, 4}
//! \endcode
//! \~\sa \a resize()
inline PIDeque < T > & fill ( std : : function < T ( size_t i ) > f ) {
deleteT ( pid_data + pid_start , pid_size ) ;
PIINTROSPECTION_CONTAINER_USED ( T , pid_size )
@@ -504,23 +1306,47 @@ public:
}
return * this ;
}
inline PIDeque < T > & assign ( const T & f = T ( ) ) { return fill ( f ) ; }
//! \~\brief
//! \~english Same as \a fill().
//! \~russian Тоже самое что и \a fill().
//! \~\sa \a fill(), \a resize()
inline PIDeque < T > & assign ( const T & e = T ( ) ) {
return fill ( e ) ;
}
//! \~\brief
//! \~english First does `resize(new_size)` then `fill(e)`.
//! \~russian Сначала делает `resize(new_size)` затем `fill(e)`.
//! \~\sa \a fill(), \a resize()
template < typename T1 = T , typename std : : enable_if <
! std : : is_trivially_copyable < T1 > : : value
, int > : : type = 0 >
inline PIDeque < T > & assign ( size_t new_size , const T & f ) {
inline PIDeque < T > & assign ( size_t new_size , const T & e ) {
resize ( new_size ) ;
return fill ( f ) ;
return fill ( e ) ;
}
template < typename T1 = T , typename std : : enable_if <
std : : is_trivially_copyable < T1 > : : value
, int > : : type = 0 >
inline PIDeque < T > & assign ( size_t new_size , const T & f ) {
inline PIDeque < T > & assign ( size_t new_size , const T & e ) {
_resizeRaw ( new_size ) ;
return fill ( f ) ;
return fill ( e ) ;
}
inline PIDeque < T > & resize ( size_t new_size , const T & f = T ( ) ) {
//! \~\brief
//! \~english Sets size of the array, new elements are copied from `e`.
//! \~russian Устанавливает размер массива, новые элементы копируются из `e`.
//! \~\details
//! \~english If `new_size` is greater than the current \a size(),
//! elements are added to the end; the new elements are initialized from `e`.
//! If `new_size` is less than the current \a size(), elements are removed from the end.
//! \~russian Если `new_size` больше чем текущий размер массива \a size(),
//! новые элементы добавляются в конец массива и создаются из `e`.
//! Если `new_size` меньше чем текущий размер массива \a size(),
//! лишние элементы удаляются с конца массива.
//! \~\sa \a size(), \a clear()
inline PIDeque < T > & resize ( size_t new_size , const T & e = T ( ) ) {
if ( new_size < pid_size ) {
deleteT ( & ( pid_data [ new_size + pid_start ] ) , pid_size - new_size ) ;
pid_size = new_size ;
@@ -533,11 +1359,24 @@ public:
alloc_forward ( new_size ) ;
PIINTROSPECTION_CONTAINER_USED ( T , ( new_size - os ) )
for ( size_t i = os + pid_start ; i < new_size + pid_start ; + + i ) {
elementNew ( pid_data + i , f ) ;
elementNew ( pid_data + i , e ) ;
}
}
return * this ;
}
//! \~\brief
//! \~english Sets size of the array, new elements created by function `f(size_t i)`.
//! \~russian Устанавливает размер массива, новые элементы создаются функцией `f(size_t i)`.
//! \~\details
//! \~english If `new_size` is greater than the current \a size(),
//! elements are added to the end; the new elements created by function `f(size_t i)`.
//! If `new_size` is less than the current \a size(), elements are removed from the end.
//! \~russian Если `new_size` больше чем текущий размер массива \a size(),
//! новые элементы добавляются в конец массива и функцией `f(size_t i)`.
//! Если `new_size` меньше чем текущий размер массива \a size(),
//! лишние элементы удаляются с конца массива.
//! \~\sa \a size(), \a clear()
inline PIDeque < T > & resize ( size_t new_size , std : : function < T ( size_t i ) > f ) {
if ( new_size < pid_size ) {
deleteT ( & ( pid_data [ new_size + pid_start ] ) , pid_size - new_size ) ;
@@ -571,6 +1410,25 @@ public:
return * this ;
}
inline void _copyRaw ( T * dst , const T * src , size_t size ) {
newT ( dst , src , size ) ;
}
//! \~\brief
//! \~english Attempts to allocate memory for at least `new_size` elements.
//! \~russian Резервируется память под как минимум `new_size` элементов.
//! \~\details
//! \~english If you know in advance how large the array will be,
//! you should call this function to prevent reallocations and memory fragmentation.
//! If `new_size` is greater than the current \a capacity(),
//! new storage is allocated, otherwise the function does nothing.
//! This function does not change the \a size() of the array.
//! \~russian Если вы заранее знаете, насколько велик будет массив,
//! вы можете вызвать эту функцию, чтобы предотвратить перераспределение и фрагментацию памяти.
//! Если размер `new_size` больше чем выделенная память \a capacity(),
//! то произойдёт выделение новой памяти и перераспределение массива.
//! Эта функция не изменяет количество элементов в массиве \a size().
//! \~\sa \a size(), \a capacity(), \a resize()
inline PIDeque < T > & reserve ( size_t new_size ) {
if ( new_size < = pid_rsize ) return * this ;
size_t os = pid_size ;
@@ -579,6 +1437,18 @@ public:
return * this ;
}
//! \~\brief
//! \~english Inserts value `e` at `index` position in the array.
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
//! \~\details
//! \~english The index must be greater than 0 and less than or equal to \a size().
//! \~russian Индекс должен быть больше 0 и меньше или равен \a size().
//! \code
//! PIDeque<int> v{1, 3, 5};
//! v.insert(2, 7);
//! piCout << v; // {1, 3, 7, 5}
//! \endcode
//! \~\sa \a append(), \a prepend(), \a remove()
inline PIDeque < T > & insert ( size_t index , const T & e = T ( ) ) {
if ( index = = pid_size ) return push_back ( e ) ;
PIINTROSPECTION_CONTAINER_USED ( T , 1 )
@@ -598,6 +1468,14 @@ public:
elementNew ( pid_data + pid_start + index , e ) ;
return * this ;
}
//! \~\brief
//! \~english Inserts value `e` at `index` position in the array.
//! \~russian Вставляет значение `e` в позицию `index` в массиве.
//! \~\details
//! \~english The index must be greater than 0 and less than or equal to \a size().
//! \~russian Индекс должен быть больше 0 и меньше или равен \a size().
//! \~\sa \a append(), \a prepend(), \a remove()
inline PIDeque < T > & insert ( size_t index , T & & e ) {
if ( index = = pid_size ) return push_back ( e ) ;
PIINTROSPECTION_CONTAINER_USED ( T , 1 )
@@ -617,31 +1495,78 @@ public:
elementNew ( pid_data + pid_start + index , std : : move ( e ) ) ;
return * this ;
}
inline PIDeque < T > & insert ( size_t index , const PIDeque < T > & other ) {
if ( other . isEmpty ( ) ) return * this ;
//! \~\brief
//! \~english Inserts array `v` at `index` position in the array.
//! \~russian Вставляет массив `v` в позицию `index` в массиве.
//! \~\details
//! \~english The index must be greater than or equal to 0 and less than or equal to \a size().
//! \~russian Индекс должен быть больше или равен 0 и меньше или равен \a size().
//! \~\sa \a append(), \a prepend(), \a remove()
inline PIDeque < T > & insert ( size_t index , const PIDeque < T > & v ) {
if ( v . isEmpty ( ) ) return * this ;
# ifndef NDEBUG
if ( & other = = this ) {
if ( & v = = this ) {
printf ( " error with PIDeque<%s>::insert \n " , __PIP_TYPENAME__ ( T ) ) ;
}
# endif
assert ( & other ! = this ) ;
assert ( & v ! = this ) ;
bool dir = pid_rsize < = 2 ? true : ( index > = pid_rsize / 2 ? true : false ) ;
if ( dir ) {
ssize_t os = pid_size - index ;
alloc_forward ( pid_size + other . pid_size ) ;
alloc_forward ( pid_size + v . pid_size ) ;
if ( os > 0 ) {
memmove ( ( void * ) ( & ( pid_data [ index + pid_start + other . pid_size ] ) ) , ( const void * ) ( & ( pid_data [ index + pid_start ] ) ) , os * sizeof ( T ) ) ;
memmove ( ( void * ) ( & ( pid_data [ index + pid_start + v . pid_size ] ) ) , ( const void * ) ( & ( pid_data [ index + pid_start ] ) ) , os * sizeof ( T ) ) ;
}
} else {
alloc_backward ( pid_size + other . pid_size , - other . pid_size ) ;
alloc_backward ( pid_size + v . pid_size , - v . pid_size ) ;
if ( index > 0 ) {
memmove ( ( void * ) ( & ( pid_data [ pid_start ] ) ) , ( const void * ) ( & ( pid_data [ pid_start + other . pid_size ] ) ) , index * sizeof ( T ) ) ;
memmove ( ( void * ) ( & ( pid_data [ pid_start ] ) ) , ( const void * ) ( & ( pid_data [ pid_start + v . pid_size ] ) ) , index * sizeof ( T ) ) ;
}
}
newT ( pid_data + pid_start + index , other . pid_data + other . pid_start , other . pid_size ) ;
newT ( pid_data + pid_start + index , v . pid_data + v . pid_start , v . pid_size ) ;
return * this ;
}
//! \~\brief
//! \~english Inserts the given elements at `index` position in the array.
//! \~russian Вставляет элементы в позицию `index` в массиве.
//! \~\details
//! \~english The index must be greater than or equal to 0 and less than or equal to \a size().
//! Inserts the given elements from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Индекс должен быть больше или равен 0 и меньше или равен \a size().
//! Вставляет элементы из
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
//! \~\sa \a append(), \a prepend(), \a remove()
inline PIDeque < T > & insert ( size_t index , std : : initializer_list < T > init_list ) {
bool dir = pid_rsize < = 2 ? true : ( index > = pid_rsize / 2 ? true : false ) ;
if ( dir ) {
ssize_t os = pid_size - index ;
alloc_forward ( pid_size + init_list . size ( ) ) ;
if ( os > 0 ) {
memmove ( ( void * ) ( & ( pid_data [ index + pid_start + init_list . size ( ) ] ) ) , ( const void * ) ( & ( pid_data [ index + pid_start ] ) ) , os * sizeof ( T ) ) ;
}
} else {
alloc_backward ( pid_size + init_list . size ( ) , - init_list . size ( ) ) ;
if ( index > 0 ) {
memmove ( ( void * ) ( & ( pid_data [ pid_start ] ) ) , ( const void * ) ( & ( pid_data [ pid_start + init_list . size ( ) ] ) ) , index * sizeof ( T ) ) ;
}
}
newT ( pid_data + pid_start + index , init_list . begin ( ) , init_list . size ( ) ) ;
return * this ;
}
//! \~\brief
//! \~english Removes `count` elements from the middle of the array, starting at `index` position.
//! \~russian Удаляет элементы из массива, начиная с позиции `index`, в количестве `count`.
//! \~\details
//! \code
//! PIDeque<int> v{1, 3, 7, 5};
//! v.remove(1, 2);
//! piCout << v; // {1, 5}
//! \endcode
//! \~\sa \a resize(), \a insert(), \a removeOne(), \a removeAll(), \a removeWhere()
inline PIDeque < T > & remove ( size_t index , size_t count = 1 ) {
if ( count = = 0 ) return * this ;
if ( index + count > = pid_size ) {
@@ -664,6 +1589,12 @@ public:
return * this ;
}
//! \~\brief
//! \~english Swaps array `v` other with this array.
//! \~russian Меняет местами массив `v` с этим массивом.
//! \~\details
//! \~english This operation is very fast and never fails.
//! \~russian Эта операция выполняется мгновенно без копирования памяти и никогда не дает сбоев.
inline void swap ( PIDeque < T > & other ) {
piSwap < T * > ( pid_data , other . pid_data ) ;
piSwap < size_t > ( pid_size , other . pid_size ) ;
@@ -733,6 +1664,57 @@ public:
return * this ;
}
//! \~\brief
//! \~english Reverses this array.
//! \~russian Обращает порядок следования элементов этого массива.
//! \~\details
//! \~english This method reverses an array [in place](https://en.wikipedia.org/wiki/In-place_algorithm).
//! The first array element becomes the last, and the last array element becomes the first.
//! The reverse method transposes the elements of the calling array object in place,
//! mutating the array, and returning a reference to the array.
//! \~russian Метод reverse() на месте переставляет элементы массива,
//! на котором он был вызван, изменяет массив и возвращает ссылку на него.
//! Первый элемент массива становится последним, а последний — первым.
//! \~\code
//! PIDeque<int> v{1, 3, 7, 5};
//! v.reverse();
//! piCout << v; // {5, 7, 3, 1}
//! \endcode
//! \~\sa \a reversed()
inline PIDeque < T > & reverse ( ) {
size_t s2 = pid_size / 2 ;
for ( size_t i = 0 ; i < s2 ; + + i ) {
piSwap < T > ( pid_data [ pid_start + i ] , pid_data [ pid_start + pid_size - i - 1 ] ) ;
}
return * this ;
}
//! \~\brief
//! \~english Returns reversed array.
//! \~russian Возвращает перевернутый массив.
//! \~\details
//! \~english Returns a copy of the array with elements in reverse order.
//! The first array element becomes the last, and the last array element becomes the first.
//! \~russian Возвращает копию массива с элементами в обратном порядке.
//! Первый элемент массива становится последним, а последний — первым.
//! \~\sa \a reverse()
inline PIDeque < T > reversed ( ) const {
PIDeque < T > ret ( * this ) ;
return ret . reverse ( ) ;
}
//! \~\brief
//! \~english Increases or decreases the size of the array by `add_size` elements.
//! \~russian Увеличивает или уменьшает размер массива на `add_size` элементов.
//! \~\details
//! \~english If `add_size > 0` then elements are added to the end of the array.
//! If `add_size < 0` then elements are removed from the end of the array.
//! If `add_size < 0` and there are fewer elements in the array than specified, then the array becomes empty.
//! \~russian Если `add_size > 0` то в конец массива добавляются элементы.
//! Если `add_size < 0` то с конца массива удаляются элементы.
//! Если `add_size < 0` и в массиве меньше элементов чем указано, то массив становится пустым.
//! \~\sa \a resize()
inline PIDeque < T > & enlarge ( llong pid_size ) {
llong ns = size_s ( ) + pid_size ;
if ( ns < = 0 ) clear ( ) ;
@@ -740,6 +1722,16 @@ public:
return * this ;
}
//! \brief
//! \~english Remove no more than one element equal `e`.
//! \~russian Удаляет первый элемент, который равен элементу `e`.
//! \~\details
//! \~\code
//! PIDeque<int> v{3, 2, 5, 2, 7};
//! v.removeOne(2);
//! piCout << v; // {3, 5, 2, 7}
//! \endcode
//! \~\sa \a remove(), \a removeAll(), \a removeWhere()
inline PIDeque < T > & removeOne ( const T & e ) {
for ( size_t i = 0 ; i < pid_size ; + + i ) {
if ( pid_data [ i + pid_start ] = = e ) {
@@ -749,6 +1741,17 @@ public:
}
return * this ;
}
//! \brief
//! \~english Remove all elements equal `e`.
//! \~russian Удаляет все элементы, равные элементу `e`.
//! \~\details
//! \~\code
//! PIDeque<int> v{3, 2, 5, 2, 7};
//! v.removeAll(2);
//! piCout << v; // {3, 5, 7}
//! \endcode
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
inline PIDeque < T > & removeAll ( const T & e ) {
for ( ssize_t i = 0 ; i < ssize_t ( pid_size ) ; + + i ) {
if ( pid_data [ i + pid_start ] = = e ) {
@@ -758,6 +1761,19 @@ public:
}
return * this ;
}
//! \brief
//! \~english Remove all elements in the array
//! passes the test implemented by the provided function `test`.
//! \~russian Удаляет все элементы, удовлетворяющие условию,
//! заданному в передаваемой функции `test`.
//! \~\details
//! \~\code
//! PIDeque<int> v{3, 2, 5, 2, 7};
//! v.removeWhere([](const int & i){return i > 2;});
//! piCout << v; // {2, 2}
//! \endcode
//! \~\sa \a remove(), \a removeOne(), \a removeWhere()
inline PIDeque < T > & removeWhere ( std : : function < bool ( const T & e ) > test ) {
for ( ssize_t i = 0 ; i < ssize_t ( pid_size ) ; + + i ) {
if ( test ( pid_data [ i + pid_start ] ) ) {
@@ -768,21 +1784,78 @@ public:
return * this ;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
//! \~english If size() is less than capacity(), which is most often
//! then the addition will be very fast.
//! In any case, the addition is fast and does not depend on the size of the array.
//! If the new size() is greater than capacity()
//! then all iterators and references
//! (including the past-the-end iterator) are invalidated.
//! Otherwise only the past-the-end iterator is invalidated.
//! \~russian Если size() меньше capacity(), что чаше всего,
//! то добавление будет очень быстрым.
//! В любом случае добавление быстрое и не зависит от размера массива.
//! Если новый size() больше, чем capacity(),
//! то все итераторы и указатели становятся нерабочими.
//! В противном случае, все, кроме итераторов указывающих на конец массива,
//! остаются в рабочем состоянии.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.push_back(4);
//! v.push_back(5);
//! piCout << v; // {1, 2, 3, 4, 5}
//! \endcode
//! \~\sa \a push_front(), \a append(), \a prepend(), \a insert()
inline PIDeque < T > & push_back ( const T & e ) {
alloc_forward ( pid_size + 1 ) ;
PIINTROSPECTION_CONTAINER_USED ( T , 1 ) ;
elementNew ( pid_data + pid_start + pid_size - 1 , e ) ;
return * this ;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\sa \a push_back()
inline PIDeque < T > & push_back ( T & & e ) {
alloc_forward ( pid_size + 1 ) ;
PIINTROSPECTION_CONTAINER_USED ( T , 1 ) ;
elementNew ( pid_data + pid_start + pid_size - 1 , std : : move ( e ) ) ;
return * this ;
}
inline PIDeque < T > & append ( const T & e ) { return push_back ( e ) ; }
inline PIDeque < T > & append ( T & & e ) { return push_back ( std : : move ( e ) ) ; }
inline PIDeque < T > & append ( const PIDeque < T > & v ) {
//! \brief
//! \~english Appends the given elements to the end of the array.
//! \~russian Добавляет элементы в конец массива.
//! \~\details
//! \~english Overloaded function.
//! Appends the given elements from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Перегруженая функция.
//! Добавляет элементы из
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
//! \~\sa \a push_back()
inline PIDeque < T > & push_back ( std : : initializer_list < T > init_list ) {
size_t ps = pid_size ;
alloc_forward ( pid_size + init_list . size ( ) ) ;
newT ( pid_data + pid_start + ps , init_list . begin ( ) , init_list . size ( ) ) ;
return * this ;
}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\sa \a push_back()
inline PIDeque < T > & push_back ( const PIDeque < T > & v ) {
# ifndef NDEBUG
if ( & v = = this ) {
printf ( " error with PIDeque<%s>::append \n " , __PIP_TYPENAME__ ( T ) ) ;
@@ -794,23 +1867,352 @@ public:
newT ( pid_data + ps + pid_start , v . pid_data + v . pid_start , v . pid_size ) ;
return * this ;
}
inline PIDeque < T > & operator < < ( const T & e ) { return push_back ( e ) ; }
inline PIDeque < T > & operator < < ( T & & e ) { return push_back ( std : : move ( e ) ) ; }
inline PIDeque < T > & operator < < ( const PIDeque < T > & v ) { return append ( v ) ; }
inline PIDeque < T > & push_front ( const T & e ) { insert ( 0 , e ) ; return * this ; }
inline PIDeque < T > & push_front ( T & & e ) { insert ( 0 , std : : move ( e ) ) ; return * this ; }
inline PIDeque < T > & prepend ( const T & e ) { return push_front ( e ) ; }
inline PIDeque < T > & prepend ( T & & e ) { return push_front ( std : : move ( e ) ) ; }
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
//! \~english If size() is less than capacity(), which is most often
//! then the addition will be very fast.
//! In any case, the addition is fast and does not depend on the size of the array.
//! If the new size() is greater than capacity()
//! then all iterators and references
//! (including the past-the-end iterator) are invalidated.
//! Otherwise only the past-the-end iterator is invalidated.
//! \~russian Если size() меньше capacity(), что чаше всего,
//! то добавление будет очень быстрым.
//! В любом случае добавление быстрое и не зависит от размера массива.
//! Если новый size() больше, чем capacity(),
//! то все итераторы и указатели становятся нерабочими.
//! В противном случае, все, кроме итераторов указывающих на конец массива,
//! остаются в рабочем состоянии.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.append(4);
//! v.append(5);
//! piCout << v; // {1, 2, 3, 4, 5}
//! \endcode
//! \~\sa \a prepend(), \a push_front(), \a push_back(), \a insert()
inline PIDeque < T > & append ( const T & e ) {
return push_back ( e ) ;
}
inline PIDeque < T > & pop_back ( ) { if ( pid_size = = 0 ) return * this ; resize ( pid_size - 1 ) ; return * this ; }
inline PIDeque < T > & pop_front ( ) { if ( pid_size = = 0 ) return * this ; remove ( 0 ) ; return * this ; }
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\sa \a append()
inline PIDeque < T > & append ( T & & e ) {
return push_back ( std : : move ( e ) ) ;
}
inline T take_back ( ) { T e ( back ( ) ) ; pop_back ( ) ; return e ; }
inline T take_front ( ) { T e ( front ( ) ) ; pop_front ( ) ; return e ; }
//! \brief
//! \~english Appends the given elements to the end of the array.
//! \~russian Добавляет элементы в конец массива.
//! \~\details
//! \~english Overloaded function.
//! Appends the given elements from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Перегруженая функция.
//! Добавляет элементы из
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
//! \~\sa \a append()
inline PIDeque < T > & append ( std : : initializer_list < T > init_list ) {
return push_back ( init_list ) ;
}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.append(PIDeque<int>{4, 5});
//! piCout << v; // {1, 2, 3, 4, 5}
//! \endcode
//! \~\sa \a append()
inline PIDeque < T > & append ( const PIDeque < T > & v ) {
return push_back ( v ) ;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v << 4 << 5;
//! piCout << v; // {1, 2, 3, 4, 5}
//! \endcode
//! \~\sa \a append()
inline PIDeque < T > & operator < < ( const T & e ) {
return push_back ( e ) ;
}
//! \brief
//! \~english Appends the given element `e` to the end of the array.
//! \~russian Добавляет элемент `e` в конец массива.
//! \~\details
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v << 4 << 5;
//! piCout << v; // {1, 2, 3, 4, 5}
//! \endcode
//! \~\sa \a append()
inline PIDeque < T > & operator < < ( T & & e ) {
return push_back ( std : : move ( e ) ) ;
}
//! \brief
//! \~english Appends the given array `v` to the end of the array.
//! \~russian Добавляет массив `v` в конец массива.
//! \~\details
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v << PIDeque<int>{4, 5};
//! piCout << v; // {1, 2, 3, 4, 5}
//! \endcode
//! \~\sa \a append(), \a push_back()
inline PIDeque < T > & operator < < ( const PIDeque < T > & v ) {
return append ( v ) ;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
//! \~english If there is free space at the beginning of the array,
//! which is most often, then the addition will be very fast.
//! In any case, the addition is fast and does not depend on the size of the array.
//! If there is no free space at the beginning of the array
//! then all iterators and references
//! (including the past-the-begin iterator) are invalidated.
//! Otherwise only the past-the-begin iterator is invalidated.
//! \~russian Если в начале массива имеется свободное место,
//! что чаше всего, то добавление будет очень быстрым.
//! В любом случае добавление быстрое и не зависит от размера массива.
//! Если в начале массива нет свободного места,
//! то все итераторы и указатели становятся нерабочими.
//! В противном случае, все, кроме итераторов указывающих на начало массива,
//! остаются в рабочем состоянии.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.push_front(4);
//! v.push_front(5);
//! piCout << v; // {5, 4, 1, 2, 3}
//! \endcode
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
inline PIDeque < T > & push_front ( const T & e ) {
insert ( 0 , e ) ;
return * this ;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\sa \a push_front()
inline PIDeque < T > & push_front ( T & & e ) {
insert ( 0 , std : : move ( e ) ) ;
return * this ;
}
//! \brief
//! \~english Appends the given array `v` to the begin of the array.
//! \~russian Добавляет массив `v` в начало массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.push_front(PIDeque<int>{4, 5});
//! piCout << v; // {4, 5, 1, 2, 3}
//! \endcode
//! \~\sa \a push_front()
inline PIDeque < T > & push_front ( const PIDeque < T > & v ) {
insert ( 0 , v ) ;
return * this ;
}
//! \brief
//! \~english Appends the given elements to the begin of the array.
//! \~russian Добавляет элементы в начало массива.
//! \~\details
//! \~english Overloaded function.
//! Appends the given elements from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Перегруженая функция.
//! Добавляет элементы из
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
//! \~\sa \a append()
inline PIDeque < T > & push_front ( std : : initializer_list < T > init_list ) {
insert ( 0 , init_list ) ;
return * this ;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
//! \~english If there is free space at the beginning of the array,
//! which is most often, then the addition will be very fast.
//! In any case, the addition is fast and does not depend on the size of the array.
//! If there is no free space at the beginning of the array
//! then all iterators and references
//! (including the past-the-begin iterator) are invalidated.
//! Otherwise only the past-the-begin iterator is invalidated.
//! \~russian Если в начале массива имеется свободное место,
//! что чаше всего, то добавление будет очень быстрым.
//! В любом случае добавление быстрое и не зависит от размера массива.
//! Если в начале массива нет свободного места,
//! то все итераторы и указатели становятся нерабочими.
//! В противном случае, все, кроме итераторов указывающих на начало массива,
//! остаются в рабочем состоянии.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.prepend(4);
//! v.prepend(5);
//! piCout << v; // {5, 4, 1, 2, 3}
//! \endcode
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
inline PIDeque < T > & prepend ( const T & e ) {
return push_front ( e ) ;
}
//! \brief
//! \~english Appends the given element `e` to the begin of the array.
//! \~russian Добавляет элемент `e` в начало массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\sa \a prepend()
inline PIDeque < T > & prepend ( T & & e ) {
return push_front ( std : : move ( e ) ) ;
}
//! \brief
//! \~english Appends the given array `v` to the begin of the array.
//! \~russian Добавляет массив `v` в начало массива.
//! \~\details
//! \~english Overloaded function.
//! \~russian Перегруженая функция.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.prepend(PIDeque<int>{4, 5});
//! piCout << v; // {4, 5, 1, 2, 3}
//! \endcode
//! \~\sa \a prepend()
inline PIDeque < T > & prepend ( const PIDeque < T > & v ) {
return push_front ( v ) ;
}
//! \brief
//! \~english Appends the given elements to the begin of the array.
//! \~russian Добавляет элементы в начало массива.
//! \~\details
//! \~english Overloaded function.
//! Appends the given elements from
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
//! \~russian Перегруженая функция.
//! Добавляет элементы из
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
//! \~\sa \a append()
inline PIDeque < T > & prepend ( std : : initializer_list < T > init_list ) {
return prepend ( init_list ) ;
}
//! \brief
//! \~english Remove one element from the end of the array.
//! \~russian Удаляет один элемент с конца массива.
//! \~\details
//! \~english Deleting an element from the end is very fast
//! and does not depend on the size of the array.
//! \~russian Удаление элемента с конца выполняется очень быстро
//! и не зависит от размера массива.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.pop_back();
//! piCout << v; // {1, 2}
//! \endcode
//! \~\sa \a pop_front(), \a take_back(), \a take_front()
inline PIDeque < T > & pop_back ( ) {
if ( pid_size = = 0 ) return * this ;
resize ( pid_size - 1 ) ;
return * this ;
}
//! \brief
//! \~english Remove one element from the begining of the array.
//! \~russian Удаляет один элемент с начала массива.
//! \~\details
//! \~english Removing an element from the beginning takes longer than from the end.
//! This time is directly proportional to the size of the array.
//! All iterators and references are invalidated.
//! \~russian Удаление элемента с начала выполняется дольше чем с конца.
//! Это время прямопропорционально размеру массива.
//! При удалении элемента все итераторы и указатели становятся нерабочими.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! v.pop_front();
//! piCout << v; // {2, 3}
//! \endcode
//! \~\sa \a pop_back(), \a take_back(), \a take_front()
inline PIDeque < T > & pop_front ( ) {
if ( pid_size = = 0 ) return * this ;
remove ( 0 ) ;
return * this ;
}
//! \brief
//! \~english Remove one element from the end of the array and return it.
//! \~russian Удаляет один элемент с начала массива и возвращает е г о .
//! \~\details
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! piCout << v.take_back(); // 3
//! piCout << v; // {1, 2}
//! \endcode
//! \~\sa \a take_front(), \a pop_back(), \a pop_front()
inline T take_back ( ) {
T e ( back ( ) ) ;
pop_back ( ) ;
return e ;
}
//! \brief
//! \~english Remove one element from the begining of the array and return it.
//! \~russian Удаляет один элемент с конца массива и возвращает е г о .
//! \~\details
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! piCout << v.take_front(); // 1
//! piCout << v; // {2, 3}
//! \endcode
//! \~\sa \a take_front(), \a pop_back(), \a pop_front()
inline T take_front ( ) {
T e ( front ( ) ) ;
pop_front ( ) ;
return e ;
}
//! \brief
//! \~english Returns an array converted to another type.
//! \~russian Возвращает конвертированный в другой тип массив.
//! \~\details
//! \~\code
//! PIDeque<double> v{1.1, 2.5, 3.8};
//! PIDeque<int> v2 = v.toType<int>();
//! piCout << v2; // {1, 2, 3}
//! \endcode
//! \~\sa \a map()
template < typename ST >
PIDeque < ST > toType ( ) const {
inline PIDeque < ST > toType ( ) const {
PIDeque < ST > ret ( pid_size ) ;
for ( size_t i = 0 ; i < pid_size ; + + i ) {
ret [ i ] = ST ( pid_data [ i + pid_start ] ) ;
@@ -818,45 +2220,167 @@ public:
return ret ;
}
const PIDeque < T > & forEach ( std : : function < void ( const T & e ) > f ) const {
for ( size_t i = 0 ; i < pid_size ; + + i ) {
f ( pid_data [ i + pid_start ] ) ;
}
return * this ;
}
PIDeque < T > copyForEach ( std : : function < T ( const T & e ) > f ) const {
PIDeque < T > ret ; ret . reserve ( pid_size ) ;
for ( size_t i = 0 ; i < pid_size ; + + i ) {
ret < < f ( pid_data [ i + pid_start ] ) ;
//! \brief
//! \~english Returns a new array with all elements
//! that pass the test implemented by the provided function `test`.
//! \~russian Возвращает новый массив с о всеми элементами,
//! прошедшими проверку, задаваемую в передаваемой функции `test`.
//! \~\details
//! \~\code
//! PIDeque<int> v{3, 2, 5, 2, 7};
//! PIDeque<int> v2 = v.filter([](const int & i){return i > 2;});
//! piCout << v2; // {3, 5, 7}
//! \endcode
//! \~\sa \a map(), \a any(), \a every()
inline PIDeque < T > filter ( std : : function < bool ( const T & e ) > test ) const {
PIDeque < T > ret ;
for ( size_t i = pid_start ; i < pid_start + pid_size ; + + i ) {
if ( test ( pid_data [ i ] ) ) ret < < pid_data [ i ] ;
}
return ret ;
}
PIDeque < T > & forEachInplace ( std : : function < T ( const T & e ) > f ) {
for ( size_t i = 0 ; i < pid_size ; + + i )
pid_data [ i + pid_start ] = f ( pid_data [ i + pid_start ] ) ;
//! \brief
//! \~english Execute function `void f(const T & e)` for every element in array.
//! \~russian Выполняет функцию `void f(const T & e)` для каждого элемента массива.
//! \~\details
//! \~russian Н е позволяет изменять элементы массива.
//! Для редактирования элементов используйте функцию вида `void f(T & e)`.
//! \~english Does not allow changing array elements.
//! To edit elements, use the function like `void f(T & e)`
//! \~\code
//! PIDeque<int> v{1, 2, 3, 4, 5};
//! int s = 0;
//! v.forEach([&s](const int & e){s += e;});
//! piCout << s; // 15
//! \endcode
//! \~\sa \a filter(), \a map(), \a reduce(), \a any(), \a every()
inline void forEach ( std : : function < void ( const T & e ) > f ) const {
for ( size_t i = pid_start ; i < pid_start + pid_size ; + + i ) {
f ( pid_data [ i ] ) ;
}
}
//! \brief
//! \~english Execute function `void f(T & e)` for every element in array.
//! \~russian Выполняет функцию `void f(T & e)` для каждого элемента массива.
//! \~\details
//! \~english Overloaded function.
//! Allows you to change the elements of the array.
//! \~russian Перегруженая функция.
//! Позволяет изменять элементы массива.
//! \~\code
//! PIDeque<int> v{1, 2, 3, 4, 5};
//! v.forEach([](int & e){e++;});
//! piCout << v; // {2, 3, 4, 5, 6}
//! \endcode
//! \~\sa \a filter(), \a map(), \a reduce(), \a any(), \a every()
inline PIDeque < T > & forEach ( std : : function < void ( T & e ) > f ) {
for ( size_t i = pid_start ; i < pid_start + pid_size ; + + i ) {
f ( pid_data [ i ] ) ;
}
return * this ;
}
//! \brief
//! \~english С reates a new array populated with the results
//! of calling a provided function `ST f(const T & e)` on every element in the calling array.
//! \~russian Создаёт новый массив с результатом вызова указанной функции
//! `ST f(const T & e)` для каждого элемента массива.
//! \~\details
//! \~english Calls a provided function`ST f(const T & e)`
//! once for each element in an array, in order,
//! and constructs a new array from the results.
//! \~russian Метод `map` вызывает переданную функцию `ST f(const T & e)`
//! один раз для каждого элемента, в порядке их появления
//! и конструирует новый массив из результатов её вызова.
//! \~\code
//! PIDeque<int> v{1, 2, 3};
//! PIStringList sl = v.map<PIString>([](const int & i){return PIString::fromNumber(i);});
//! piCout << sl; {"1", "2", "3"}
//! \endcode
//! \~\sa \a forEach(), \a reduce()
template < typename ST >
PIDeque < ST > map ( std : : function < ST ( const T & e ) > f ) const {
inline PIDeque < ST > map ( std : : function < ST ( const T & e ) > f ) const {
PIDeque < ST > ret ; ret . reserve ( pid_size ) ;
for ( size_t i = 0 ; i < pid_size ; + + i ) {
ret < < f ( pid_data [ i + pid_start ] ) ;
for ( size_t i = pid_start ; i < pid_start + pid_size ; + + i ) {
ret < < f ( pid_data [ i ] ) ;
}
return ret ;
}
template < typename ST >
PIDeque < ST > toType ( std : : function < ST ( const T & e ) > f ) const { return map ( f ) ; }
//! \brief
//! \~english Applies the function `ST f(const T & e, const ST & acc)`
//! to each element of the array (from left to right), returns one value.
//! \~russian Применяет функцию `ST f(const T & e, const ST & acc)`
//! к каждому элементу массива (слева-направо), возвращает одно значение.
//! \~\details
//! \~english The reduce() method performs the `f` function
//! once for each element in the array.
//! If the `initial` argument is passed when calling reduce(),
//! then when the function `f` is called for the first time,
//! the value of `acc` will be assigned to `initial`.
//! If the array is empty, the value `initial` will be returned.
//! \param f is a function like `ST f(const T & e, const ST & acc)`,
//! executed for each element of the array. It takes two arguments:
//! * **e** - current element of the array
//! * **acc** - accumulator accumulating the value
//! which this function returns after visiting the next element
//!
//! \param initial _optional_ Object used as the second argument
//! when the `f` function is first called.
//! \~russian Метод reduce() выполняет функцию `f`
//! один раз для каждого элемента, присутствующего в массиве.
//! Если при вызове reduce() передан аргумент `initial`,
//! то при первом вызове функции `f` значение `acc`
//! будет равным значению `initial`.
//! Если массив пустой то будет возвращено значение `initial`.
//! \param f Функция, вида `ST f(const T & e, const ST & acc)`,
//! выполняющаяся для каждого элемента массива.
//! Она принимает два аргумента:
//! * **e** - текущий элемент массива
//! * **acc** - аккумулятор, аккумулирующий значение
//! которое возвращает эта функция после посещения очередного элемента
//!
//! \param initial _о пцио на льный_ Объект,
//! используемый в качестве второго аргумента при первом вызове функции `f`.
//!
//! \~\code
//! PIDeque<int> v{1, 2, 3, 4, 5};
//! int s = v.reduce<int>([](const int & e, const int & acc){return e + acc;});
//! piCout << s; // 15
//! \endcode
//! \~\sa \a forEach(), \a map()
template < typename ST >
ST reduce ( std : : function < ST ( const T & e , const ST & acc ) > f , const ST & initial = ST ( ) ) const {
inline ST reduce ( std : : function < ST ( const T & e , const ST & acc ) > f , const ST & initial = ST ( ) ) const {
ST ret ( initial ) ;
for ( size_t i = 0 ; i < pid_size ; + + i ) {
ret = f ( pid_data [ i + pid_start ] , ret ) ;
for ( size_t i = pid_start ; i < pid_start + pid_size ; + + i ) {
ret = f ( pid_data [ i ] , ret ) ;
}
return ret ;
}
inline PIDeque < PIDeque < T > > reshape ( size_t rows , size_t cols , int order = byRow ) const {
//! \brief
//! \~english Changes the dimension of the array, creates a two-dimensional array from a one-dimensional array.
//! \~russian Изменяет размерность массива, из одномерного массива создает двухмерный.
//! \~\details
//! \~russian
//! \param rows размер внешнего массива
//! \param cols размер внутренних массивов
//! \param order порядок обхода исходного массива, задаётся с помощью \a ReshapeOrder
//! \~english
//! \param rows size external array
//! \param cols size internal arrays
//! \param order the order of traversing the source array is set using \a ReshapeOrder
//! \~\code
//! PIDeque<int> v{1, 2, 3, 4};
//! PIDeque<PIDeque<int>> m1 = v.reshape(2,2);
//! piCout << m1; // {{1, 2}, {3, 4}}
//! PIDeque<PIDeque<int>> m2 = v.reshape(2,2, ReshapeByColumn);
//! piCout << m2; // {{1, 3}, {2, 4}}
//! \endcode
//! \~\sa \a map(), \a reduce(), \a flatten()
inline PIDeque < PIDeque < T > > reshape ( size_t rows , size_t cols , ReshapeOrder order = ReshapeByRow ) const {
PIDeque < PIDeque < T > > ret ;
if ( isEmpty ( ) ) return ret ;
# ifndef NDEBUG
@@ -866,12 +2390,12 @@ public:
# endif
assert ( rows * cols = = pid_size ) ;
ret . resize ( rows ) ;
if ( order = = b yRow) {
if ( order = = ReshapeB yRow) {
for ( size_t r = 0 ; r < rows ; r + + ) {
ret [ r ] = PIDeque < T > ( & ( pid_data [ r * cols ] ) , cols ) ;
}
}
if ( order = = b yColumn) {
if ( order = = ReshapeB yColumn) {
for ( size_t r = 0 ; r < rows ; r + + ) {
ret [ r ] . resize ( cols ) ;
for ( size_t c = 0 ; c < cols ; c + + ) {
@@ -882,21 +2406,36 @@ public:
return ret ;
}
//! \brief
//! \~english Changes the dimension of the array, creates a one-dimensional array from a two-dimensional array.
//! \~russian Изменяет размерность массива, из двухмерный массива создает одномерный.
//! \~\details
//! \~russian Делает массив плоским.
//! Порядок обхода исходного массива, задаётся с помощью \a ReshapeOrder.
//! \~english Makes the array flat.
//! Е he order of traversing the source array is set using \a ReshapeOrder.
//! \~\code
//! PIDeque<int> v{1, 2, 3, 4, 5, 6};
//! PIDeque<PIDeque<int>> xv = v.reshape(3,2);
//! piCout << xv; // {{1, 2}, {3, 4}, {5, 6}}
//! piCout << xv.flatten<int>(); // {1, 2, 3, 4, 5, 6}
//! \endcode
//! \~\sa \a map(), \a reduce(), \a reshape()
template < typename C , typename std : : enable_if <
std : : is_same < T , PIDeque < C > > : : value
, int > : : type = 0 >
inline PIDeque < C > reshape ( int order = b yRow) const {
inline PIDeque < C > flatten ( ReshapeOrder order = ReshapeB yRow) const {
PIDeque < C > ret ;
if ( isEmpty ( ) ) return ret ;
size_t rows = size ( ) ;
size_t cols = at ( 0 ) . size ( ) ;
ret . reserve ( rows * cols ) ;
if ( order = = b yRow) {
if ( order = = ReshapeB yRow) {
for ( size_t r = 0 ; r < rows ; r + + ) {
ret . append ( at ( r ) ) ;
}
}
if ( order = = b yColumn) {
if ( order = = ReshapeB yColumn) {
for ( size_t c = 0 ; c < cols ; c + + ) {
for ( size_t r = 0 ; r < rows ; r + + ) {
ret < < at ( r ) [ c ] ;
@@ -907,6 +2446,33 @@ public:
return ret ;
}
//! \brief
//! \~english Changes the dimension of the two-dimensional array.
//! \~russian Изменяет размерность двухмерного массива.
//! \~\details
//! \~russian
//! \param rows размер внешнего массива
//! \param cols размер внутренних массивов
//! \param order порядок обхода исходного массива, задаётся с помощью \a ReshapeOrder
//! \~english
//! \param rows size external array
//! \param cols size internal arrays
//! \param order the order of traversing the source array is set using \a ReshapeOrder
//! \~\code
//! PIDeque<int> v{1, 2, 3, 4, 5, 6};
//! PIDeque<PIDeque<int>> xv = v.reshape(3,2);
//! piCout << xv; // {{1, 2}, {3, 4}, {5, 6}}
//! piCout << xv.reshape<int>(2,3); // {{1, 2, 3}, {4, 5, 6}}
//! \endcode
//! \~\sa \a map(), \a reduce(), \a reshape()
template < typename C , typename std : : enable_if <
std : : is_same < T , PIDeque < C > > : : value
, int > : : type = 0 >
inline PIDeque < PIDeque < C > > reshape ( size_t rows , size_t cols , ReshapeOrder order = ReshapeByRow ) const {
PIDeque < C > fl = flatten < C > ( ) ;
return fl . reshape ( rows , cols , order ) ;
}
private :
inline void _reset ( ) { pid_size = pid_rsize = pid_start = 0 ; pid_data = 0 ; }
inline size_t asize ( ssize_t s ) {
@@ -1051,6 +2617,8 @@ private:
# ifdef PIP_STD_IOSTREAM
//! \~english Output operator to [std::ostream](https://en.cppreference.com/w/cpp/io/basic_ostream).
//! \~russian Оператор вывода в [std::ostream](https://ru.cppreference.com/w/cpp/io/basic_ostream).
template < typename T >
inline std : : ostream & operator < < ( std : : ostream & s , const PIDeque < T > & v ) {
s < < " { " ;
@@ -1063,6 +2631,10 @@ inline std::ostream & operator <<(std::ostream & s, const PIDeque<T> & v) {
}
# endif
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
template < typename T >
inline PICout operator < < ( PICout s , const PIDeque < T > & v ) {
s . space ( ) ;
@@ -1077,7 +2649,10 @@ inline PICout operator <<(PICout s, const PIDeque<T> & v) {
return s ;
}
template < typename T > inline void piSwap ( PIDeque < T > & f , PIDeque < T > & s ) { f . swap ( s ) ; }
template < typename T >
inline void piSwap ( PIDeque < T > & f , PIDeque < T > & s ) {
f . swap ( s ) ;
}
# endif // PIDEQUE_H