@@ -42,25 +42,81 @@
template < typename Key , typename T >
template < typename Key , typename T >
class PIMapIterator ;
class PIMapIterator ;
template < typename Key , typename T >
class PIMapReverseIterator ;
//! \addtogroup Containers
//! \{
//! \class PIMap
//! \brief
//! \~english Associative array.
//! \~russian Словарь.
//! \~\}
//! \details
//! \~english
//! A collection of key/value pairs, from which you retrieve a value using its associated key.
//! There is a finite number of keys in the map, and each key has exactly one value associated with it.
//! \a value() returns value for key and leave map
//! unchaged in any case. \a operator [] create entry in map if
//! there is no entry for given key. You can retrieve all
//! keys by method \a keys() and all values by methos \a values().
//! To iterate all entries use class PIMapIterator, or methods
//! \a makeIterator() and \a makeReverseIterator().
//! A key in the Map may only occur once.
//! \~russian
//! Словари, в принципе, похожи на обычные, используемые в повседневной жизни.
//! Они хранят элементы одного и того же типа, индексируемые ключевыми значениями.
//! Достоинство словаря в том, что он позволяет быстро получать значение,
//! ассоциированное с заданным ключом.
//! Ключи должны быть уникальными.
//! Элемент
//! В контейнеры этого типа заносятся элементы вместе с ключами,
//! по которым их можно найти, которыми могут выступать значения любого типа.
//! \a operator [] позволяет получить доступ к элементу по ключу,
//! и если такого эелемента небыло, то он будет создан.
template < typename Key , typename T >
template < typename Key , typename T >
class PIMap {
class PIMap {
template < typename Key1 , typename T1 > friend class PIMapIterator ;
template < typename Key1 , typename T1 > friend class PIMapIterator ;
template < typename Key1 , typename T1 > friend class PIMapReverseIterator ;
template < typename P , typename Key1 , typename T1 >
template < typename P , typename Key1 , typename T1 >
friend PIBinaryStream < P > & operator < < ( PIBinaryStream < P > & s , const PIMap < Key1 , T1 > & v ) ;
friend PIBinaryStream < P > & operator < < ( PIBinaryStream < P > & s , const PIMap < Key1 , T1 > & v ) ;
template < typename P , typename Key1 , typename T1 >
template < typename P , typename Key1 , typename T1 >
friend PIBinaryStream < P > & operator > > ( PIBinaryStream < P > & s , PIMap < Key1 , T1 > & v ) ;
friend PIBinaryStream < P > & operator > > ( PIBinaryStream < P > & s , PIMap < Key1 , T1 > & v ) ;
public :
public :
PIMap ( ) { ; }
typedef T mapped_type ;
typedef Key key_type ;
typedef PIPair < Key , T > value_type ;
//! \~english Constructs an empty map.
//! \~russian Создает пустой словарь.
PIMap ( ) { }
//! \~english Copy constructor.
//! \~russian Копирующий конструктор.
PIMap ( const PIMap < Key , T > & other ) { * this = other ; }
PIMap ( const PIMap < Key , T > & other ) { * this = other ; }
//! \~english Move constructor.
//! \~russian Перемещающий конструктор.
PIMap ( PIMap < Key , T > & & other ) : pim_content ( std : : move ( other . pim_content ) ) , pim_index ( std : : move ( other . pim_index ) ) { }
PIMap ( PIMap < Key , T > & & other ) : pim_content ( std : : move ( other . pim_content ) ) , pim_index ( std : : move ( other . pim_index ) ) { }
//! \~english Contructs map 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
//! PIMap <int, PIString> m{{1, "a"}, {2, "b"}};
//! piCout << m; // {1, 2, 3}
//! \endcode
PIMap ( std : : initializer_list < std : : pair < Key , T > > init_list ) {
PIMap ( std : : initializer_list < std : : pair < Key , T > > init_list ) {
for ( auto i : init_list ) {
for ( auto i : init_list ) {
insert ( std : : get < 0 > ( i ) , std : : get < 1 > ( i ) ) ;
insert ( std : : get < 0 > ( i ) , std : : get < 1 > ( i ) ) ;
}
}
}
}
virtual ~ PIMap ( ) { ; }
//! \~english Assign operator.
//! \~russian Оператор присваивания.
PIMap < Key , T > & operator = ( const PIMap < Key , T > & other ) {
PIMap < Key , T > & operator = ( const PIMap < Key , T > & other ) {
if ( this = = & other ) return * this ;
if ( this = = & other ) return * this ;
clear ( ) ;
clear ( ) ;
@@ -69,14 +125,12 @@ public:
return * this ;
return * this ;
}
}
//! \~english Assign move operator.
//! \~russian Оператор перемещающего присваивания.
PIMap < Key , T > & operator = ( PIMap < Key , T > & & other ) {
PIMap < Key , T > & operator = ( PIMap < Key , T > & & other ) {
swap ( other ) ;
swap ( other ) ;
return * this ;
return * this ;
}
}
typedef T mapped_type ;
typedef Key key_type ;
typedef PIPair < Key , T > value_type ;
class iterator {
class iterator {
friend class PIMap < Key , T > ;
friend class PIMap < Key , T > ;
@@ -88,7 +142,9 @@ public:
iterator ( ) : parent ( nullptr ) , pos ( 0 ) { }
iterator ( ) : parent ( nullptr ) , pos ( 0 ) { }
const Key & key ( ) const { return const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) ; }
const Key & key ( ) const { return const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) ; }
T & value ( ) { return const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ; }
T & value ( ) { return const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ; }
inline PIPair < Key , T > operator * ( ) const { return PIPair < Key , T > ( const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) , const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ) ; }
inline PIPair < Key , T > operator * ( ) const {
return PIPair < Key , T > ( const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) , const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ) ;
}
void operator + + ( ) { + + pos ; }
void operator + + ( ) { + + pos ; }
void operator + + ( int ) { + + pos ; }
void operator + + ( int ) { + + pos ; }
void operator - - ( ) { - - pos ; }
void operator - - ( ) { - - pos ; }
@@ -107,7 +163,9 @@ public:
reverse_iterator ( ) : parent ( nullptr ) , pos ( 0 ) { }
reverse_iterator ( ) : parent ( nullptr ) , pos ( 0 ) { }
const Key & key ( ) const { return const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) ; }
const Key & key ( ) const { return const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) ; }
T & value ( ) const { return const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ; }
T & value ( ) const { return const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ; }
inline PIPair < Key , T > operator * ( ) const { return PIPair < Key , T > ( const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) , const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ) ; }
inline PIPair < Key , T > operator * ( ) const {
return PIPair < Key , T > ( const_cast < PIMap < Key , T > * > ( parent ) - > _key ( pos ) , const_cast < PIMap < Key , T > * > ( parent ) - > _value ( pos ) ) ;
}
void operator + + ( ) { - - pos ; }
void operator + + ( ) { - - pos ; }
void operator + + ( int ) { - - pos ; }
void operator + + ( int ) { - - pos ; }
void operator - - ( ) { + + pos ; }
void operator - - ( ) { + + pos ; }
@@ -152,26 +210,45 @@ public:
bool operator ! = ( const const_reverse_iterator & it ) const { return ( pos ! = it . pos ) ; }
bool operator ! = ( const const_reverse_iterator & it ) const { return ( pos ! = it . pos ) ; }
} ;
} ;
iterator begin ( ) { return iterator ( this , 0 ) ; }
iterator begin ( ) { return iterator ( this , 0 ) ; }
iterator end ( ) { return iterator ( this , size ( ) ) ; }
iterator end ( ) { return iterator ( this , size ( ) ) ; }
const_iterator begin ( ) const { return const_iterator ( this , 0 ) ; }
const_iterator begin ( ) const { return const_iterator ( this , 0 ) ; }
const_iterator end ( ) const { return const_iterator ( this , size ( ) ) ; }
const_iterator end ( ) const { return const_iterator ( this , size ( ) ) ; }
const_iterator constBegin ( ) const { return const_iterator ( this , 0 ) ; }
const_iterator constBegin ( ) const { return const_iterator ( this , 0 ) ; }
const_iterator constEnd ( ) const { return const_iterator ( this , size ( ) ) ; }
const_iterator constEnd ( ) const { return const_iterator ( this , size ( ) ) ; }
reverse_iterator rbegin ( ) { return reverse_iterator ( this , size ( ) - 1 ) ; }
reverse_iterator rbegin ( ) { return reverse_iterator ( this , size ( ) - 1 ) ; }
reverse_iterator rend ( ) { return reverse_iterator ( this , - 1 ) ; }
reverse_iterator rend ( ) { return reverse_iterator ( this , - 1 ) ; }
const_reverse_iterator rbegin ( ) const { return const_reverse_iterator ( this , size ( ) - 1 ) ; }
const_reverse_iterator rbegin ( ) const { return const_reverse_iterator ( this , size ( ) - 1 ) ; }
const_reverse_iterator rend ( ) const { return const_reverse_iterator ( this , - 1 ) ; }
const_reverse_iterator rend ( ) const { return const_reverse_iterator ( this , - 1 ) ; }
const_reverse_iterator constRbegin ( ) const { return const_reverse_iterator ( this , size ( ) - 1 ) ; }
const_reverse_iterator constRbegin ( ) const { return const_reverse_iterator ( this , size ( ) - 1 ) ; }
const_reverse_iterator constRend ( ) const { return const_reverse_iterator ( this , - 1 ) ; }
const_reverse_iterator constRend ( ) const { return const_reverse_iterator ( this , - 1 ) ; }
//! \relatesalso PIMapIterator
PIMapIterator < Key , T > makeIterator ( ) const { return PIMapIterator < Key , T > ( * this ) ; }
PIMapIterator < Key , T > makeIterator ( ) const { return PIMapIterator < Key , T > ( * this ) ; }
PIMapIterator < Key , T > makeReverseIterator ( ) const { return PIMapIterator < Key , T > ( * this , true ) ; }
//! \relatesalso PIMapReverseIterator
PIMapReverseIterator < Key , T > makeReverseIterator ( ) const { return PIMapReverseIterator < Key , T > ( * this ) ; }
size_t size ( ) const { return pim_content . size ( ) ; }
size_t size ( ) const { return pim_content . size ( ) ; }
int size_s ( ) const { return pim_content . size_s ( ) ; }
int size_s ( ) const { return pim_content . size_s ( ) ; }
size_t length ( ) const { return pim_content . size ( ) ; }
size_t length ( ) const { return pim_content . size ( ) ; }
bool isEmpty ( ) const { return ( pim_content . size ( ) = = 0 ) ; }
bool isEmpty ( ) const { return ( pim_content . size ( ) = = 0 ) ; }
bool isNotEmpty ( ) const { return ( pim_content . size ( ) > 0 ) ; }
bool isNotEmpty ( ) const { return ( pim_content . size ( ) > 0 ) ; }
T & operator [ ] ( const Key & key ) {
T & operator [ ] ( const Key & key ) {
@@ -183,6 +260,15 @@ public:
return pim_content . back ( ) ;
return pim_content . back ( ) ;
}
}
T at ( const Key & key ) const { return value ( key ) ; }
T at ( const Key & key ) const { return value ( key ) ; }
T take ( const Key & key ) const {
bool f ( false ) ;
ssize_t i = _find ( key , f ) ;
if ( ! f ) return T ( ) ;
T ret ( pim_content [ pim_index [ i ] . index ] ) ;
_remove ( i ) ;
return ret ;
}
PIMap < Key , T > & operator < < ( const PIMap < Key , T > & other ) {
PIMap < Key , T > & operator < < ( const PIMap < Key , T > & other ) {
# ifndef NDEBUG
# ifndef NDEBUG
@@ -192,24 +278,66 @@ public:
# endif
# endif
assert ( & other ! = this ) ;
assert ( & other ! = this ) ;
if ( other . isEmpty ( ) ) return * this ;
if ( other . isEmpty ( ) ) return * this ;
if ( other . size ( ) = = 1 ) { insert ( other . pim_index [ 0 ] . key , other . pim_content [ 0 ] ) ; return * this ; }
if ( other . size ( ) = = 1 ) {
if ( other . size ( ) = = 2 ) { insert ( other . pim_index [ 0 ] . key , other . pim_content [ 0 ] ) ; insert ( other . pim_index [ 1 ] . key , other . pim_content [ 1 ] ) ; return * this ; }
insert ( other . pim_index [ 0 ] . key , other . pim_content [ 0 ] ) ;
return * this ;
}
if ( other . size ( ) = = 2 ) {
insert ( other . pim_index [ 0 ] . key , other . pim_content [ 0 ] ) ;
insert ( other . pim_index [ 1 ] . key , other . pim_content [ 1 ] ) ;
return * this ;
}
for ( int i = 0 ; i < other . pim_index . size_s ( ) ; + + i ) {
for ( int i = 0 ; i < other . pim_index . size_s ( ) ; + + i ) {
insert ( other . pim_index [ i ] . key , other . pim_content [ other . pim_index [ i ] . index ] ) ;
insert ( other . pim_index [ i ] . key , other . pim_content [ other . pim_index [ i ] . index ] ) ;
}
}
return * this ;
return * this ;
}
}
bool operator = = ( const PIMap < Key , T > & t ) const { return ( pim_content = = t . pim_content & & pim_index = = t . pim_index ) ; }
bool operator = = ( const PIMap < Key , T > & t ) const {
bool operator ! = ( const PIMap < Key , T > & t ) const { return ( pim_content ! = t . pim_content | | pim_index ! = t . pim_index ) ; }
return ( pim_content = = t . pim_content & & pim_index = = t . pim_index ) ;
bool contains ( const Key & key ) const { bool f ( false ) ; _find ( key , f ) ; return f ; }
}
bool operator ! = ( const PIMap < Key , T > & t ) const {
return ( pim_content ! = t . pim_content | | pim_index ! = t . pim_index ) ;
}
bool contains ( const Key & key ) const {
bool f ( false ) ; _find ( key , f ) ;
return f ;
}
PIMap < Key , T > & reserve ( size_t new_size ) { pim_content . reserve ( new_size ) ; pim_index . reserve ( new_size ) ; return * this ; }
bool containsValue ( const T & value ) const {
return pim_content . contains ( value ) ;
}
PIMap < Key , T > & removeOne ( const Key & key ) { bool f ( false ) ; ssize_t i = _find ( key , f ) ; if ( f ) _remove ( i ) ; return * this ; }
PIMap < Key , T > & reserve ( size_t new_size ) {
PIMap < Key , T > & remove ( const Key & key ) { return removeOne ( key ) ; }
pim_content . reserve ( new_size ) ;
PIMap < Key , T > & erase ( const Key & key ) { return removeOne ( key ) ; }
pim_index . reserve ( new_size ) ;
PIMap < Key , T > & clear ( ) { pim_content . clear ( ) ; pim_index . clear ( ) ; return * this ; }
return * this ;
}
PIMap < Key , T > & remove ( const Key & key ) {
bool f ( false ) ;
ssize_t i = _find ( key , f ) ;
if ( f ) _remove ( i ) ;
return * this ;
}
PIMap < Key , T > & removeWhere ( std : : function < bool ( const Key & key , const T & value ) > test ) {
for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i ) {
if ( pim_index [ i ] . key , pim_content [ pim_index [ i ] . index ] ) {
_remove ( i ) ;
- - i ;
}
}
}
PIMap < Key , T > & erase ( const Key & key ) { return remove ( key ) ; }
PIMap < Key , T > & clear ( ) {
pim_content . clear ( ) ;
pim_index . clear ( ) ;
return * this ;
}
void swap ( PIMap < Key , T > & other ) {
void swap ( PIMap < Key , T > & other ) {
pim_content . swap ( other . pim_content ) ;
pim_content . swap ( other . pim_content ) ;
@@ -219,7 +347,6 @@ public:
PIMap < Key , T > & insert ( const Key & key , const T & value ) {
PIMap < Key , T > & insert ( const Key & key , const T & value ) {
bool f ( false ) ;
bool f ( false ) ;
ssize_t i = _find ( key , f ) ;
ssize_t i = _find ( key , f ) ;
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
if ( f ) {
if ( f ) {
pim_content [ pim_index [ i ] . index ] = value ;
pim_content [ pim_index [ i ] . index ] = value ;
} else {
} else {
@@ -231,7 +358,6 @@ public:
PIMap < Key , T > & insert ( const Key & key , T & & value ) {
PIMap < Key , T > & insert ( const Key & key , T & & value ) {
bool f ( false ) ;
bool f ( false ) ;
ssize_t i = _find ( key , f ) ;
ssize_t i = _find ( key , f ) ;
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
if ( f ) {
if ( f ) {
pim_content [ pim_index [ i ] . index ] = std : : move ( value ) ;
pim_content [ pim_index [ i ] . index ] = std : : move ( value ) ;
} else {
} else {
@@ -240,28 +366,85 @@ public:
}
}
return * this ;
return * this ;
}
}
T value ( const Key & key , const T & default_ = T ( ) ) const { bool f ( false ) ; ssize_t i = _find ( k ey, f ) ; if ( ! f ) return default_ ; return pim_content [ pim_index [ i ] . index ] ; }
PIMap < Key , T > & insert ( const PIPair < K ey, T > & pair ) {
bool f ( false ) ;
ssize_t i = _find ( pair . first , f ) ;
if ( f ) {
pim_content [ pim_index [ i ] . index ] = pair . second ;
} else {
pim_content . push_back ( pair . second ) ;
pim_index . insert ( i , MapIndex ( pair . first , pim_content . size ( ) - 1 ) ) ;
}
return * this ;
}
PIMap < Key , T > & insert ( PIPair < Key , T > & & pair ) {
bool f ( false ) ;
Key k ( std : : move ( pair . first ) ) ;
ssize_t i = _find ( k , f ) ;
if ( f ) {
pim_content [ pim_index [ i ] . index ] = std : : move ( pair . second ) ;
} else {
pim_content . push_back ( std : : move ( pair . second ) ) ;
pim_index . insert ( i , MapIndex ( k , pim_content . size ( ) - 1 ) ) ;
}
return * this ;
}
T value ( const Key & key , const T & default_ = T ( ) ) const {
bool f ( false ) ;
ssize_t i = _find ( key , f ) ;
if ( ! f ) return default_ ;
return pim_content [ pim_index [ i ] . index ] ;
}
PIVector < T > values ( ) const { return pim_content ; }
PIVector < T > values ( ) const { return pim_content ; }
Key key ( const T & value_ , const Key & default_ = Key ( ) ) const { for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i ) if ( pim_content [ pim_index [ i ] . index ] = = value_ ) return pim_index [ i ] . key ; return default_ ; }
Key key ( const T & value_ , const Key & default_ = Key ( ) ) const {
for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i ) {
if ( pim_content [ pim_index [ i ] . index ] = = value_ ) {
return pim_index [ i ] . key ;
}
}
return default_ ;
}
PIVector < Key > keys ( ) const {
PIVector < Key > keys ( ) const {
PIVector < Key > ret ;
PIVector < Key > ret ;
for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i )
ret . reserve ( pim_index . size ( ) ) ;
for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i ) {
ret < < pim_index [ i ] . key ;
ret < < pim_index [ i ] . key ;
}
return ret ;
}
void forEach ( std : : function < void ( const Key & key , const T & value ) > f ) const {
for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i ) {
f ( pim_index [ i ] . key , pim_content [ pim_index [ i ] . index ] ) ;
}
}
template < typename Key2 , typename T2 >
inline PIMap < Key2 , T2 > map ( std : : function < PIPair < Key2 , T2 > ( const Key & key , const T & value ) > f ) const {
PIMap < Key2 , T2 > ret ; ret . reserve ( size ( ) ) ;
for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i ) {
ret . insert ( f ( pim_index [ i ] . key , pim_content [ pim_index [ i ] . index ] ) ) ;
}
return ret ;
}
template < typename ST >
inline PIVector < ST > map ( std : : function < ST ( const Key & key , const T & value ) > f ) const {
PIVector < ST > ret ; ret . reserve ( size ( ) ) ;
for ( int i = 0 ; i < pim_index . size_s ( ) ; + + i ) {
ret < < f ( pim_index [ i ] . key , pim_content [ pim_index [ i ] . index ] ) ;
}
return ret ;
return ret ;
}
}
// void dump() {
// piCout << "PIMap" << size() << "entries" << PICoutManipulators::NewLine << "content:";
// for (size_t i = 0; i < pim_content.size(); ++i)
// piCout << PICoutManipulators::Tab << i << ":" << pim_content[i];
// piCout << "index:";
// for (size_t i = 0; i < pim_index.size(); ++i)
// piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
// }
private :
private :
struct MapIndex {
struct MapIndex {
MapIndex ( Key k = Key ( ) , size_t i = 0 ) : key ( k ) , index ( i ) { ; }
MapIndex ( const Key & k = Key ( ) , size_t i = 0 ) : key ( k ) , index ( i ) { }
MapIndex ( Key & & k , size_t i = 0 ) : key ( std : : move ( k ) ) , index ( i ) { }
Key key ;
Key key ;
size_t index ;
size_t index ;
bool operator = = ( const MapIndex & s ) const { return key = = s . key ; }
bool operator = = ( const MapIndex & s ) const { return key = = s . key ; }
@@ -269,6 +452,7 @@ private:
bool operator < ( const MapIndex & s ) const { return key < s . key ; }
bool operator < ( const MapIndex & s ) const { return key < s . key ; }
bool operator > ( const MapIndex & s ) const { return key > s . key ; }
bool operator > ( const MapIndex & s ) const { return key > s . key ; }
} ;
} ;
template < typename P , typename Key1 , typename T1 >
template < typename P , typename Key1 , typename T1 >
friend PIBinaryStream < P > & operator > > ( PIBinaryStream < P > & s , PIDeque < typename PIMap < Key1 , T1 > : : MapIndex > & v ) ;
friend PIBinaryStream < P > & operator > > ( PIBinaryStream < P > & s , PIDeque < typename PIMap < Key1 , T1 > : : MapIndex > & v ) ;
template < typename P , typename Key1 , typename T1 >
template < typename P , typename Key1 , typename T1 >
@@ -285,6 +469,7 @@ private:
found = false ;
found = false ;
return first ;
return first ;
}
}
ssize_t _find ( const Key & k , bool & found ) const {
ssize_t _find ( const Key & k , bool & found ) const {
if ( pim_index . isEmpty ( ) ) {
if ( pim_index . isEmpty ( ) ) {
found = false ;
found = false ;
@@ -292,75 +477,213 @@ private:
}
}
return _binarySearch ( 0 , pim_index . size_s ( ) - 1 , k , found ) ;
return _binarySearch ( 0 , pim_index . size_s ( ) - 1 , k , found ) ;
}
}
void _remove ( ssize_t index ) {
void _remove ( ssize_t index ) {
//if (index >= pim_index.size()) return;
size_t ci = pim_index [ index ] . index , bi = pim_index . size ( ) - 1 ;
size_t ci = pim_index [ index ] . index , bi = pim_index . size ( ) - 1 ;
pim_index . remove ( index ) ;
pim_index . remove ( index ) ;
for ( size_t i = 0 ; i < pim_index . size ( ) ; + + i )
for ( size_t i = 0 ; i < pim_index . size ( ) ; + + i ) {
if ( pim_index [ i ] . index = = bi ) {
if ( pim_index [ i ] . index = = bi ) {
pim_index [ i ] . index = ci ;
pim_index [ i ] . index = ci ;
break ;
break ;
}
}
}
piSwap < T > ( pim_content [ ci ] , pim_content . back ( ) ) ;
piSwap < T > ( pim_content [ ci ] , pim_content . back ( ) ) ;
pim_content . resize ( pim_index . size ( ) ) ;
pim_content . resize ( pim_index . size ( ) ) ;
}
}
const value_type _pair ( ssize_t index ) const {
const value_type _pair ( ssize_t index ) const {
if ( index < 0 | | index > = pim_index . size_s ( ) )
if ( index < 0 | | index > = pim_index . size_s ( ) ) return value_type ( ) ;
return value_type ( ) ;
//piCout << "_pair" << index << pim_index[index].index;
return value_type ( pim_index [ index ] . key , pim_content [ pim_index [ index ] . index ] ) ;
return value_type ( pim_index [ index ] . key , pim_content [ pim_index [ index ] . index ] ) ;
}
}
Key & _key ( ssize_t index ) { return pim_index [ index ] . key ; }
Key & _key ( ssize_t index ) { return pim_index [ index ] . key ; }
const Key & _key ( ssize_t index ) const { return pim_index [ index ] . key ; }
T & _value ( ssize_t index ) { return pim_content [ pim_index [ index ] . index ] ; }
T & _value ( ssize_t index ) { return pim_content [ pim_index [ index ] . index ] ; }
const T & _value ( ssize_t index ) const { return pim_content [ pim_index [ index ] . index ] ; }
PIVector < T > pim_content ;
PIVector < T > pim_content ;
PIDeque < MapIndex > pim_index ;
PIDeque < MapIndex > pim_index ;
} ;
} ;
//! \addtogroup Containers
//! \{
//! \class PIMapIterator
//! \brief
//! \~english Java-style iterator for \a PIMap.
//! \~russian Итератор Java стиля для \a PIMap.
//! \~\}
//! \details
//! \~english
//! This class used to easy serial access keys and values in PIMap.
//! You can use constructor to create iterator, or use \a PIMap::makeIterator()
//! \~russian
//! Этот класс используется для удобного перебора ключей и значений всего словаря в обратном порядке.
//! Ты можешь использовать конструктор, в который передать словарь, или функцию словаря \a PIMap::makeReverseIterator().
//! \~
//! \code
//! PIMap<int, PIString> m;
//! m[1] = "one";
//! m[2] = "two";
//! m[4] = "four";
//! auto it = m.makeIterator();
//! while (it.next()) {
//! piCout << it.key() << it.value();
//! // 1 one
//! // 2 two
//! // 4 four
//! \endcode
template < typename Key , typename T >
template < typename Key , typename T >
class PIMapIterator {
class PIMapIterator {
typedef PIMap < Key , T > MapType ;
typedef PIMap < Key , T > MapType ;
public :
public :
PIMapIterator ( const PIMap < Key , T > & map , bool reverse = false ) : m ( map ) , pos ( - 1 ) , rev ( reverse ) {
PIMapIterator ( const PIMap < Key , T > & map , bool reverse = false ) : m ( map ) , pos ( - 1 ) {}
if ( rev ) pos = m . size_s ( ) ;
//! \~english Returns current key.
//! \~russian Возвращает ключ текущего элемента.
//! \~\sa \a value(), \a valueRef()
const Key & key ( ) const {
return m . _key ( pos ) ;
}
}
const Key & key ( ) const { return const_cast < MapType & > ( m ) . _key ( pos ) ; }
const T & value ( ) const { return const_cast < MapType & > ( m ) . _value ( pos ) ; }
//! \~english Returns current value.
T & valueRef ( ) const { return const_cast < MapType & > ( m ) . _value ( pos ) ; }
//! \~russian Возвращает значение текущего элемента.
//! \~\sa \a key(), \a valueRef()
const T & value ( ) const {
return m . _value ( pos ) ;
}
//! \~english Returns current value reference.
//! \~russian Возвращает изменяемую ссылку на значение текущего элемента.
//! \~\sa \a key(), \a value()
T & valueRef ( ) {
return const_cast < MapType & > ( m ) . _value ( pos ) ;
}
//! \~english Returns true if iterator can jump to next entry
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
inline bool hasNext ( ) const {
inline bool hasNext ( ) const {
if ( rev ) {
return pos < ( m . size_s ( ) - 1 ) ;
return pos > 0 ;
} else {
return pos < ( m . size_s ( ) - 1 ) ;
}
return false ;
}
}
//! \~english Jump to next entry and return true if new position is valid.
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
inline bool next ( ) {
inline bool next ( ) {
if ( rev ) {
+ + pos ;
- - pos ;
return pos < m . size_s ( ) ;
return pos > = 0 ;
} else {
+ + pos ;
return pos < m . size_s ( ) ;
}
return false ;
}
}
//! \~english Reset iterator to initial position.
//! \~russian Переходит на начало.
inline void reset ( ) {
inline void reset ( ) {
if ( rev ) {
pos = - 1 ;
pos = m . size_s ( ) ;
}
} else {
private :
pos = - 1 ;
const MapType & m ;
}
ssize_t pos ;
} ;
//! \addtogroup Containers
//! \{
//! \class PIMapReverseIterator
//! \brief
//! \~english Java-style reverse iterator for \a PIMap.
//! \~russian Итератор Java стиля для \a PIMap в обратном порядке.
//! \~\}
//! \details
//! \~english
//! This class used to easy serial reverse access keys and values in PIMap.
//! You can use constructor to create iterator, or use \a PIMap::makeReverseIterator().
//! \~russian
//! Этот класс используется для удобного перебора ключей и значений всего словаря в обратном порядке.
//! Ты можешь использовать конструктор, в который передать словарь, или функцию словаря \a PIMap::makeReverseIterator().
//! \~
//! \code
//! PIMap<int, PIString> m;
//! m[1] = "one";
//! m[2] = "two";
//! m[4] = "four";
//! auto it = m.makeReverseIterator();
//! while (it.next()) {
//! piCout << it.key() << it.value();
//! }
//! // 4 four
//! // 2 two
//! // 1 one
//! \endcode
//! \~english Write access:
//! \~russian Доступ на запись:
//! \~
//! \code
//! while (it.next()) {
//! it.valueRef().append("_!");
//! piCout << it.key() << it.value();
//! }
//! // 4 four_!
//! // 2 two_!
//! // 1 one_!
//! \endcode
template < typename Key , typename T >
class PIMapReverseIterator {
typedef PIMap < Key , T > MapType ;
public :
PIMapReverseIterator ( const PIMap < Key , T > & map ) : m ( map ) , pos ( m . size_s ( ) ) { }
//! \~english Returns current key.
//! \~russian Возвращает ключ текущего элемента.
//! \~\sa \a value(), \a valueRef()
const Key & key ( ) const {
return m . _key ( pos ) ;
}
//! \~english Returns current value.
//! \~russian Возвращает значение текущего элемента.
//! \~\sa \a key(), \a valueRef()
const T & value ( ) const {
return m . _value ( pos ) ;
}
//! \~english Returns current value reference.
//! \~russian Возвращает изменяемую ссылку на значение текущего элемента.
//! \~\sa \a key(), \a value()
T & valueRef ( ) {
return const_cast < MapType & > ( m ) . _value ( pos ) ;
}
//! \~english Returns true if iterator can jump to next entry
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
inline bool hasNext ( ) const {
return pos > 0 ;
}
//! \~english Jump to next entry and return true if new position is valid.
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
inline bool next ( ) {
- - pos ;
return pos > = 0 ;
}
//! \~english Reset iterator to initial position.
//! \~russian Переходит на начало.
inline void reset ( ) {
pos = m . size_s ( ) ;
}
}
private :
private :
const MapType & m ;
const MapType & m ;
ssize_t pos ;
ssize_t pos ;
bool rev ;
} ;
} ;
# ifdef PIP_STD_IOSTREAM
# 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 Key , typename Type >
template < typename Key , typename Type >
inline std : : ostream & operator < < ( std : : ostream & s , const PIMap < Key , Type > & v ) {
inline std : : ostream & operator < < ( std : : ostream & s , const PIMap < Key , Type > & v ) {
s < < " { " ;
s < < " { " ;
@@ -376,6 +699,10 @@ inline std::ostream & operator <<(std::ostream & s, const PIMap<Key, Type> & v)
}
}
# endif
# endif
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
template < typename Key , typename Type >
template < typename Key , typename Type >
inline PICout operator < < ( PICout s , const PIMap < Key , Type > & v ) {
inline PICout operator < < ( PICout s , const PIMap < Key , Type > & v ) {
s . space ( ) ;
s . space ( ) ;
@@ -393,7 +720,8 @@ inline PICout operator <<(PICout s, const PIMap<Key, Type> & v) {
return s ;
return s ;
}
}
template < typename Key , typename Type > inline void piSwap ( PIMap < Key , Type > & f , PIMap < Key , Type > & s ) { f . swap ( s ) ; }
template < typename Key , typename Type >
inline void piSwap ( PIMap < Key , Type > & f , PIMap < Key , Type > & s ) { f . swap ( s ) ; }
# endif // PIMAP_H
# endif // PIMAP_H