code format
This commit is contained in:
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Base macros for generic containers
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Base macros for generic containers
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "picontainers.h"
|
||||
@@ -29,6 +29,6 @@ size_t _PIContainerConstantsBase::calcMinCountPoT(size_t szof) {
|
||||
elc *= 2;
|
||||
++ret;
|
||||
}
|
||||
//printf("calcMinCount sizeof = %d, min_count = %d, pot = %d\n", szof, elc, ret);
|
||||
// printf("calcMinCount sizeof = %d, min_count = %d, pot = %d\n", szof, elc, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -13,22 +13,22 @@
|
||||
//! Андрей Бычков work.a.b@yandex.ru;
|
||||
//! \~\}
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Base macros for generic containers
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Base macros for generic containers
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICONTAINERS_H
|
||||
@@ -41,23 +41,24 @@
|
||||
#else
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
template <typename C>
|
||||
template<typename C>
|
||||
class _PIReverseWrapper {
|
||||
public:
|
||||
_PIReverseWrapper(C & c): c_(c) {}
|
||||
_PIReverseWrapper(const C & c): c_(const_cast<C&>(c)) {}
|
||||
typename C::reverse_iterator begin() {return c_.rbegin();}
|
||||
typename C::reverse_iterator end() {return c_.rend(); }
|
||||
typename C::const_reverse_iterator begin() const {return c_.rbegin();}
|
||||
typename C::const_reverse_iterator end() const {return c_.rend(); }
|
||||
_PIReverseWrapper(const C & c): c_(const_cast<C &>(c)) {}
|
||||
typename C::reverse_iterator begin() { return c_.rbegin(); }
|
||||
typename C::reverse_iterator end() { return c_.rend(); }
|
||||
typename C::const_reverse_iterator begin() const { return c_.rbegin(); }
|
||||
typename C::const_reverse_iterator end() const { return c_.rend(); }
|
||||
|
||||
private:
|
||||
C & c_;
|
||||
};
|
||||
@@ -71,15 +72,24 @@ public:
|
||||
template<typename T>
|
||||
class _PIContainerConstants {
|
||||
public:
|
||||
static size_t minCountPoT() {static size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T)); return ret;}
|
||||
static size_t minCountPoT() {
|
||||
static size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! \brief
|
||||
//! \~english Template reverse wrapper over any container
|
||||
//! \~russian Шаблонная функция обертки любого контейнера для обратного доступа через итераторы
|
||||
template <typename C> _PIReverseWrapper<C> PIReverseWrap(C & c) {return _PIReverseWrapper<C>(c);}
|
||||
template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _PIReverseWrapper<C>(c);}
|
||||
template<typename C>
|
||||
_PIReverseWrapper<C> PIReverseWrap(C & c) {
|
||||
return _PIReverseWrapper<C>(c);
|
||||
}
|
||||
template<typename C>
|
||||
_PIReverseWrapper<C> PIReverseWrap(const C & c) {
|
||||
return _PIReverseWrapper<C>(c);
|
||||
}
|
||||
|
||||
|
||||
//! \brief
|
||||
@@ -88,7 +98,7 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
|
||||
//! \~\param c
|
||||
//! \~english Iteration times in loop
|
||||
//! \~russian Количество итераций цикла
|
||||
#define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c)
|
||||
#define piForTimes(c) for (int _i##c = 0; _i##c < c; ++_i##c)
|
||||
|
||||
|
||||
//! \brief
|
||||
@@ -120,7 +130,7 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
|
||||
//! // 4
|
||||
//! \endcode
|
||||
//! \sa \a piForeachC, \a piForeachR, \a piForeachRC
|
||||
#define piForeach(i, c) for(i : c)
|
||||
#define piForeach(i, c) for (i: c)
|
||||
|
||||
//! \brief
|
||||
//! \~english Macro for iterate any container
|
||||
@@ -136,7 +146,7 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
|
||||
//! \~russian Перебор всех элементов контейнера с доступом только на чтение.
|
||||
//! Перебор осуществляется в прямом порядке.
|
||||
//! \~ \sa \a piForeach, \a piForeachR, \a piForeachRC
|
||||
#define piForeachC(i, c) for(const i : c)
|
||||
#define piForeachC(i, c) for (const i: c)
|
||||
|
||||
//! \brief
|
||||
//! \~english Macro for iterate any container
|
||||
@@ -152,7 +162,7 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
|
||||
//! \~russian Перебор всех элементов контейнера с доступом на чтение и запись.
|
||||
//! Перебор осуществляется в обратном порядке.
|
||||
//! \~ \sa \a piForeach, \a piForeachC, \a piForeachRC
|
||||
#define piForeachR(i, c) for(i : PIReverseWrap(c))
|
||||
#define piForeachR(i, c) for (i: PIReverseWrap(c))
|
||||
|
||||
//! \brief
|
||||
//! \~english Macro for iterate any container
|
||||
@@ -168,8 +178,8 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
|
||||
//! \~russian Перебор всех элементов контейнера с доступом только на чтение.
|
||||
//! Перебор осуществляется в обратном порядке. Также можно писать **piForeachCR**
|
||||
//! \~ \sa \a piForeach, \a piForeachC, \a piForeachR
|
||||
#define piForeachRC(i, c) for(const i : PIReverseWrap(c))
|
||||
#define piForeachCR piForeachRC
|
||||
#define piForeachRC(i, c) for (const i: PIReverseWrap(c))
|
||||
#define piForeachCR piForeachRC
|
||||
|
||||
|
||||
//! \~\brief
|
||||
@@ -177,8 +187,10 @@ template <typename C> _PIReverseWrapper<C> PIReverseWrap(const C & c) {return _P
|
||||
//! \~russian Порядок обхода для функции изменения размерности reshape().
|
||||
//! \~ \sa \a PIVector::reshape(), \a PIDeque::reshape()
|
||||
enum ReshapeOrder {
|
||||
ReshapeByRow /*! \~english Traversing elements by line, just as they stay in memory \~russian Обход элементов построчно, так же как они находятся в памяти */,
|
||||
ReshapeByColumn /*! \~english Traversing elements by column \~russian Обход элементов по столбцам */,
|
||||
ReshapeByRow /*! \~english Traversing elements by line, just as they stay in memory \~russian Обход элементов построчно, так же как они
|
||||
находятся в памяти */
|
||||
,
|
||||
ReshapeByColumn /*! \~english Traversing elements by column \~russian Обход элементов по столбцам */,
|
||||
};
|
||||
|
||||
#endif // PICONTAINERS_H
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Containers
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Containers
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
//! \defgroup Containers Containers
|
||||
//! \~\brief
|
||||
@@ -180,12 +180,12 @@
|
||||
#ifndef PICONTAINERSMODULE_H
|
||||
#define PICONTAINERSMODULE_H
|
||||
|
||||
#include "pivector.h"
|
||||
#include "pideque.h"
|
||||
#include "pimap.h"
|
||||
#include "piqueue.h"
|
||||
#include "piset.h"
|
||||
#include "pistack.h"
|
||||
#include "pivector.h"
|
||||
#include "pivector2d.h"
|
||||
|
||||
|
||||
|
||||
@@ -13,22 +13,22 @@
|
||||
//! Андрей Бычков work.a.b@yandex.ru;
|
||||
//! \~\}
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Dynamic array of any type
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Dynamic array of any type
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIDEQUE_H
|
||||
@@ -114,22 +114,20 @@
|
||||
//! - Вставка и удаление элементов — линейная по расстоянию до конца массива 𝓞(n)
|
||||
//!
|
||||
//! \~\sa \a PIVector, \a PIMap
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class PIDeque {
|
||||
public:
|
||||
typedef bool (*CompareFunc)(const T & , const T & );
|
||||
typedef bool (*CompareFunc)(const T &, const T &);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef size_t size_type;
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
inline PIDeque() {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
}
|
||||
inline PIDeque() { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) }
|
||||
|
||||
//! \~english Copy constructor.
|
||||
//! \~russian Копирующий конструктор.
|
||||
@@ -193,8 +191,8 @@ public:
|
||||
//! \~russian Перемещающий конструктор.
|
||||
inline PIDeque(PIDeque<T> && other) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
pid_data = other.pid_data;
|
||||
pid_size = other.pid_size;
|
||||
pid_data = other.pid_data;
|
||||
pid_size = other.pid_size;
|
||||
pid_rsize = other.pid_rsize;
|
||||
pid_start = other.pid_start;
|
||||
other._reset();
|
||||
@@ -209,7 +207,7 @@ public:
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
inline PIDeque<T> & operator =(const PIDeque<T> & other) {
|
||||
inline PIDeque<T> & operator=(const PIDeque<T> & other) {
|
||||
if (this == &other) return *this;
|
||||
clear();
|
||||
alloc_forward(other.pid_size);
|
||||
@@ -219,360 +217,330 @@ public:
|
||||
|
||||
//! \~english Assign move operator.
|
||||
//! \~russian Оператор перемещающего присваивания.
|
||||
inline PIDeque<T> & operator =(PIDeque<T> && other) {
|
||||
inline PIDeque<T> & operator=(PIDeque<T> && other) {
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
class iterator {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline iterator(PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
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 ++() {
|
||||
inline iterator & operator++() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator operator ++(int) {
|
||||
inline iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
inline iterator & operator --() {
|
||||
inline iterator & operator--() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator operator --(int) {
|
||||
inline iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline iterator & operator +=(const iterator & it) {
|
||||
inline iterator & operator+=(const iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator & operator +=(size_t p) {
|
||||
inline iterator & operator+=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
inline iterator & operator -=(const iterator & it) {
|
||||
inline iterator & operator-=(const iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator & operator -=(size_t p) {
|
||||
inline iterator & operator-=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline iterator operator -(size_t p, const iterator & it) {return it - p;}
|
||||
friend inline iterator operator -(const iterator & it, size_t p) {
|
||||
friend inline iterator operator-(size_t p, const iterator & it) { return it - p; }
|
||||
friend inline iterator operator-(const iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const iterator & it1, const iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline iterator operator +(size_t p, const iterator & it) {return it + p;}
|
||||
friend inline iterator operator +(const iterator & it, size_t p) {
|
||||
friend inline iterator operator+(size_t p, const iterator & it) { return it + p; }
|
||||
friend inline iterator operator+(const iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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 {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline const_iterator(const PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
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 ++() {
|
||||
inline const_iterator & operator++() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator operator ++(int) {
|
||||
inline const_iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
inline const_iterator & operator --() {
|
||||
inline const_iterator & operator--() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator operator --(int) {
|
||||
inline const_iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline const_iterator & operator +=(const const_iterator & it) {
|
||||
inline const_iterator & operator+=(const const_iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator +=(size_t p) {
|
||||
inline const_iterator & operator+=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator -=(const const_iterator & it) {
|
||||
inline const_iterator & operator-=(const const_iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator -=(size_t p) {
|
||||
inline const_iterator & operator-=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline const_iterator operator -(size_t p, const const_iterator & it) {return it - p;}
|
||||
friend inline const_iterator operator -(const const_iterator & it, size_t p) {
|
||||
friend inline const_iterator operator-(size_t p, const const_iterator & it) { return it - p; }
|
||||
friend inline const_iterator operator-(const const_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const const_iterator & it1, const const_iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline const_iterator operator +(size_t p, const const_iterator & it) {return it + p;}
|
||||
friend inline const_iterator operator +(const const_iterator & it, size_t p) {
|
||||
friend inline const_iterator operator+(size_t p, const const_iterator & it) { return it + p; }
|
||||
friend inline const_iterator operator+(const const_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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 {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline reverse_iterator(PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
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 ++() {
|
||||
inline reverse_iterator & operator++() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator operator ++(int) {
|
||||
inline reverse_iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
inline reverse_iterator & operator --() {
|
||||
inline reverse_iterator & operator--() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator operator --(int) {
|
||||
inline reverse_iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline reverse_iterator & operator +=(const reverse_iterator & it) {
|
||||
inline reverse_iterator & operator+=(const reverse_iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator & operator +=(size_t p) {
|
||||
inline reverse_iterator & operator+=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator & operator -=(const reverse_iterator & it) {
|
||||
inline reverse_iterator & operator-=(const reverse_iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator & operator -=(size_t p) {
|
||||
inline reverse_iterator & operator-=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline reverse_iterator operator -(size_t p, const reverse_iterator & it) {return it - p;}
|
||||
friend inline reverse_iterator operator -(const reverse_iterator & it, size_t p) {
|
||||
friend inline reverse_iterator operator-(size_t p, const reverse_iterator & it) { return it - p; }
|
||||
friend inline reverse_iterator operator-(const reverse_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it2.pos - it1.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const reverse_iterator & it1, const reverse_iterator & it2) { return it2.pos - it1.pos; }
|
||||
|
||||
friend inline reverse_iterator operator +(size_t p, const reverse_iterator & it) {return it + p;}
|
||||
friend inline reverse_iterator operator +(const reverse_iterator & it, size_t p) {
|
||||
friend inline reverse_iterator operator+(size_t p, const reverse_iterator & it) { return it + p; }
|
||||
friend inline reverse_iterator operator+(const reverse_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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 {
|
||||
friend class PIDeque<T>;
|
||||
|
||||
private:
|
||||
inline const_reverse_iterator(const PIDeque<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIDeque<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
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 ++() {
|
||||
inline const_reverse_iterator & operator++() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator operator ++(int) {
|
||||
inline const_reverse_iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
inline const_reverse_iterator & operator --() {
|
||||
inline const_reverse_iterator & operator--() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator operator --(int) {
|
||||
inline const_reverse_iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline const_reverse_iterator & operator +=(const const_reverse_iterator & it) {
|
||||
inline const_reverse_iterator & operator+=(const const_reverse_iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator & operator +=(size_t p) {
|
||||
inline const_reverse_iterator & operator+=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator & operator -=(const const_reverse_iterator & it) {
|
||||
inline const_reverse_iterator & operator-=(const const_reverse_iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator & operator -=(size_t p) {
|
||||
inline const_reverse_iterator & operator-=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline const_reverse_iterator 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) {
|
||||
friend inline const_reverse_iterator 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) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
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 +(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) {
|
||||
friend inline const_reverse_iterator 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) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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; }
|
||||
};
|
||||
|
||||
|
||||
@@ -584,7 +552,7 @@ public:
|
||||
//! \~russian Если массив - пуст, возвращаемый итератор будет равен \a end().
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a end(), \a rbegin(), \a rend()
|
||||
inline iterator begin() {return iterator(this, 0);}
|
||||
inline iterator begin() { return iterator(this, 0); }
|
||||
|
||||
//! \~english Iterator to the element following the last element.
|
||||
//! \~russian Итератор на элемент, следующий за последним элементом.
|
||||
@@ -596,10 +564,10 @@ public:
|
||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a begin(), \a rbegin(), \a rend()
|
||||
inline iterator end() {return iterator(this, pid_size);}
|
||||
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 const_iterator begin() const { return const_iterator(this, 0); }
|
||||
inline const_iterator end() const { return const_iterator(this, pid_size); }
|
||||
|
||||
//! \~english Returns a reverse iterator to the first element of the reversed array.
|
||||
//! \~russian Обратный итератор на первый элемент.
|
||||
@@ -612,7 +580,7 @@ public:
|
||||
//! Если массив пустой, то совпадает с итератором \a rend().
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rend(), \a begin(), \a end()
|
||||
inline reverse_iterator rbegin() {return reverse_iterator(this, pid_size - 1);}
|
||||
inline reverse_iterator rbegin() { return reverse_iterator(this, pid_size - 1); }
|
||||
|
||||
//! \~english Returns a reverse iterator to the element.
|
||||
//! following the last element of the reversed array.
|
||||
@@ -628,25 +596,25 @@ public:
|
||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rbegin(), \a begin(), \a end()
|
||||
inline reverse_iterator rend() {return reverse_iterator(this, -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 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); }
|
||||
|
||||
//! \~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;}
|
||||
inline size_t size() const { return pid_size; }
|
||||
|
||||
//! \~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;}
|
||||
inline ssize_t size_s() const { return pid_size; }
|
||||
|
||||
//! \~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;}
|
||||
inline size_t length() const { return pid_size; }
|
||||
|
||||
//! \~english Number of elements that the container has currently allocated space for.
|
||||
//! \~russian Количество элементов, для которого сейчас выделена память массивом.
|
||||
@@ -654,9 +622,9 @@ public:
|
||||
//! \~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 capacity() const { return pid_rsize; }
|
||||
|
||||
inline size_t _start() const {return pid_start;}
|
||||
inline size_t _start() const { return pid_start; }
|
||||
|
||||
//! \~english Checks if the container has no elements.
|
||||
//! \~russian Проверяет пуст ли массив.
|
||||
@@ -664,7 +632,7 @@ public:
|
||||
//! \~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);}
|
||||
inline bool isEmpty() const { return (pid_size == 0); }
|
||||
|
||||
//! \~english Checks if the container has elements.
|
||||
//! \~russian Проверяет не пуст ли массив.
|
||||
@@ -672,7 +640,7 @@ public:
|
||||
//! \~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);}
|
||||
inline bool isNotEmpty() const { return (pid_size > 0); }
|
||||
|
||||
//! \~english Tests whether at least one element in the array
|
||||
//! passes the test implemented by the provided function `test`.
|
||||
@@ -740,8 +708,8 @@ public:
|
||||
//! 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]; }
|
||||
|
||||
//! \~english Read only access to element by `index`.
|
||||
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
|
||||
@@ -752,7 +720,7 @@ public:
|
||||
//! \~russian Индекс элемента считается от `0`.
|
||||
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline const T & at(size_t index) const {return pid_data[pid_start + index];}
|
||||
inline const T & at(size_t index) const { return pid_data[pid_start + index]; }
|
||||
|
||||
//! \~english Returns the first element of the array that
|
||||
//! passes the test implemented by the provided function `test`
|
||||
@@ -762,8 +730,10 @@ public:
|
||||
//! \~\sa \a indexWhere()
|
||||
inline const T & atWhere(std::function<bool(const T & e)> test, ssize_t start = 0, const T & def = T()) const {
|
||||
ssize_t i = indexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Returns the last element of the array that
|
||||
@@ -774,8 +744,10 @@ public:
|
||||
//! \~\sa \a lastIndexWhere()
|
||||
inline const T & lastAtWhere(std::function<bool(const T & e)> test, ssize_t start = -1, const T & def = T()) const {
|
||||
ssize_t i = lastIndexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Last element.
|
||||
@@ -787,8 +759,8 @@ public:
|
||||
//! \~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];}
|
||||
inline T & back() { return pid_data[pid_start + pid_size - 1]; }
|
||||
inline const T & back() const { return pid_data[pid_start + pid_size - 1]; }
|
||||
|
||||
//! \~english Last element.
|
||||
//! \~russian Первый элемент массива.
|
||||
@@ -799,12 +771,12 @@ public:
|
||||
//! \~russian Возвращает ссылку на пенрвый элемент в массиве.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline T & front() {return pid_data[pid_start];}
|
||||
inline const T & front() const {return pid_data[pid_start];}
|
||||
inline T & front() { return pid_data[pid_start]; }
|
||||
inline const T & front() const { return pid_data[pid_start]; }
|
||||
|
||||
//! \~english Compare operator with array `v`.
|
||||
//! \~russian Оператор сравнения с массивом `v`.
|
||||
inline bool operator ==(const PIDeque<T> & v) const {
|
||||
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;
|
||||
@@ -814,7 +786,7 @@ public:
|
||||
|
||||
//! \~english Compare operator with array `v`.
|
||||
//! \~russian Оператор сравнения с массивом `v`.
|
||||
inline bool operator !=(const PIDeque<T> & v) const {return !(*this == v);}
|
||||
inline bool operator!=(const PIDeque<T> & v) const { return !(*this == v); }
|
||||
|
||||
//! \~english Tests if element `e` exists in the array.
|
||||
//! \~russian Проверяет наличие элемента `e` в массиве.
|
||||
@@ -873,7 +845,7 @@ public:
|
||||
start = pid_size + start;
|
||||
if (start < 0) start = 0;
|
||||
}
|
||||
for (const T & e : v) {
|
||||
for (const T & e: v) {
|
||||
bool c = false;
|
||||
for (size_t i = pid_start + size_t(start); i < pid_start + pid_size; ++i) {
|
||||
if (e == pid_data[i]) {
|
||||
@@ -1134,7 +1106,7 @@ public:
|
||||
//! memcpy(vec.data(1), a, 2 * sizeof(int));
|
||||
//! piCout << v; // {2, 12, 13, 2}
|
||||
//! \endcode
|
||||
inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);}
|
||||
inline T * data(size_t index = 0) { return &(pid_data[pid_start + index]); }
|
||||
|
||||
//! \~english Read only pointer to array
|
||||
//! \~russian Указатель на память массива только для чтения.
|
||||
@@ -1153,7 +1125,7 @@ public:
|
||||
//! 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]);}
|
||||
inline const T * data(size_t index = 0) const { return &(pid_data[pid_start + index]); }
|
||||
|
||||
//! \~english Creates sub-array of this array.
|
||||
//! \~russian Создает подмассив, то есть кусок из текущего массива.
|
||||
@@ -1184,21 +1156,17 @@ public:
|
||||
//! \~english 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>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & clear() {
|
||||
deleteT(pid_data + pid_start, pid_size);
|
||||
pid_size = 0;
|
||||
pid_size = 0;
|
||||
pid_start = (pid_rsize - pid_size) / 2;
|
||||
return *this;
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & clear() {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, pid_size)
|
||||
pid_size = 0;
|
||||
pid_size = 0;
|
||||
pid_start = (pid_rsize - pid_size) / 2;
|
||||
return *this;
|
||||
}
|
||||
@@ -1242,21 +1210,17 @@ public:
|
||||
//! \~english Same as \a fill().
|
||||
//! \~russian Тоже самое что и \a fill().
|
||||
//! \~\sa \a fill(), \a resize()
|
||||
inline PIDeque<T> & assign(const T & e = T()) {return fill(e);}
|
||||
inline PIDeque<T> & assign(const T & e = T()) { return fill(e); }
|
||||
|
||||
//! \~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>
|
||||
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 & e) {
|
||||
resize(new_size);
|
||||
return fill(e);
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
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 & e) {
|
||||
_resizeRaw(new_size);
|
||||
return fill(e);
|
||||
@@ -1278,7 +1242,7 @@ public:
|
||||
if (new_size < pid_size) {
|
||||
deleteT(pid_data + pid_start + new_size, pid_size - new_size);
|
||||
pid_size = new_size;
|
||||
}else if (new_size > pid_size) {
|
||||
} else if (new_size > pid_size) {
|
||||
expand(new_size, e);
|
||||
}
|
||||
return *this;
|
||||
@@ -1306,25 +1270,21 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIDeque<T> & _resizeRaw(size_t new_size) {
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
if (new_size > pid_size) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-pid_size));
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size - pid_size));
|
||||
}
|
||||
if (new_size < pid_size) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size-new_size));
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, (pid_size - new_size));
|
||||
}
|
||||
#endif
|
||||
alloc_forward(new_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) {
|
||||
newT(dst, src, size);
|
||||
}
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) { newT(dst, src, size); }
|
||||
|
||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
||||
@@ -1367,12 +1327,12 @@ public:
|
||||
alloc_forward(pid_size + 1);
|
||||
if (index < pid_size - 1) {
|
||||
size_t os = pid_size - index - 1;
|
||||
memmove((void*)(pid_data + pid_start + index + 1), (const void*)(pid_data + pid_start + index), os * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + index + 1), (const void *)(pid_data + pid_start + index), os * sizeof(T));
|
||||
}
|
||||
} else {
|
||||
alloc_backward(pid_size + 1, -1);
|
||||
if (index > 0) {
|
||||
memmove((void*)(pid_data + pid_start), (const void*)(pid_data + pid_start + 1), index * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start), (const void *)(pid_data + pid_start + 1), index * sizeof(T));
|
||||
}
|
||||
}
|
||||
elementNew(pid_data + pid_start + index, e);
|
||||
@@ -1393,12 +1353,12 @@ public:
|
||||
alloc_forward(pid_size + 1);
|
||||
if (index < pid_size - 1) {
|
||||
size_t os = pid_size - index - 1;
|
||||
memmove((void*)(pid_data + pid_start + index + 1), (const void*)(pid_data + pid_start + index), os * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + index + 1), (const void *)(pid_data + pid_start + index), os * sizeof(T));
|
||||
}
|
||||
} else {
|
||||
alloc_backward(pid_size + 1, -1);
|
||||
if (index > 0) {
|
||||
memmove((void*)(pid_data + pid_start), (const void*)(pid_data + pid_start + 1), index * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start), (const void *)(pid_data + pid_start + 1), index * sizeof(T));
|
||||
}
|
||||
}
|
||||
elementNew(pid_data + pid_start + index, std::move(e));
|
||||
@@ -1424,12 +1384,12 @@ public:
|
||||
ssize_t os = pid_size - index;
|
||||
alloc_forward(pid_size + v.pid_size);
|
||||
if (os > 0) {
|
||||
memmove((void*)(pid_data + pid_start + index + v.pid_size), (const void*)(pid_data + pid_start + index), os * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + index + v.pid_size), (const void *)(pid_data + pid_start + index), os * sizeof(T));
|
||||
}
|
||||
} else {
|
||||
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 + v.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, v.pid_data + v.pid_start, v.pid_size);
|
||||
@@ -1453,12 +1413,14 @@ public:
|
||||
ssize_t os = ssize_t(pid_size) - index;
|
||||
alloc_forward(pid_size + init_list.size());
|
||||
if (os > 0) {
|
||||
memmove((void*)(pid_data + pid_start + index + init_list.size()), (const void*)(pid_data + pid_start + index), os * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + index + init_list.size()),
|
||||
(const void *)(pid_data + pid_start + index),
|
||||
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));
|
||||
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());
|
||||
@@ -1485,10 +1447,10 @@ public:
|
||||
size_t os = pid_size - index - count;
|
||||
deleteT(pid_data + pid_start + index, count);
|
||||
if (os <= index) {
|
||||
memmove((void*)(pid_data + pid_start + index), (const void*)(pid_data + pid_start + index + count), os * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + index), (const void *)(pid_data + pid_start + index + count), os * sizeof(T));
|
||||
} else {
|
||||
if (index > 0) {
|
||||
memmove((void*)(pid_data + pid_start + count), (const void*)(pid_data + pid_start), index * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + count), (const void *)(pid_data + pid_start), index * sizeof(T));
|
||||
}
|
||||
pid_start += count;
|
||||
}
|
||||
@@ -1503,7 +1465,7 @@ public:
|
||||
//! \~english This operation is very fast and never fails.
|
||||
//! \~russian Эта операция выполняется мгновенно без копирования памяти и никогда не дает сбоев.
|
||||
inline void swap(PIDeque<T> & other) {
|
||||
piSwap<T*>(pid_data, other.pid_data);
|
||||
piSwap<T *>(pid_data, other.pid_data);
|
||||
piSwap<size_t>(pid_size, other.pid_size);
|
||||
piSwap<size_t>(pid_rsize, other.pid_rsize);
|
||||
piSwap<size_t>(pid_start, other.pid_start);
|
||||
@@ -1548,23 +1510,18 @@ public:
|
||||
//! Complexity `O(N·log(N))`.
|
||||
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
||||
//! Для сравнения элементов используется функция сравнения `comp`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше второго.
|
||||
//! Сигнатура функции сравнения должна быть эквивалентна следующей:
|
||||
//! \code
|
||||
//! bool comp(const T &a, const T &b);
|
||||
//! \endcode
|
||||
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
||||
//! Функция обязана возвращать `false` для одинаковых элементов,
|
||||
//! иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
||||
//! Сложность сортировки `O(N·log(N))`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше
|
||||
//! второго. Сигнатура функции сравнения должна быть эквивалентна следующей: \code bool comp(const T &a, const T &b); \endcode Сигнатура
|
||||
//! не обязана содержать const &, однако, функция не может изменять переданные объекты. Функция обязана возвращать `false` для
|
||||
//! одинаковых элементов, иначе это приведёт к неопределённому поведению программы и ошибкам памяти. Для сортировки используется функция
|
||||
//! [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort). Сложность сортировки `O(N·log(N))`.
|
||||
//! \~\code
|
||||
//! PIDeque<int> v{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
|
||||
//! v.sort([](const int & a, const int & b){return a > b;});
|
||||
//! piCout << v; // 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
//! \endcode
|
||||
//! \~\sa \a sort()
|
||||
inline PIDeque<T> & sort(std::function<bool(const T &a, const T &b)> comp) {
|
||||
inline PIDeque<T> & sort(std::function<bool(const T & a, const T & b)> comp) {
|
||||
std::sort(begin(), end(), comp);
|
||||
return *this;
|
||||
}
|
||||
@@ -1587,9 +1544,9 @@ public:
|
||||
//! \endcode
|
||||
//! \~\sa \a reversed()
|
||||
inline PIDeque<T> & reverse() {
|
||||
size_t s2 = pid_size/2;
|
||||
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]);
|
||||
piSwap<T>(pid_data[pid_start + i], pid_data[pid_start + pid_size - i - 1]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -1619,8 +1576,10 @@ public:
|
||||
//! \~\sa \a resize()
|
||||
inline PIDeque<T> & enlarge(ssize_t add_size, const T & e = T()) {
|
||||
ssize_t ns = size_s() + add_size;
|
||||
if (ns <= 0) clear();
|
||||
else resize(size_t(ns), e);
|
||||
if (ns <= 0)
|
||||
clear();
|
||||
else
|
||||
resize(size_t(ns), e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1789,7 +1748,7 @@ public:
|
||||
//! 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> & append(const T & e) { return push_back(e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the end of the array.
|
||||
//! \~russian Добавляет элемент `e` в конец массива.
|
||||
@@ -1797,7 +1756,7 @@ public:
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a append()
|
||||
inline PIDeque<T> & append(T && e) {return push_back(std::move(e));}
|
||||
inline PIDeque<T> & append(T && e) { return push_back(std::move(e)); }
|
||||
|
||||
//! \~english Appends the given elements to the end of the array.
|
||||
//! \~russian Добавляет элементы в конец массива.
|
||||
@@ -1809,7 +1768,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации 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);}
|
||||
inline PIDeque<T> & append(std::initializer_list<T> init_list) { return push_back(init_list); }
|
||||
|
||||
//! \~english Appends the given array `v` to the end of the array.
|
||||
//! \~russian Добавляет массив `v` в конец массива.
|
||||
@@ -1822,7 +1781,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a append()
|
||||
inline PIDeque<T> & append(const PIDeque<T> & v) {return push_back(v);}
|
||||
inline PIDeque<T> & append(const PIDeque<T> & v) { return push_back(v); }
|
||||
|
||||
//! \~english Appends the given element `e` to the end of the array.
|
||||
//! \~russian Добавляет элемент `e` в конец массива.
|
||||
@@ -1833,7 +1792,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a append()
|
||||
inline PIDeque<T> & operator <<(const T & e) {return push_back(e);}
|
||||
inline PIDeque<T> & operator<<(const T & e) { return push_back(e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the end of the array.
|
||||
//! \~russian Добавляет элемент `e` в конец массива.
|
||||
@@ -1844,7 +1803,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a append()
|
||||
inline PIDeque<T> & operator <<(T && e) {return push_back(std::move(e));}
|
||||
inline PIDeque<T> & operator<<(T && e) { return push_back(std::move(e)); }
|
||||
|
||||
//! \~english Appends the given array `v` to the end of the array.
|
||||
//! \~russian Добавляет массив `v` в конец массива.
|
||||
@@ -1855,7 +1814,7 @@ public:
|
||||
//! 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);}
|
||||
inline PIDeque<T> & operator<<(const PIDeque<T> & v) { return append(v); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1912,9 +1871,7 @@ public:
|
||||
//! piCout << v; // {4, 5, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a push_front()
|
||||
inline PIDeque<T> & push_front(const PIDeque<T> & v) {
|
||||
return insert(0, v);
|
||||
}
|
||||
inline PIDeque<T> & push_front(const PIDeque<T> & v) { return insert(0, v); }
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
@@ -1926,9 +1883,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации 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) {
|
||||
return insert(0, init_list);
|
||||
}
|
||||
inline PIDeque<T> & push_front(std::initializer_list<T> init_list) { return insert(0, init_list); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1954,7 +1909,7 @@ public:
|
||||
//! 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);}
|
||||
inline PIDeque<T> & prepend(const T & e) { return push_front(e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1962,7 +1917,7 @@ public:
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a prepend()
|
||||
inline PIDeque<T> & prepend(T && e) {return push_front(std::move(e));}
|
||||
inline PIDeque<T> & prepend(T && e) { return push_front(std::move(e)); }
|
||||
|
||||
//! \~english Appends the given array `v` to the begin of the array.
|
||||
//! \~russian Добавляет массив `v` в начало массива.
|
||||
@@ -1975,7 +1930,7 @@ public:
|
||||
//! piCout << v; // {4, 5, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a prepend()
|
||||
inline PIDeque<T> & prepend(const PIDeque<T> & v) {return push_front(v);}
|
||||
inline PIDeque<T> & prepend(const PIDeque<T> & v) { return push_front(v); }
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
@@ -1987,7 +1942,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации 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 push_front(init_list);}
|
||||
inline PIDeque<T> & prepend(std::initializer_list<T> init_list) { return push_front(init_list); }
|
||||
|
||||
//! \~english Remove one element from the end of the array.
|
||||
//! \~russian Удаляет один элемент с конца массива.
|
||||
@@ -2071,7 +2026,7 @@ public:
|
||||
//! piCout << v2; // {1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> toType() const {
|
||||
PIDeque<ST> ret(pid_size);
|
||||
ret.reserve(pid_size);
|
||||
@@ -2116,7 +2071,7 @@ public:
|
||||
//! \~\sa \a filter()
|
||||
inline PIDeque<T> filterReverse(std::function<bool(const T & e)> test) const {
|
||||
PIDeque<T> ret;
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
if (test(pid_data[i])) ret << pid_data[i];
|
||||
}
|
||||
return ret;
|
||||
@@ -2127,7 +2082,7 @@ public:
|
||||
//! \~\sa \a filterReverse()
|
||||
inline PIDeque<T> filterReverseIndexed(std::function<bool(size_t index, const T & e)> test) const {
|
||||
PIDeque<T> ret;
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
if (test(i - pid_start, pid_data[i])) ret << pid_data[i];
|
||||
}
|
||||
return ret;
|
||||
@@ -2196,7 +2151,7 @@ public:
|
||||
//! \~russian Аналогично \a forEach() но от конца до начала (справа на лево).
|
||||
//! \~\sa \a forEach()
|
||||
inline void forEachReverse(std::function<void(const T & e)> f) const {
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
f(pid_data[i]);
|
||||
}
|
||||
}
|
||||
@@ -2205,7 +2160,7 @@ public:
|
||||
//! \~russian Аналогично \a forEachReverse(), но позволяет изменять элементы массива.
|
||||
//! \~\sa \a forEach(), \a forEachReverse()
|
||||
inline PIDeque<T> & forEachReverse(std::function<void(T & e)> f) {
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
f(pid_data[i]);
|
||||
}
|
||||
return *this;
|
||||
@@ -2215,7 +2170,7 @@ public:
|
||||
//! \~russian Аналогично \a forEachIndexed() но от конца до начала (справа на лево).
|
||||
//! \~\sa \a forEachIndexed(), \a forEachReverse(), \a forEach()
|
||||
inline void forEachReverseIndexed(std::function<void(size_t index, const T & e)> f) const {
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
f(i - pid_start, pid_data[i]);
|
||||
}
|
||||
}
|
||||
@@ -2224,7 +2179,7 @@ public:
|
||||
//! \~russian Аналогично \a forEachReverseIndexed(), но позволяет изменять элементы массива.
|
||||
//! \~\sa \a forEachReverseIndexed(), \a forEachIndexed(), \a forEachReverse(), \a forEach()
|
||||
inline PIDeque<T> & forEachReverseIndexed(std::function<void(size_t index, T & e)> f) {
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
f(i - pid_start, pid_data[i]);
|
||||
}
|
||||
return *this;
|
||||
@@ -2247,9 +2202,10 @@ public:
|
||||
//! piCout << sl; // {"1", "2", "3"}
|
||||
//! \endcode
|
||||
//! \~\sa \a forEach(), \a reduce()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> map(std::function<ST(const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
||||
ret << f(pid_data[i]);
|
||||
}
|
||||
@@ -2264,9 +2220,10 @@ public:
|
||||
//! piCout << sl; // {"0", "1", "2"}
|
||||
//! \endcode
|
||||
//! \~\sa \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> mapIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
||||
ret << f(i - pid_start, pid_data[i]);
|
||||
}
|
||||
@@ -2281,10 +2238,11 @@ public:
|
||||
//! piCout << sl; // {"3", "2", "1"}
|
||||
//! \endcode
|
||||
//! \~\sa \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> mapReverse(std::function<ST(const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
ret << f(pid_data[i]);
|
||||
}
|
||||
return ret;
|
||||
@@ -2298,10 +2256,11 @@ public:
|
||||
//! piCout << sl; // {"2", "1", "0"}
|
||||
//! \endcode
|
||||
//! \~\sa \a mapReverse()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIDeque<ST> mapReverseIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
PIDeque<ST> ret;
|
||||
ret.reserve(pid_size);
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
ret << f(size_t(i) - pid_start, pid_data[i]);
|
||||
}
|
||||
return ret;
|
||||
@@ -2348,7 +2307,7 @@ public:
|
||||
//! piCout << s; // 15
|
||||
//! \endcode
|
||||
//! \~\sa \a reduceIndexed(), \a reduceReverse(), \a reduceReverseIndexed(), \a forEach(), \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
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 = pid_start; i < pid_start + pid_size; ++i) {
|
||||
@@ -2360,7 +2319,7 @@ public:
|
||||
//! \~english Same as \a reduce() but with `index` parameter in `f`.
|
||||
//! \~russian Аналогично \a reduce() но с параметром индекса `index` в функции `f`.
|
||||
//! \~\sa \a reduce()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline ST reduceIndexed(std::function<ST(size_t index, const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||
ST ret(initial);
|
||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
||||
@@ -2372,10 +2331,10 @@ public:
|
||||
//! \~english Same as \a reduce() but from end to begin (from right to left).
|
||||
//! \~russian Аналогично \a reduce() но от конца до начала (справа на лево).
|
||||
//! \~\sa \a reduce()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline ST reduceReverse(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||
ST ret(initial);
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
ret = f(pid_data[i], ret);
|
||||
}
|
||||
return ret;
|
||||
@@ -2384,10 +2343,10 @@ public:
|
||||
//! \~english Same as \a reduceReverse() but with `index` parameter in `f`.
|
||||
//! \~russian Аналогично \a reduceReverse() но с параметром индекса `index` в функции `f`.
|
||||
//! \~\sa \a reduceReverse()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline ST reduceReverseIndexed(std::function<ST(size_t index, const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||
ST ret(initial);
|
||||
for (ssize_t i = ssize_t(pid_start+pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
for (ssize_t i = ssize_t(pid_start + pid_size) - 1; i >= ssize_t(pid_start); --i) {
|
||||
ret = f(size_t(i) - pid_start, pid_data[i], ret);
|
||||
}
|
||||
return ret;
|
||||
@@ -2416,22 +2375,22 @@ public:
|
||||
PIDeque<PIDeque<T>> ret;
|
||||
if (isEmpty()) return ret;
|
||||
#ifndef NDEBUG
|
||||
if (rows*cols != pid_size) {
|
||||
if (rows * cols != pid_size) {
|
||||
printf("error with PIDeque<%s>::reshape\n", __PIP_TYPENAME__(T));
|
||||
}
|
||||
#endif
|
||||
assert(rows*cols == pid_size);
|
||||
assert(rows * cols == pid_size);
|
||||
ret.expand(rows);
|
||||
if (order == ReshapeByRow) {
|
||||
for (size_t r = 0; r < rows; r++) {
|
||||
ret[r] = PIDeque<T>(&(pid_data[r*cols]), cols);
|
||||
ret[r] = PIDeque<T>(&(pid_data[r * cols]), cols);
|
||||
}
|
||||
}
|
||||
if (order == ReshapeByColumn) {
|
||||
for (size_t r = 0; r < rows; r++) {
|
||||
ret[r].expand(cols);
|
||||
for (size_t c = 0; c < cols; c++) {
|
||||
ret[r][c] = pid_data[c*rows + r];
|
||||
ret[r][c] = pid_data[c * rows + r];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2452,9 +2411,7 @@ public:
|
||||
//! 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>
|
||||
template<typename C, typename std::enable_if<std::is_same<T, PIDeque<C>>::value, int>::type = 0>
|
||||
inline PIDeque<C> flatten(ReshapeOrder order = ReshapeByRow) const {
|
||||
PIDeque<C> ret;
|
||||
if (isEmpty()) return ret;
|
||||
@@ -2495,9 +2452,7 @@ public:
|
||||
//! 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>
|
||||
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);
|
||||
@@ -2514,11 +2469,11 @@ public:
|
||||
PIDeque<PIDeque<T>> ret;
|
||||
if (isEmpty()) return ret;
|
||||
size_t start = 0;
|
||||
ssize_t ci = indexOf(separator, start);
|
||||
ssize_t ci = indexOf(separator, start);
|
||||
while (ci >= 0) {
|
||||
ret << PIDeque<T>(pid_data + pid_start + start, ci - start);
|
||||
start = ci + 1;
|
||||
ci = indexOf(separator, start);
|
||||
ci = indexOf(separator, start);
|
||||
}
|
||||
if (start < pid_size) {
|
||||
ret << PIDeque<T>(pid_data + pid_start + start, pid_size - start);
|
||||
@@ -2534,9 +2489,9 @@ public:
|
||||
if (isEmpty() || sz == 0) return ret;
|
||||
size_t ch = pid_size / sz;
|
||||
for (size_t i = 0; i < ch; ++i) {
|
||||
ret << PIDeque<T>(pid_data + pid_start + sz*i, sz);
|
||||
ret << PIDeque<T>(pid_data + pid_start + sz * i, sz);
|
||||
}
|
||||
size_t t = ch*sz;
|
||||
size_t t = ch * sz;
|
||||
if (t < pid_size) {
|
||||
ret << PIDeque<T>(pid_data + pid_start + t, pid_size - t);
|
||||
}
|
||||
@@ -2565,16 +2520,16 @@ public:
|
||||
if (index >= pid_size || count == 0) return ret;
|
||||
if (index + count > pid_size) count = pid_size - index;
|
||||
ret.alloc_forward(count);
|
||||
memcpy((void*)(ret.pid_data + ret.pid_start), (const void*)(pid_data + pid_start + index), count * sizeof(T));
|
||||
memcpy((void *)(ret.pid_data + ret.pid_start), (const void *)(pid_data + pid_start + index), count * sizeof(T));
|
||||
|
||||
size_t os = pid_size - index - count;
|
||||
if (os <= index) {
|
||||
if (os > 0) {
|
||||
memmove((void*)(pid_data + pid_start + index), (const void*)(pid_data + pid_start + index + count), os * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + index), (const void *)(pid_data + pid_start + index + count), os * sizeof(T));
|
||||
}
|
||||
} else {
|
||||
if (index > 0) {
|
||||
memmove((void*)(pid_data + pid_start + count), (const void*)(pid_data + pid_start), index * sizeof(T));
|
||||
memmove((void *)(pid_data + pid_start + count), (const void *)(pid_data + pid_start), index * sizeof(T));
|
||||
}
|
||||
pid_start += count;
|
||||
}
|
||||
@@ -2584,10 +2539,10 @@ public:
|
||||
|
||||
private:
|
||||
inline void _reset() {
|
||||
pid_size = 0;
|
||||
pid_size = 0;
|
||||
pid_rsize = 0;
|
||||
pid_start = 0;
|
||||
pid_data = nullptr;
|
||||
pid_data = nullptr;
|
||||
}
|
||||
|
||||
inline size_t asize(ssize_t s) {
|
||||
@@ -2595,15 +2550,14 @@ private:
|
||||
if (pid_rsize * 2 >= size_t(s) && pid_rsize < size_t(s)) {
|
||||
return pid_rsize * 2;
|
||||
}
|
||||
size_t t = _PIContainerConstants<T>::minCountPoT();
|
||||
size_t t = _PIContainerConstants<T>::minCountPoT();
|
||||
size_t s_ = s - 1;
|
||||
while (s_ >> t) ++t;
|
||||
while (s_ >> t)
|
||||
++t;
|
||||
return (1 << t);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
for (size_t i = 0; i < s; ++i) {
|
||||
@@ -2611,17 +2565,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
memcpy((void*)(dst), (const void*)(src), s * sizeof(T));
|
||||
memcpy((void *)(dst), (const void *)(src), s * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
if (d != nullptr) {
|
||||
@@ -2631,56 +2581,42 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, const T & from) {
|
||||
new(to)T(from);
|
||||
new (to) T(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
new(to)T(std::move(from));
|
||||
new (to) T(std::move(from));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T1 * to, const T & from) {
|
||||
(*to) = from;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
(*to) = std::move(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {
|
||||
from.~T();
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {}
|
||||
|
||||
inline void dealloc() {
|
||||
if (pid_data != nullptr) {
|
||||
free((void*)pid_data);
|
||||
free((void *)pid_data);
|
||||
pid_data = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -2691,7 +2627,7 @@ private:
|
||||
if (pid_start < (pid_size * 2) || ssize_t(pid_start) > (ssize_t(pid_rsize) - (ssize_t(pid_size) * 2))) {
|
||||
size_t ns = (pid_rsize - pid_size) / 2;
|
||||
if (pid_start != ns) {
|
||||
memmove((void*)(pid_data + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
||||
memmove((void *)(pid_data + ns), (const void *)(pid_data + pid_start), pid_size * sizeof(T));
|
||||
pid_start = ns;
|
||||
}
|
||||
}
|
||||
@@ -2699,7 +2635,7 @@ private:
|
||||
} else {
|
||||
size_t ns = (pid_rsize - pid_size) / 2;
|
||||
if (pid_start != ns) {
|
||||
memmove((void*)(pid_data + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
||||
memmove((void *)(pid_data + ns), (const void *)(pid_data + pid_start), pid_size * sizeof(T));
|
||||
pid_start = ns;
|
||||
}
|
||||
}
|
||||
@@ -2711,18 +2647,18 @@ private:
|
||||
if (pid_start > 0) checkMove();
|
||||
return;
|
||||
}
|
||||
pid_size = new_size;
|
||||
pid_size = new_size;
|
||||
size_t as = asize(pid_start + new_size);
|
||||
if (as != pid_rsize) {
|
||||
PIINTROSPECTION_CONTAINER_ALLOC(T, (as-pid_rsize))
|
||||
T * p_d = (T*)(realloc((void*)(pid_data), as*sizeof(T)));
|
||||
PIINTROSPECTION_CONTAINER_ALLOC(T, (as - pid_rsize))
|
||||
T * p_d = (T *)(realloc((void *)(pid_data), as * sizeof(T)));
|
||||
#ifndef NDEBUG
|
||||
if (!p_d) {
|
||||
printf("error with PIDeque<%s>::alloc\n", __PIP_TYPENAME__(T));
|
||||
}
|
||||
#endif
|
||||
assert(p_d);
|
||||
pid_data = p_d;
|
||||
pid_data = p_d;
|
||||
pid_rsize = as;
|
||||
}
|
||||
}
|
||||
@@ -2735,14 +2671,14 @@ private:
|
||||
as = pid_rsize;
|
||||
}
|
||||
if (as > pid_rsize) {
|
||||
T * td = (T*)(malloc(as * sizeof(T)));
|
||||
T * td = (T *)(malloc(as * sizeof(T)));
|
||||
size_t ns = pid_start + as - pid_rsize;
|
||||
PIINTROSPECTION_CONTAINER_ALLOC(T, (as-pid_rsize))
|
||||
PIINTROSPECTION_CONTAINER_ALLOC(T, (as - pid_rsize))
|
||||
if (pid_rsize > 0 && pid_data != 0) {
|
||||
memcpy((void*)(td + ns), (const void*)(pid_data + pid_start), pid_size * sizeof(T));
|
||||
memcpy((void *)(td + ns), (const void *)(pid_data + pid_start), pid_size * sizeof(T));
|
||||
dealloc();
|
||||
}
|
||||
pid_data = td;
|
||||
pid_data = td;
|
||||
pid_rsize = as;
|
||||
pid_start = ns;
|
||||
}
|
||||
@@ -2754,7 +2690,7 @@ private:
|
||||
inline void expand(size_t new_size, const T & e = T()) {
|
||||
size_t os = pid_size;
|
||||
alloc_forward(new_size);
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size - os))
|
||||
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
|
||||
elementNew(pid_data + i, e);
|
||||
}
|
||||
@@ -2763,14 +2699,14 @@ private:
|
||||
inline void expand(size_t new_size, std::function<T(size_t i)> f) {
|
||||
size_t os = pid_size;
|
||||
alloc_forward(new_size);
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||
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(i));
|
||||
}
|
||||
}
|
||||
|
||||
T * pid_data = nullptr;
|
||||
size_t pid_size = 0;
|
||||
T * pid_data = nullptr;
|
||||
size_t pid_size = 0;
|
||||
size_t pid_rsize = 0;
|
||||
size_t pid_start = 0;
|
||||
};
|
||||
@@ -2780,7 +2716,7 @@ private:
|
||||
//! \~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) {
|
||||
inline std::ostream & operator<<(std::ostream & s, const PIDeque<T> & v) {
|
||||
s << "{";
|
||||
for (size_t i = 0; i < v.size(); ++i) {
|
||||
s << v[i];
|
||||
@@ -2796,7 +2732,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIDeque<T> & v) {
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
template<typename T>
|
||||
inline PICout operator <<(PICout s, const PIDeque<T> & v) {
|
||||
inline PICout operator<<(PICout s, const PIDeque<T> & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "{";
|
||||
@@ -2810,7 +2746,9 @@ inline PICout operator <<(PICout s, const PIDeque<T> & v) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void piSwap(PIDeque<T> & f, PIDeque<T> & s) {f.swap(s);}
|
||||
inline void piSwap(PIDeque<T> & f, PIDeque<T> & s) {
|
||||
f.swap(s);
|
||||
}
|
||||
|
||||
|
||||
#endif // PIDEQUE_H
|
||||
|
||||
@@ -13,36 +13,40 @@
|
||||
//! Андрей Бычков work.a.b@yandex.ru;
|
||||
//! \~\}
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Associative array with custom types of key and value
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Associative array with custom types of key and value
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIMAP_H
|
||||
#define PIMAP_H
|
||||
|
||||
#include "pivector.h"
|
||||
#include "pideque.h"
|
||||
#include "pipair.h"
|
||||
#include "pivector.h"
|
||||
|
||||
|
||||
template <typename Key, typename T> class PIMapIteratorConst;
|
||||
template <typename Key, typename T> class PIMapIteratorConstReverse;
|
||||
template <typename Key, typename T> class PIMapIterator;
|
||||
template <typename Key, typename T> class PIMapIteratorReverse;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConst;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConstReverse;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIterator;
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorReverse;
|
||||
|
||||
|
||||
//! \addtogroup Containers
|
||||
@@ -74,16 +78,21 @@ template <typename Key, typename T> class PIMapIteratorReverse;
|
||||
//! по которым их можно найти, которыми могут выступать значения любого типа.
|
||||
//! \a operator [] позволяет получить доступ к элементу по ключу,
|
||||
//! и если такого эелемента не было, то он будет создан.
|
||||
template <typename Key, typename T>
|
||||
template<typename Key, typename T>
|
||||
class PIMap {
|
||||
template <typename Key1, typename T1> friend class PIMapIteratorConst;
|
||||
template <typename Key1, typename T1> friend class PIMapIteratorConstReverse;
|
||||
template <typename Key1, typename T1> friend class PIMapIterator;
|
||||
template <typename Key1, typename T1> friend class PIMapIteratorReverse;
|
||||
template <typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMap<Key1, T1> & v);
|
||||
template <typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMap<Key1, T1> & v);
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIteratorConst;
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIteratorConstReverse;
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIterator;
|
||||
template<typename Key1, typename T1>
|
||||
friend class PIMapIteratorReverse;
|
||||
template<typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMap<Key1, T1> & v);
|
||||
template<typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key1, T1> & v);
|
||||
|
||||
public:
|
||||
typedef T mapped_type;
|
||||
typedef Key key_type;
|
||||
@@ -95,11 +104,11 @@ public:
|
||||
|
||||
//! \~english Copy constructor.
|
||||
//! \~russian Копирующий конструктор.
|
||||
inline PIMap(const PIMap<Key, T> & other) : pim_content(other.pim_content), pim_index(other.pim_index) {}
|
||||
inline PIMap(const PIMap<Key, T> & other): pim_content(other.pim_content), pim_index(other.pim_index) {}
|
||||
|
||||
//! \~english Move constructor.
|
||||
//! \~russian Перемещающий конструктор.
|
||||
inline PIMap(PIMap<Key, T> && other) : pim_content(std::move(other.pim_content)), pim_index(std::move(other.pim_index)) {}
|
||||
inline 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).
|
||||
@@ -118,150 +127,158 @@ public:
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
inline PIMap<Key, T> & operator =(const PIMap<Key, T> & other) {
|
||||
inline PIMap<Key, T> & operator=(const PIMap<Key, T> & other) {
|
||||
if (this == &other) return *this;
|
||||
clear();
|
||||
pim_content = other.pim_content;
|
||||
pim_index = other.pim_index;
|
||||
pim_index = other.pim_index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Assign move operator.
|
||||
//! \~russian Оператор перемещающего присваивания.
|
||||
inline PIMap<Key, T> & operator =(PIMap<Key, T> && other) {
|
||||
inline PIMap<Key, T> & operator=(PIMap<Key, T> && other) {
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
class iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
iterator(): parent(nullptr), pos(0) {}
|
||||
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(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));
|
||||
const Key & key() const { return const_cast<PIMap<Key, T> *>(parent)->_key(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));
|
||||
}
|
||||
void operator ++() {++pos;}
|
||||
void operator ++(int) {++pos;}
|
||||
void operator --() {--pos;}
|
||||
void operator --(int) {--pos;}
|
||||
bool operator ==(const iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const iterator & it) const {return (pos != it.pos);}
|
||||
void operator++() { ++pos; }
|
||||
void operator++(int) { ++pos; }
|
||||
void operator--() { --pos; }
|
||||
void operator--(int) { --pos; }
|
||||
bool operator==(const iterator & it) const { return (pos == it.pos); }
|
||||
bool operator!=(const iterator & it) const { return (pos != it.pos); }
|
||||
};
|
||||
|
||||
|
||||
class reverse_iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
reverse_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
reverse_iterator(): parent(nullptr), pos(0) {}
|
||||
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);}
|
||||
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));
|
||||
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); }
|
||||
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 ++(int) {--pos;}
|
||||
void operator --() {++pos;}
|
||||
void operator --(int) {++pos;}
|
||||
bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
|
||||
void operator++() { --pos; }
|
||||
void operator++(int) { --pos; }
|
||||
void operator--() { ++pos; }
|
||||
void operator--(int) { ++pos; }
|
||||
bool operator==(const reverse_iterator & it) const { return (pos == it.pos); }
|
||||
bool operator!=(const reverse_iterator & it) const { return (pos != it.pos); }
|
||||
};
|
||||
|
||||
|
||||
class const_iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
const_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
const_iterator(): parent(nullptr), pos(0) {}
|
||||
const value_type operator *() const {return parent->_pair(pos);}
|
||||
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(pos);}
|
||||
const T & value() const {return const_cast<PIMap<Key, T> * >(parent)->_value(pos);}
|
||||
void operator ++() {++pos;}
|
||||
void operator ++(int) {++pos;}
|
||||
void operator --() {--pos;}
|
||||
void operator --(int) {--pos;}
|
||||
bool operator ==(const const_iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const const_iterator & it) const {return (pos != it.pos);}
|
||||
const value_type operator*() const { return parent->_pair(pos); }
|
||||
const Key & key() const { return const_cast<PIMap<Key, T> *>(parent)->_key(pos); }
|
||||
const T & value() const { return const_cast<PIMap<Key, T> *>(parent)->_value(pos); }
|
||||
void operator++() { ++pos; }
|
||||
void operator++(int) { ++pos; }
|
||||
void operator--() { --pos; }
|
||||
void operator--(int) { --pos; }
|
||||
bool operator==(const const_iterator & it) const { return (pos == it.pos); }
|
||||
bool operator!=(const const_iterator & it) const { return (pos != it.pos); }
|
||||
};
|
||||
|
||||
|
||||
class const_reverse_iterator {
|
||||
friend class PIMap<Key, T>;
|
||||
|
||||
private:
|
||||
const_reverse_iterator(const PIMap<Key, T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIMap<Key, T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
const_reverse_iterator(): parent(nullptr), pos(0) {}
|
||||
const value_type operator *() const {return parent->_pair(pos);}
|
||||
void operator ++() {--pos;}
|
||||
void operator ++(int) {--pos;}
|
||||
void operator --() {++pos;}
|
||||
void operator --(int) {++pos;}
|
||||
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
|
||||
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
|
||||
const value_type operator*() const { return parent->_pair(pos); }
|
||||
void operator++() { --pos; }
|
||||
void operator++(int) { --pos; }
|
||||
void operator--() { ++pos; }
|
||||
void operator--(int) { ++pos; }
|
||||
bool operator==(const const_reverse_iterator & it) const { return (pos == it.pos); }
|
||||
bool operator!=(const const_reverse_iterator & it) const { return (pos != it.pos); }
|
||||
};
|
||||
|
||||
|
||||
//! \~english Iterator to the first element.
|
||||
//! \~russian Итератор на первый элемент.
|
||||
inline iterator begin() {return iterator(this, 0);}
|
||||
inline iterator begin() { return iterator(this, 0); }
|
||||
|
||||
//! \~english Iterator to the element following the last element.
|
||||
//! \~russian Итератор на элемент, следующий за последним элементом.
|
||||
inline iterator end() {return iterator(this, size());}
|
||||
inline iterator end() { return iterator(this, size()); }
|
||||
|
||||
inline const_iterator begin() const {return const_iterator(this, 0);}
|
||||
inline const_iterator end() const {return const_iterator(this, size());}
|
||||
inline const_iterator begin() const { return const_iterator(this, 0); }
|
||||
inline const_iterator end() const { return const_iterator(this, size()); }
|
||||
|
||||
//! \~english Returns a reverse iterator to the first element of the reversed array.
|
||||
//! \~russian Обратный итератор на первый элемент.
|
||||
inline reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);}
|
||||
inline reverse_iterator rbegin() { return reverse_iterator(this, size() - 1); }
|
||||
|
||||
//! \~english Returns a reverse iterator to the element.
|
||||
//! following the last element of the reversed array.
|
||||
//! \~russian Обратный итератор на элемент,
|
||||
//! следующий за последним элементом.
|
||||
inline reverse_iterator rend() {return reverse_iterator(this, -1);}
|
||||
inline reverse_iterator rend() { return reverse_iterator(this, -1); }
|
||||
|
||||
inline const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);}
|
||||
inline const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
||||
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(this, size() - 1); }
|
||||
inline const_reverse_iterator rend() const { return const_reverse_iterator(this, -1); }
|
||||
|
||||
//! \relatesalso PIMapIteratorConst
|
||||
inline PIMapIteratorConst<Key, T> makeIterator() const {return PIMapIteratorConst<Key, T>(*this);}
|
||||
inline PIMapIteratorConst<Key, T> makeIterator() const { return PIMapIteratorConst<Key, T>(*this); }
|
||||
|
||||
//! \relatesalso PIMapIterator
|
||||
inline PIMapIterator<Key, T> makeIterator() {return PIMapIterator<Key, T>(*this);}
|
||||
inline PIMapIterator<Key, T> makeIterator() { return PIMapIterator<Key, T>(*this); }
|
||||
|
||||
//! \relatesalso PIMapIteratorConstReverse
|
||||
inline PIMapIteratorConstReverse<Key, T> makeReverseIterator() const {return PIMapIteratorConstReverse<Key, T>(*this);}
|
||||
inline PIMapIteratorConstReverse<Key, T> makeReverseIterator() const { return PIMapIteratorConstReverse<Key, T>(*this); }
|
||||
|
||||
//! \relatesalso PIMapIteratorReverse
|
||||
inline PIMapIteratorReverse<Key, T> makeReverseIterator() {return PIMapIteratorReverse<Key, T>(*this);}
|
||||
inline PIMapIteratorReverse<Key, T> makeReverseIterator() { return PIMapIteratorReverse<Key, T>(*this); }
|
||||
|
||||
//! \~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 pim_content.size();}
|
||||
inline size_t size() const { return pim_content.size(); }
|
||||
|
||||
//! \~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 int size_s() const {return pim_content.size_s();}
|
||||
inline int size_s() const { return pim_content.size_s(); }
|
||||
|
||||
//! \~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 pim_content.size();}
|
||||
inline size_t length() const { return pim_content.size(); }
|
||||
|
||||
//! \~english Checks if the container has no elements.
|
||||
//! \~russian Проверяет пуст ли массив.
|
||||
@@ -269,7 +286,7 @@ public:
|
||||
//! \~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 (pim_content.size() == 0);}
|
||||
inline bool isEmpty() const { return (pim_content.size() == 0); }
|
||||
|
||||
//! \~english Checks if the container has elements.
|
||||
//! \~russian Проверяет не пуст ли массив.
|
||||
@@ -277,7 +294,7 @@ public:
|
||||
//! \~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 (pim_content.size() > 0);}
|
||||
inline bool isNotEmpty() const { return (pim_content.size() > 0); }
|
||||
|
||||
|
||||
//! \~english Full access to element key `key`.
|
||||
@@ -299,7 +316,7 @@ public:
|
||||
//! piCout << m; // {огурец: 350, лук: 25}
|
||||
//! \endcode
|
||||
//! \~\sa \a insert(), \a value(), \a key()
|
||||
inline T & operator [](const Key & key) {
|
||||
inline T & operator[](const Key & key) {
|
||||
bool f(false);
|
||||
ssize_t i = _find(key, f);
|
||||
if (f) return pim_content[pim_index[i].index];
|
||||
@@ -311,7 +328,7 @@ public:
|
||||
//! \~english Same as \a value().
|
||||
//! \~russian Синоним \a value().
|
||||
//! \~\sa \a operator[](), \a value(), \a key()
|
||||
inline T at(const Key & key) const {return value(key);}
|
||||
inline T at(const Key & key) const { return value(key); }
|
||||
|
||||
//! \~english Remove element with key `key` from the array and return it.
|
||||
//! \~russian Удаляет элемент с ключом `key` из массива и возвращает его.
|
||||
@@ -323,10 +340,10 @@ public:
|
||||
_remove(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Inserts all elements in array `other` to this array with overwrite.
|
||||
//! \~russian Вставляет все элементы `other` этот массив с перезаписью.
|
||||
inline PIMap<Key, T> & operator <<(const PIMap<Key, T> & other) {
|
||||
inline PIMap<Key, T> & operator<<(const PIMap<Key, T> & other) {
|
||||
#ifndef NDEBUG
|
||||
if (&other == this) {
|
||||
printf("error with PIMap<%s, %s>::<<\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
|
||||
@@ -351,28 +368,23 @@ public:
|
||||
|
||||
//! \~english Compare operator with array `m`.
|
||||
//! \~russian Оператор сравнения с массивом `m`.
|
||||
inline bool operator ==(const PIMap<Key, T> & m) const {
|
||||
return (pim_content == m.pim_content && pim_index == m.pim_index);
|
||||
}
|
||||
inline bool operator==(const PIMap<Key, T> & m) const { return (pim_content == m.pim_content && pim_index == m.pim_index); }
|
||||
|
||||
//! \~english Compare operator with array `m`.
|
||||
//! \~russian Оператор сравнения с массивом `m`.
|
||||
inline bool operator !=(const PIMap<Key, T> & m) const {
|
||||
return (pim_content != m.pim_content || pim_index != m.pim_index);
|
||||
}
|
||||
inline bool operator!=(const PIMap<Key, T> & m) const { return (pim_content != m.pim_content || pim_index != m.pim_index); }
|
||||
|
||||
//! \~english Tests if element with key `key` exists in the array.
|
||||
//! \~russian Проверяет наличие элемента с ключом `key` в массиве.
|
||||
inline bool contains(const Key & key) const {
|
||||
bool f(false); _find(key, f);
|
||||
bool f(false);
|
||||
_find(key, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
//! \~english Tests if element with value `value` exists in the array.
|
||||
//! \~russian Проверяет наличие элемента со значением `value` в массиве.
|
||||
inline bool containsValue(const T & value) const {
|
||||
return pim_content.contains(value);
|
||||
}
|
||||
inline bool containsValue(const T & value) const { return pim_content.contains(value); }
|
||||
|
||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
||||
@@ -407,9 +419,7 @@ public:
|
||||
|
||||
//! \~english Same as \a remove().
|
||||
//! \~russian Синоним функции \a remove().
|
||||
inline PIMap<Key, T> & erase(const Key & key) {
|
||||
return remove(key);
|
||||
}
|
||||
inline PIMap<Key, T> & erase(const Key & key) { return remove(key); }
|
||||
|
||||
|
||||
//! \~english Clear array, remove all elements.
|
||||
@@ -424,7 +434,7 @@ public:
|
||||
pim_index.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Swaps array `v` other with this array.
|
||||
//! \~russian Меняет местами массив `v` с этим массивом.
|
||||
//! \~\details
|
||||
@@ -507,7 +517,7 @@ public:
|
||||
|
||||
//! \~english Returns an array of values of all elements
|
||||
//! \~russian Возвращает массив значений всех эелметнов
|
||||
inline PIVector<T> values() const {return pim_content;}
|
||||
inline PIVector<T> values() const { return pim_content; }
|
||||
|
||||
//! \~english Returns the key of the first element
|
||||
//! whose value matches `value` or `default_` if there is no such element.
|
||||
@@ -545,9 +555,10 @@ public:
|
||||
//! of calling a provided function `PIPair<Key2, T2> f(const Key & key, const T & value)` on every element in the calling array.
|
||||
//! \~russian Создаёт новый словарь PIMap<Key2, T2> с результатом вызова указанной функции
|
||||
//! `PIPair<Key2, T2> f(const Key & key, const T & value)` для каждого элемента массива.
|
||||
template <typename Key2, typename T2>
|
||||
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());
|
||||
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]));
|
||||
}
|
||||
@@ -558,15 +569,16 @@ public:
|
||||
//! of calling a provided function `ST f(const Key & key, const T & value)` on every element in the calling array.
|
||||
//! \~russian Создаёт новый массив PIVector<ST> с результатом вызова указанной функции
|
||||
//! `ST f(const Key & key, const T & value)` для каждого элемента массива.
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIVector<ST> map(std::function<ST(const Key & key, const T & value)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(size());
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//! \~english Returns a new array with all elements
|
||||
//! that pass the test implemented by the provided function `bool test(const Key & key, const T & value)`.
|
||||
//! \~russian Возвращает новый массив со всеми элементами,
|
||||
@@ -587,24 +599,29 @@ private:
|
||||
MapIndex(Key && k, size_t i = 0): key(std::move(k)), index(i) {}
|
||||
Key key;
|
||||
size_t index;
|
||||
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;}
|
||||
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>
|
||||
friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
||||
template <typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
||||
template<typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
||||
template<typename P, typename Key1, typename T1>
|
||||
friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIDeque<typename PIMap<Key1, T1>::MapIndex> & v);
|
||||
|
||||
inline ssize_t _binarySearch(ssize_t first, ssize_t last, const Key & key, bool & found) const {
|
||||
ssize_t mid;
|
||||
while (first <= last) {
|
||||
mid = (first + last) / 2;
|
||||
if (key > pim_index[mid].key) first = mid + 1;
|
||||
else if (key < pim_index[mid].key) last = mid - 1;
|
||||
else {found = true; return mid;}
|
||||
if (key > pim_index[mid].key)
|
||||
first = mid + 1;
|
||||
else if (key < pim_index[mid].key)
|
||||
last = mid - 1;
|
||||
else {
|
||||
found = true;
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
found = false;
|
||||
return first;
|
||||
@@ -636,14 +653,14 @@ private:
|
||||
return value_type(pim_index[index].key, pim_content[pim_index[index].index]);
|
||||
}
|
||||
|
||||
inline Key & _key(ssize_t index) {return pim_index[index].key;}
|
||||
inline Key & _key(ssize_t index) { return pim_index[index].key; }
|
||||
|
||||
inline const Key & _key(ssize_t index) const {return pim_index[index].key;}
|
||||
inline const Key & _key(ssize_t index) const { return pim_index[index].key; }
|
||||
|
||||
inline T & _value(ssize_t index) {return pim_content[pim_index[index].index];}
|
||||
inline T & _value(ssize_t index) { return pim_content[pim_index[index].index]; }
|
||||
|
||||
inline const T & _value(ssize_t index) const { return pim_content[pim_index[index].index]; }
|
||||
|
||||
inline const T & _value(ssize_t index) const {return pim_content[pim_index[index].index];}
|
||||
|
||||
|
||||
PIVector<T> pim_content;
|
||||
PIDeque<MapIndex> pim_index;
|
||||
@@ -678,33 +695,28 @@ private:
|
||||
//! // 2 two
|
||||
//! // 4 four
|
||||
//! \endcode
|
||||
template <typename Key, typename T>
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConst {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIteratorConst(const PIMap<Key, T> & map): m(map), pos(-1) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline const T & value() const {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline const T & value() const { return m._value(pos); }
|
||||
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos < (m.size_s() - 1);
|
||||
}
|
||||
inline bool hasNext() const { return pos < (m.size_s() - 1); }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -717,9 +729,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = -1;
|
||||
}
|
||||
inline void reset() { pos = -1; }
|
||||
|
||||
private:
|
||||
const MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -754,32 +765,27 @@ private:
|
||||
//! // 2 two
|
||||
//! // 1 one
|
||||
//! \endcode
|
||||
template <typename Key, typename T>
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorConstReverse {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIteratorConstReverse(const PIMap<Key, T> & map): m(map), pos(m.size_s()) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline const T & value() const {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline const T & value() const { return m._value(pos); }
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos > 0;
|
||||
}
|
||||
inline bool hasNext() const { return pos > 0; }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -792,9 +798,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = m.size_s();
|
||||
}
|
||||
inline void reset() { pos = m.size_s(); }
|
||||
|
||||
private:
|
||||
const MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -830,32 +835,27 @@ private:
|
||||
//! // 2 two_!
|
||||
//! // 4 four_!
|
||||
//! \endcode
|
||||
template <typename Key, typename T>
|
||||
template<typename Key, typename T>
|
||||
class PIMapIterator {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIterator(PIMap<Key, T> & map): m(map), pos(-1) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline T & value() {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline T & value() { return m._value(pos); }
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos < (m.size_s() - 1);
|
||||
}
|
||||
inline bool hasNext() const { return pos < (m.size_s() - 1); }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -868,9 +868,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = -1;
|
||||
}
|
||||
inline void reset() { pos = -1; }
|
||||
|
||||
private:
|
||||
MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -906,32 +905,27 @@ private:
|
||||
//! // 2 two_!
|
||||
//! // 1 one_!
|
||||
//! \endcode
|
||||
template <typename Key, typename T>
|
||||
template<typename Key, typename T>
|
||||
class PIMapIteratorReverse {
|
||||
typedef PIMap<Key, T> MapType;
|
||||
|
||||
public:
|
||||
inline PIMapIteratorReverse(PIMap<Key, T> & map): m(map), pos(m.size_s()) {}
|
||||
|
||||
//! \~english Returns current key.
|
||||
//! \~russian Возвращает ключ текущего элемента.
|
||||
//! \~\sa \a value()
|
||||
inline const Key & key() const {
|
||||
return m._key(pos);
|
||||
}
|
||||
inline const Key & key() const { return m._key(pos); }
|
||||
|
||||
//! \~english Returns current value.
|
||||
//! \~russian Возвращает значение текущего элемента.
|
||||
//! \~\sa \a key()
|
||||
inline T & value() {
|
||||
return m._value(pos);
|
||||
}
|
||||
inline T & value() { return m._value(pos); }
|
||||
|
||||
//! \~english Returns true if iterator can jump to next entry
|
||||
//! \~russian Возвращает true если итератор может перейти к следующему элементу.
|
||||
//! \~\sa \a next()
|
||||
inline bool hasNext() const {
|
||||
return pos > 0;
|
||||
}
|
||||
inline bool hasNext() const { return pos > 0; }
|
||||
|
||||
//! \~english Jump to next entry and return true if new position is valid.
|
||||
//! \~russian Переходит к следующему элементу и возвращает true если он существует.
|
||||
@@ -944,9 +938,8 @@ public:
|
||||
//! \~english Reset iterator to initial position.
|
||||
//! \~russian Переходит на начало.
|
||||
//! \~\sa \a next()
|
||||
inline void reset() {
|
||||
pos = m.size_s();
|
||||
}
|
||||
inline void reset() { pos = m.size_s(); }
|
||||
|
||||
private:
|
||||
MapType & m;
|
||||
ssize_t pos;
|
||||
@@ -957,12 +950,11 @@ private:
|
||||
//! \~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>
|
||||
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 << "{";
|
||||
bool first = true;
|
||||
for (typename PIMap<Key, Type>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (!first)
|
||||
s << ", ";
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
s << i.key() << ": " << i.value();
|
||||
}
|
||||
@@ -976,14 +968,13 @@ inline std::ostream & operator <<(std::ostream & s, const PIMap<Key, Type> & v)
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
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.saveAndSetControls(0);
|
||||
s << "{";
|
||||
bool first = true;
|
||||
for (typename PIMap<Key, Type>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (!first)
|
||||
s << ", ";
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
s << i.key() << ": " << i.value();
|
||||
}
|
||||
@@ -993,7 +984,9 @@ inline PICout operator <<(PICout s, const PIMap<Key, Type> & v) {
|
||||
}
|
||||
|
||||
template<typename Key, typename Type>
|
||||
inline void piSwap(PIMap<Key, Type> & f, PIMap<Key, Type> & s) {f.swap(s);}
|
||||
inline void piSwap(PIMap<Key, Type> & f, PIMap<Key, Type> & s) {
|
||||
f.swap(s);
|
||||
}
|
||||
|
||||
|
||||
#endif // PIMAP_H
|
||||
|
||||
@@ -13,22 +13,22 @@
|
||||
//! Андрей Бычков work.a.b@yandex.ru;
|
||||
//! \~\}
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
pair
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
pair
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIPAIR_H
|
||||
@@ -48,29 +48,28 @@
|
||||
template<typename Type0, typename Type1>
|
||||
class PIPair {
|
||||
public:
|
||||
|
||||
//! \~english Constructs an empty PIPair.
|
||||
//! \~russian Создает пустой PIPair.
|
||||
PIPair() : first(), second() {}
|
||||
PIPair(): first(), second() {}
|
||||
|
||||
//! \~english Constructs PIPair from [std::tuple](https://en.cppreference.com/w/cpp/utility/tuple).
|
||||
//! \~russian Создает PIPair из [std::tuple](https://ru.cppreference.com/w/cpp/utility/tuple).
|
||||
PIPair(std::tuple<Type0, Type1> tuple) {
|
||||
first = std::get<0>(tuple);
|
||||
first = std::get<0>(tuple);
|
||||
second = std::get<1>(tuple);
|
||||
}
|
||||
|
||||
//! \~english Constructs PIPair from values `value0` and `value1`.
|
||||
//! \~russian Создает PIPair из `value0` и `value1`.
|
||||
PIPair(const Type0 & value0, const Type1 & value1) {
|
||||
first = value0;
|
||||
first = value0;
|
||||
second = value1;
|
||||
}
|
||||
|
||||
//! \~english Move constructor.
|
||||
//! \~russian Перемещающий конструктор.
|
||||
PIPair(Type0 && value0, Type1 && value1) {
|
||||
first = std::move(value0);
|
||||
first = std::move(value0);
|
||||
second = std::move(value1);
|
||||
}
|
||||
|
||||
@@ -86,20 +85,20 @@ public:
|
||||
//! \~english Compare operator with PIPair.
|
||||
//! \~russian Оператор сравнения с PIPair.
|
||||
template<typename Type0, typename Type1>
|
||||
inline bool operator ==(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {
|
||||
inline bool operator==(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {
|
||||
return (value0.first == value1.first) && (value0.second == value1.second);
|
||||
}
|
||||
|
||||
//! \~english Compare operator with PIPair.
|
||||
//! \~russian Оператор сравнения с PIPair.
|
||||
template<typename Type0, typename Type1>
|
||||
inline bool operator !=(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {
|
||||
inline bool operator!=(const PIPair<Type0, Type1> & value0, const PIPair<Type0, Type1> & value1) {
|
||||
return (value0.first != value1.first) || (value0.second != value1.second);
|
||||
}
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
template<typename Type0, typename Type1>
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> & v) {
|
||||
inline std::ostream & operator<<(std::ostream & s, const PIPair<Type0, Type1> & v) {
|
||||
s << "(" << v.first << ", " << v.second << ")";
|
||||
return s;
|
||||
}
|
||||
@@ -109,7 +108,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIPair<Type0, Type1> &
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
template<typename Type0, typename Type1>
|
||||
inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {
|
||||
inline PICout operator<<(PICout s, const PIPair<Type0, Type1> & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "(" << v.first << ", " << v.second << ")";
|
||||
@@ -125,18 +124,18 @@ inline PICout operator <<(PICout s, const PIPair<Type0, Type1> & v) {
|
||||
//! auto p = createPIPair(1, 'a');
|
||||
//! piCout << p; // (1, a)
|
||||
//! \endcode
|
||||
template< class T1, class T2 >
|
||||
PIPair<T1,T2> createPIPair(const T1 & f, const T2 & s) {
|
||||
return PIPair<T1,T2>(f, s);
|
||||
template<class T1, class T2>
|
||||
PIPair<T1, T2> createPIPair(const T1 & f, const T2 & s) {
|
||||
return PIPair<T1, T2>(f, s);
|
||||
}
|
||||
|
||||
|
||||
//! \~english Creates \a PIPair object, deducing the target type from the types of arguments.
|
||||
//! \~russian Создает \a PIPair выводя типы из аргументов.
|
||||
//! \sa \a createPIPair()
|
||||
template< class T1, class T2 >
|
||||
PIPair<T1,T2> createPIPair(T1 && f, T2 && s) {
|
||||
return PIPair<T1,T2>(std::move(f), std::move(s));
|
||||
template<class T1, class T2>
|
||||
PIPair<T1, T2> createPIPair(T1 && f, T2 && s) {
|
||||
return PIPair<T1, T2>(std::move(f), std::move(s));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,22 +13,22 @@
|
||||
//! Андрей Бычков work.a.b@yandex.ru;
|
||||
//! \~\}
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Queue container
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Queue container
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQUEUE_H
|
||||
@@ -53,18 +53,23 @@
|
||||
template<typename T>
|
||||
class PIQueue: public PIDeque<T> {
|
||||
public:
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
PIQueue() {}
|
||||
|
||||
//! \~english Puts an element on the queue.
|
||||
//! \~russian Кладёт элемент в очередь.
|
||||
PIDeque<T> & enqueue(const T & v) {PIDeque<T>::push_front(v); return *this;}
|
||||
PIDeque<T> & enqueue(const T & v) {
|
||||
PIDeque<T>::push_front(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Move an element on the queue.
|
||||
//! \~russian Перемещает элемент в очередь.
|
||||
PIDeque<T> & enqueue(T && v) {PIDeque<T>::push_front(std::move(v)); return *this;}
|
||||
PIDeque<T> & enqueue(T && v) {
|
||||
PIDeque<T>::push_front(std::move(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Retrieves and returns an element from the queue.
|
||||
//! \~russian Забирает и возвращает элемент из очереди.
|
||||
@@ -74,7 +79,7 @@ public:
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
T dequeue() {return PIDeque<T>::take_back();}
|
||||
T dequeue() { return PIDeque<T>::take_back(); }
|
||||
|
||||
//! \~english Head element of the queue.
|
||||
//! \~russian Головной (верхний) элемент очереди.
|
||||
@@ -86,8 +91,8 @@ public:
|
||||
//! \~russian Возвращает ссылку на головной (верхний) элемент очереди.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
T & head() {return PIDeque<T>::back();}
|
||||
const T & head() const {return PIDeque<T>::back();}
|
||||
T & head() { return PIDeque<T>::back(); }
|
||||
const T & head() const { return PIDeque<T>::back(); }
|
||||
|
||||
//! \~english Tail element of the queue.
|
||||
//! \~russian Хвостовой (нижний) элемент очереди.
|
||||
@@ -98,16 +103,16 @@ public:
|
||||
//! \~russian Возвращает ссылку на хвостовой (нижний) элемент очереди.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
T & tail() {return PIDeque<T>::front();}
|
||||
const T & tail() const {return PIDeque<T>::front();}
|
||||
T & tail() { return PIDeque<T>::front(); }
|
||||
const T & tail() const { return PIDeque<T>::front(); }
|
||||
|
||||
//! \~english Converts \a PIQueue to \a PIVector.
|
||||
//! \~russian Преобразует \a PIQueue в \a PIVector.
|
||||
PIVector<T> toVector() const {return PIVector<T>(PIDeque<T>::data(), PIDeque<T>::size());}
|
||||
PIVector<T> toVector() const { return PIVector<T>(PIDeque<T>::data(), PIDeque<T>::size()); }
|
||||
|
||||
//! \~english Converts \a PIQueue to \a PIDeque.
|
||||
//! \~russian Преобразует \a PIQueue в \a PIDeque.
|
||||
PIDeque<T> toDeque() const {return PIDeque<T>(*this);}
|
||||
PIDeque<T> toDeque() const { return PIDeque<T>(*this); }
|
||||
};
|
||||
|
||||
#endif // PIQUEUE_H
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/*! \file piset.h
|
||||
* \brief Set container
|
||||
*
|
||||
*
|
||||
* This file declare PISet
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Set container
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Set container
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PISET_H
|
||||
@@ -34,25 +34,37 @@
|
||||
* set with \a operator[] or with function \a find(). These function
|
||||
* has logarithmic complexity.
|
||||
*/
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class PISet: public PIMap<T, uchar> {
|
||||
typedef PIMap<T, uchar> _CSet;
|
||||
|
||||
public:
|
||||
|
||||
//! Contructs an empty set
|
||||
PISet() {}
|
||||
|
||||
//! Contructs set with one element "value"
|
||||
PISet(const T & value) {_CSet::insert(value, 0);}
|
||||
|
||||
PISet(const T & value) { _CSet::insert(value, 0); }
|
||||
|
||||
//! Contructs set with elements "v0" and "v1"
|
||||
PISet(const T & v0, const T & v1) {_CSet::insert(v0, 0); _CSet::insert(v1, 0);}
|
||||
|
||||
PISet(const T & v0, const T & v1) {
|
||||
_CSet::insert(v0, 0);
|
||||
_CSet::insert(v1, 0);
|
||||
}
|
||||
|
||||
//! Contructs set with elements "v0", "v1" and "v2"
|
||||
PISet(const T & v0, const T & v1, const T & v2) {_CSet::insert(v0, 0); _CSet::insert(v1, 0); _CSet::insert(v2, 0);}
|
||||
|
||||
PISet(const T & v0, const T & v1, const T & v2) {
|
||||
_CSet::insert(v0, 0);
|
||||
_CSet::insert(v1, 0);
|
||||
_CSet::insert(v2, 0);
|
||||
}
|
||||
|
||||
//! Contructs set with elements "v0", "v1", "v2" and "v3"
|
||||
PISet(const T & v0, const T & v1, const T & v2, const T & v3) {_CSet::insert(v0, 0); _CSet::insert(v1, 0); _CSet::insert(v2, 0); _CSet::insert(v3, 0);}
|
||||
PISet(const T & v0, const T & v1, const T & v2, const T & v3) {
|
||||
_CSet::insert(v0, 0);
|
||||
_CSet::insert(v1, 0);
|
||||
_CSet::insert(v2, 0);
|
||||
_CSet::insert(v3, 0);
|
||||
}
|
||||
|
||||
//! Contructs set from vector of elements
|
||||
PISet(const PIVector<T> & values) {
|
||||
@@ -71,16 +83,28 @@ public:
|
||||
}
|
||||
|
||||
typedef T key_type;
|
||||
|
||||
PISet<T> & operator <<(const T & t) {_CSet::insert(t, 0); return *this;}
|
||||
PISet<T> & operator <<(T && t) {_CSet::insert(std::move(t), 0); return *this;}
|
||||
PISet<T> & operator <<(const PISet<T> & other) {(*(_CSet*)this) << *((_CSet*)&other); return *this;}
|
||||
|
||||
|
||||
PISet<T> & operator<<(const T & t) {
|
||||
_CSet::insert(t, 0);
|
||||
return *this;
|
||||
}
|
||||
PISet<T> & operator<<(T && t) {
|
||||
_CSet::insert(std::move(t), 0);
|
||||
return *this;
|
||||
}
|
||||
PISet<T> & operator<<(const PISet<T> & other) {
|
||||
(*(_CSet *)this) << *((_CSet *)&other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Returns if element "t" exists in this set
|
||||
bool operator [](const T & t) const {return _CSet::contains(t);}
|
||||
|
||||
bool operator[](const T & t) const { return _CSet::contains(t); }
|
||||
|
||||
//! Returns if element "t" exists in this set
|
||||
PISet<T> & remove(const T & t) {_CSet::remove(t); return *this;}
|
||||
PISet<T> & remove(const T & t) {
|
||||
_CSet::remove(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Unite set with "v"
|
||||
PISet<T> & unite(const PISet<T> & v) {
|
||||
@@ -107,48 +131,76 @@ public:
|
||||
}
|
||||
|
||||
//! Unite set with "v"
|
||||
PISet<T> & operator +=(const PISet<T> & v) {return unite(v);}
|
||||
PISet<T> & operator+=(const PISet<T> & v) { return unite(v); }
|
||||
|
||||
//! Unite set with "v"
|
||||
PISet<T> & operator |=(const PISet<T> & v) {return unite(v);}
|
||||
PISet<T> & operator|=(const PISet<T> & v) { return unite(v); }
|
||||
|
||||
//! Subtract set with "v"
|
||||
PISet<T> & operator -=(const PISet<T> & v) {return subtract(v);}
|
||||
PISet<T> & operator-=(const PISet<T> & v) { return subtract(v); }
|
||||
|
||||
//! Intersect set with "v"
|
||||
PISet<T> & operator &=(const PISet<T> & v) {return intersect(v);}
|
||||
PISet<T> & operator&=(const PISet<T> & v) { return intersect(v); }
|
||||
|
||||
//! Returns content of set as PIVector
|
||||
PIVector<T> toVector() const {PIVector<T> ret; for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i) ret << i.key(); return ret;}
|
||||
PIVector<T> toVector() const {
|
||||
PIVector<T> ret;
|
||||
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
|
||||
ret << i.key();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! Returns content of set as PIDeque
|
||||
PIDeque<T> toDeque() const {PIDeque<T> ret; for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i) ret << i.key(); return ret;}
|
||||
|
||||
PIDeque<T> toDeque() const {
|
||||
PIDeque<T> ret;
|
||||
for (typename _CSet::const_iterator i = _CSet::begin(); i != _CSet::end(); ++i)
|
||||
ret << i.key();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! \relatesalso PISet \brief Returns unite of two sets
|
||||
template <typename T> PISet<T> operator +(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.unite(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator+(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.unite(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \relatesalso PISet \brief Returns subtraction of two sets
|
||||
template <typename T> PISet<T> operator -(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.subtract(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator-(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.subtract(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \relatesalso PISet \brief Returns unite of two sets
|
||||
template <typename T> PISet<T> operator |(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.unite(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator|(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.unite(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! \relatesalso PISet \brief Returns intersetion of two sets
|
||||
template <typename T> PISet<T> operator &(const PISet<T> & v0, const PISet<T> & v1) {PISet<T> ret(v0); ret.intersect(v1); return ret;}
|
||||
template<typename T>
|
||||
PISet<T> operator&(const PISet<T> & v0, const PISet<T> & v1) {
|
||||
PISet<T> ret(v0);
|
||||
ret.intersect(v1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
template<typename Type>
|
||||
inline PICout operator <<(PICout s, const PISet<Type> & v) {
|
||||
inline PICout operator<<(PICout s, const PISet<Type> & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "{";
|
||||
bool first = true;
|
||||
for (typename PIMap<Type, uchar>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (!first)
|
||||
s << ", ";
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
s << i.key();
|
||||
}
|
||||
|
||||
@@ -13,29 +13,29 @@
|
||||
//! Андрей Бычков work.a.b@yandex.ru;
|
||||
//! \~\}
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Stack container
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Stack container
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PISTACK_H
|
||||
#define PISTACK_H
|
||||
|
||||
#include "pivector.h"
|
||||
#include "pideque.h"
|
||||
#include "pivector.h"
|
||||
|
||||
//! \addtogroup Containers
|
||||
//! \{
|
||||
@@ -53,18 +53,23 @@
|
||||
template<typename T>
|
||||
class PIStack: public PIVector<T> {
|
||||
public:
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
PIStack() {}
|
||||
|
||||
//! \~english Puts an element on the stack.
|
||||
//! \~russian Кладёт элемент в стек.
|
||||
PIVector<T> & push(const T & v) {PIVector<T>::push_back(v); return *this;}
|
||||
PIVector<T> & push(const T & v) {
|
||||
PIVector<T>::push_back(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Move an element on the stack.
|
||||
//! \~russian Перемещает элемент в стек.
|
||||
PIVector<T> & push(T && v) {PIVector<T>::push_back(std::move(v)); return *this;}
|
||||
PIVector<T> & push(T && v) {
|
||||
PIVector<T>::push_back(std::move(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \~english Retrieves and returns an element from the stack.
|
||||
//! \~russian Забирает и возвращает элемент из стека.
|
||||
@@ -74,7 +79,7 @@ public:
|
||||
//! Otherwise will be undefined behavior.
|
||||
//! \~russian Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
T pop() {return PIVector<T>::take_back();}
|
||||
T pop() { return PIVector<T>::take_back(); }
|
||||
|
||||
//! \~english Top element of the stack
|
||||
//! \~russian Верхний элемент стека.
|
||||
@@ -86,16 +91,16 @@ public:
|
||||
//! \~russian Возвращает ссылку на верхний элемент стека.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
T & top() {return PIVector<T>::back();}
|
||||
const T & top() const {return PIVector<T>::back();}
|
||||
T & top() { return PIVector<T>::back(); }
|
||||
const T & top() const { return PIVector<T>::back(); }
|
||||
|
||||
//! \~english Converts \a PIStack to \a PIVector.
|
||||
//! \~russian Преобразует \a PIStack в \a PIVector.
|
||||
PIVector<T> toVector() const {return PIVector<T>(*this);}
|
||||
PIVector<T> toVector() const { return PIVector<T>(*this); }
|
||||
|
||||
//! \~english Converts \a PIStack to \a PIDeque.
|
||||
//! \~russian Преобразует \a PIStack в \a PIDeque.
|
||||
PIDeque<T> toDeque() const {return PIDeque<T>(PIVector<T>::data(), PIVector<T>::size());}
|
||||
PIDeque<T> toDeque() const { return PIDeque<T>(PIVector<T>::data(), PIVector<T>::size()); }
|
||||
};
|
||||
|
||||
#endif // PISTACK_H
|
||||
|
||||
@@ -13,22 +13,22 @@
|
||||
//! Андрей Бычков work.a.b@yandex.ru;
|
||||
//! \~\}
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Sequence linear container aka dynamic size array of any type
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Sequence linear container aka dynamic size array of any type
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIVECTOR_H
|
||||
@@ -114,22 +114,20 @@
|
||||
//! - Вставка и удаление элементов — линейная по расстоянию до конца массива 𝓞(n)
|
||||
//!
|
||||
//! \~\sa \a PIDeque, \a PIMap
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class PIVector {
|
||||
public:
|
||||
typedef bool (*CompareFunc)(const T & , const T & );
|
||||
typedef bool (*CompareFunc)(const T &, const T &);
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T * pointer;
|
||||
typedef const T * const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef size_t size_type;
|
||||
|
||||
//! \~english Constructs an empty array.
|
||||
//! \~russian Создает пустой массив.
|
||||
inline PIVector() {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
}
|
||||
inline PIVector() { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) }
|
||||
|
||||
//! \~english Contructs array from raw `data`.
|
||||
//! This constructor reserve `size` and copy from `data` pointer.
|
||||
@@ -193,8 +191,8 @@ public:
|
||||
//! \~russian Перемещающий конструктор.
|
||||
inline PIVector(PIVector<T> && v) {
|
||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||
piv_data = v.piv_data;
|
||||
piv_size = v.piv_size;
|
||||
piv_data = v.piv_data;
|
||||
piv_size = v.piv_size;
|
||||
piv_rsize = v.piv_rsize;
|
||||
v._reset();
|
||||
}
|
||||
@@ -208,7 +206,7 @@ public:
|
||||
|
||||
//! \~english Assign operator.
|
||||
//! \~russian Оператор присваивания.
|
||||
inline PIVector<T> & operator =(const PIVector<T> & v) {
|
||||
inline PIVector<T> & operator=(const PIVector<T> & v) {
|
||||
if (this == &v) return *this;
|
||||
clear();
|
||||
alloc(v.piv_size);
|
||||
@@ -218,360 +216,330 @@ public:
|
||||
|
||||
//! \~english Assign move operator.
|
||||
//! \~russian Оператор перемещающего присваивания.
|
||||
inline PIVector<T> & operator =(PIVector<T> && v) {
|
||||
inline PIVector<T> & operator=(PIVector<T> && v) {
|
||||
swap(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
class iterator {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline iterator(PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
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 ++() {
|
||||
inline iterator & operator++() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator operator ++(int) {
|
||||
inline iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
inline iterator & operator --() {
|
||||
inline iterator & operator--() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator operator --(int) {
|
||||
inline iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline iterator & operator +=(const iterator & it) {
|
||||
inline iterator & operator+=(const iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator & operator +=(size_t p) {
|
||||
inline iterator & operator+=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
inline iterator & operator -=(const iterator & it) {
|
||||
inline iterator & operator-=(const iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline iterator & operator -=(size_t p) {
|
||||
inline iterator & operator-=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline iterator operator -(size_t p, const iterator & it) {return it - p;}
|
||||
friend inline iterator operator -(const iterator & it, size_t p) {
|
||||
friend inline iterator operator-(size_t p, const iterator & it) { return it - p; }
|
||||
friend inline iterator operator-(const iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const iterator & it1, const iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const iterator & it1, const iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline iterator operator +(size_t p, const iterator & it) {return it + p;}
|
||||
friend inline iterator operator +(const iterator & it, size_t p) {
|
||||
friend inline iterator operator+(size_t p, const iterator & it) { return it + p; }
|
||||
friend inline iterator operator+(const iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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 {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline const_iterator(const PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
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 ++() {
|
||||
inline const_iterator & operator++() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator operator ++(int) {
|
||||
inline const_iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
inline const_iterator & operator --() {
|
||||
inline const_iterator & operator--() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator operator --(int) {
|
||||
inline const_iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline const_iterator & operator +=(const const_iterator & it) {
|
||||
inline const_iterator & operator+=(const const_iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator +=(size_t p) {
|
||||
inline const_iterator & operator+=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator -=(const const_iterator & it) {
|
||||
inline const_iterator & operator-=(const const_iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_iterator & operator -=(size_t p) {
|
||||
inline const_iterator & operator-=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline const_iterator operator -(size_t p, const const_iterator & it) {return it - p;}
|
||||
friend inline const_iterator operator -(const const_iterator & it, size_t p) {
|
||||
friend inline const_iterator operator-(size_t p, const const_iterator & it) { return it - p; }
|
||||
friend inline const_iterator operator-(const const_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const const_iterator & it1, const const_iterator & it2) {
|
||||
return it1.pos - it2.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const const_iterator & it1, const const_iterator & it2) { return it1.pos - it2.pos; }
|
||||
|
||||
friend inline const_iterator operator +(size_t p, const const_iterator & it) {return it + p;}
|
||||
friend inline const_iterator operator +(const const_iterator & it, size_t p) {
|
||||
friend inline const_iterator operator+(size_t p, const const_iterator & it) { return it + p; }
|
||||
friend inline const_iterator operator+(const const_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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 {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline reverse_iterator(PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
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 ++() {
|
||||
inline reverse_iterator & operator++() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator operator ++(int) {
|
||||
inline reverse_iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
inline reverse_iterator & operator --() {
|
||||
inline reverse_iterator & operator--() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator operator --(int) {
|
||||
inline reverse_iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline reverse_iterator & operator +=(const reverse_iterator & it) {
|
||||
inline reverse_iterator & operator+=(const reverse_iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator & operator +=(size_t p) {
|
||||
inline reverse_iterator & operator+=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator & operator -=(const reverse_iterator & it) {
|
||||
inline reverse_iterator & operator-=(const reverse_iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline reverse_iterator & operator -=(size_t p) {
|
||||
inline reverse_iterator & operator-=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline reverse_iterator operator -(size_t p, const reverse_iterator & it) {return it - p;}
|
||||
friend inline reverse_iterator operator -(const reverse_iterator & it, size_t p) {
|
||||
friend inline reverse_iterator operator-(size_t p, const reverse_iterator & it) { return it - p; }
|
||||
friend inline reverse_iterator operator-(const reverse_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const reverse_iterator & it1, const reverse_iterator & it2) {
|
||||
return it2.pos - it1.pos;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator-(const reverse_iterator & it1, const reverse_iterator & it2) { return it2.pos - it1.pos; }
|
||||
|
||||
friend inline reverse_iterator operator +(size_t p, const reverse_iterator & it) {return it + p;}
|
||||
friend inline reverse_iterator operator +(const reverse_iterator & it, size_t p) {
|
||||
friend inline reverse_iterator operator+(size_t p, const reverse_iterator & it) { return it + p; }
|
||||
friend inline reverse_iterator operator+(const reverse_iterator & it, size_t p) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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 {
|
||||
friend class PIVector<T>;
|
||||
|
||||
private:
|
||||
inline const_reverse_iterator(const PIVector<T> * v, ssize_t p): parent(v), pos(p) {}
|
||||
const PIVector<T> * parent;
|
||||
ssize_t pos;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T * pointer;
|
||||
typedef T & reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
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 ++() {
|
||||
inline const_reverse_iterator & operator++() {
|
||||
--pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator operator ++(int) {
|
||||
inline const_reverse_iterator operator++(int) {
|
||||
auto tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
inline const_reverse_iterator & operator --() {
|
||||
inline const_reverse_iterator & operator--() {
|
||||
++pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator operator --(int) {
|
||||
inline const_reverse_iterator operator--(int) {
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline const_reverse_iterator & operator +=(const const_reverse_iterator & it) {
|
||||
inline const_reverse_iterator & operator+=(const const_reverse_iterator & it) {
|
||||
pos -= it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator & operator +=(size_t p) {
|
||||
inline const_reverse_iterator & operator+=(size_t p) {
|
||||
pos -= p;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator & operator -=(const const_reverse_iterator & it) {
|
||||
inline const_reverse_iterator & operator-=(const const_reverse_iterator & it) {
|
||||
pos += it.pos;
|
||||
return *this;
|
||||
}
|
||||
inline const_reverse_iterator & operator -=(size_t p) {
|
||||
inline const_reverse_iterator & operator-=(size_t p) {
|
||||
pos += p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline const_reverse_iterator 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) {
|
||||
friend inline const_reverse_iterator 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) {
|
||||
auto tmp = it;
|
||||
tmp -= p;
|
||||
return tmp;
|
||||
}
|
||||
friend inline std::ptrdiff_t operator -(const const_reverse_iterator & it1, const const_reverse_iterator & it2) {
|
||||
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 +(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) {
|
||||
friend inline const_reverse_iterator 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) {
|
||||
auto tmp = it;
|
||||
tmp += p;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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; }
|
||||
};
|
||||
|
||||
//! \~english Iterator to the first element.
|
||||
@@ -582,7 +550,7 @@ public:
|
||||
//! \~russian Если массив пустой, возвращаемый итератор будет равен \a end().
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a end(), \a rbegin(), \a rend()
|
||||
inline iterator begin() {return iterator(this, 0);}
|
||||
inline iterator begin() { return iterator(this, 0); }
|
||||
|
||||
//! \~english Iterator to the element following the last element.
|
||||
//! \~russian Итератор на элемент, следующий за последним элементом.
|
||||
@@ -594,10 +562,10 @@ public:
|
||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a begin(), \a rbegin(), \a rend()
|
||||
inline iterator end() {return iterator(this, piv_size);}
|
||||
inline iterator end() { return iterator(this, piv_size); }
|
||||
|
||||
inline const_iterator begin() const {return const_iterator(this, 0);}
|
||||
inline const_iterator end() const {return const_iterator(this, piv_size);}
|
||||
inline const_iterator begin() const { return const_iterator(this, 0); }
|
||||
inline const_iterator end() const { return const_iterator(this, piv_size); }
|
||||
|
||||
//! \~english Returns a reverse iterator to the first element of the reversed array.
|
||||
//! \~russian Обратный итератор на первый элемент.
|
||||
@@ -610,7 +578,7 @@ public:
|
||||
//! Если массив пустой, то совпадает с итератором \a rend().
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rend(), \a begin(), \a end()
|
||||
inline reverse_iterator rbegin() {return reverse_iterator(this, piv_size - 1);}
|
||||
inline reverse_iterator rbegin() { return reverse_iterator(this, piv_size - 1); }
|
||||
|
||||
//! \~english Returns a reverse iterator to the element
|
||||
//! following the last element of the reversed array.
|
||||
@@ -625,25 +593,25 @@ public:
|
||||
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||
//! \~\return \ref stl_iterators
|
||||
//! \~\sa \a rbegin(), \a begin(), \a end()
|
||||
inline reverse_iterator rend() {return reverse_iterator(this, -1);}
|
||||
inline reverse_iterator rend() { return reverse_iterator(this, -1); }
|
||||
|
||||
inline const_reverse_iterator rbegin() const {return const_reverse_iterator(this, piv_size - 1);}
|
||||
inline const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
|
||||
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(this, piv_size - 1); }
|
||||
inline const_reverse_iterator rend() const { return const_reverse_iterator(this, -1); }
|
||||
|
||||
//! \~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 piv_size;}
|
||||
inline size_t size() const { return piv_size; }
|
||||
|
||||
//! \~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 piv_size;}
|
||||
inline ssize_t size_s() const { return piv_size; }
|
||||
|
||||
//! \~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 piv_size;}
|
||||
inline size_t length() const { return piv_size; }
|
||||
|
||||
//! \~english Number of elements that the container has currently allocated space for.
|
||||
//! \~russian Количество элементов, для которого сейчас выделена память массивом.
|
||||
@@ -651,7 +619,7 @@ public:
|
||||
//! \~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 piv_rsize;}
|
||||
inline size_t capacity() const { return piv_rsize; }
|
||||
|
||||
//! \~english Checks if the container has no elements.
|
||||
//! \~russian Проверяет пуст ли массив.
|
||||
@@ -659,7 +627,7 @@ public:
|
||||
//! \~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 (piv_size == 0);}
|
||||
inline bool isEmpty() const { return (piv_size == 0); }
|
||||
|
||||
//! \~english Checks if the container has elements.
|
||||
//! \~russian Проверяет не пуст ли массив.
|
||||
@@ -667,7 +635,7 @@ public:
|
||||
//! \~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 (piv_size > 0);}
|
||||
inline bool isNotEmpty() const { return (piv_size > 0); }
|
||||
|
||||
//! \~english Tests whether at least one element in the array
|
||||
//! passes the test implemented by the provided function `test`.
|
||||
@@ -735,8 +703,8 @@ public:
|
||||
//! piCout << v; // {1, 2, 5, 9}
|
||||
//! \endcode
|
||||
//! \~\sa \a at()
|
||||
inline T & operator [](size_t index) {return piv_data[index];}
|
||||
inline const T & operator [](size_t index) const {return piv_data[index];}
|
||||
inline T & operator[](size_t index) { return piv_data[index]; }
|
||||
inline const T & operator[](size_t index) const { return piv_data[index]; }
|
||||
|
||||
//! \~english Read only access to element by `index`.
|
||||
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
|
||||
@@ -747,7 +715,7 @@ public:
|
||||
//! \~russian Индекс элемента считается от `0`.
|
||||
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline const T & at(size_t index) const {return piv_data[index];}
|
||||
inline const T & at(size_t index) const { return piv_data[index]; }
|
||||
|
||||
|
||||
//! \~english Returns the first element of the array that
|
||||
@@ -758,8 +726,10 @@ public:
|
||||
//! \~\sa \a indexWhere()
|
||||
inline const T & atWhere(std::function<bool(const T & e)> test, ssize_t start = 0, const T & def = T()) const {
|
||||
ssize_t i = indexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Returns the last element of the array that
|
||||
@@ -770,8 +740,10 @@ public:
|
||||
//! \~\sa \a lastIndexWhere()
|
||||
inline const T & lastAtWhere(std::function<bool(const T & e)> test, ssize_t start = -1, const T & def = T()) const {
|
||||
ssize_t i = lastIndexWhere(test, start);
|
||||
if (i < 0) return def;
|
||||
else return at(i);
|
||||
if (i < 0)
|
||||
return def;
|
||||
else
|
||||
return at(i);
|
||||
}
|
||||
|
||||
//! \~english Last element.
|
||||
@@ -783,8 +755,8 @@ public:
|
||||
//! \~russian Возвращает ссылку на последний элемент в массиве.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline T & back() {return piv_data[piv_size - 1];}
|
||||
inline const T & back() const {return piv_data[piv_size - 1];}
|
||||
inline T & back() { return piv_data[piv_size - 1]; }
|
||||
inline const T & back() const { return piv_data[piv_size - 1]; }
|
||||
|
||||
//! \~english Last element.
|
||||
//! \~russian Первый элемент массива.
|
||||
@@ -795,12 +767,12 @@ public:
|
||||
//! \~russian Возвращает ссылку на пенрвый элемент в массиве.
|
||||
//! Эта функция предполагает, что массив не пустой.
|
||||
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
inline T & front() {return piv_data[0];}
|
||||
inline const T & front() const {return piv_data[0];}
|
||||
inline T & front() { return piv_data[0]; }
|
||||
inline const T & front() const { return piv_data[0]; }
|
||||
|
||||
//! \~english Compare operator with array `v`.
|
||||
//! \~russian Оператор сравнения с массивом `v`.
|
||||
inline bool operator ==(const PIVector<T> & v) const {
|
||||
inline bool operator==(const PIVector<T> & v) const {
|
||||
if (piv_size != v.piv_size) return false;
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
if (v[i] != piv_data[i]) return false;
|
||||
@@ -810,7 +782,7 @@ public:
|
||||
|
||||
//! \~english Compare operator with array `v`.
|
||||
//! \~russian Оператор сравнения с массивом `v`.
|
||||
inline bool operator !=(const PIVector<T> & v) const {return !(*this == v);}
|
||||
inline bool operator!=(const PIVector<T> & v) const { return !(*this == v); }
|
||||
|
||||
//! \~english Tests if element `e` exists in the array.
|
||||
//! \~russian Проверяет наличие элемента `e` в массиве.
|
||||
@@ -869,7 +841,7 @@ public:
|
||||
start = piv_size + start;
|
||||
if (start < 0) start = 0;
|
||||
}
|
||||
for (const T & e : v) {
|
||||
for (const T & e: v) {
|
||||
bool c = false;
|
||||
for (size_t i = start; i < piv_size; ++i) {
|
||||
if (e == piv_data[i]) {
|
||||
@@ -1122,7 +1094,7 @@ public:
|
||||
//! memcpy(vec.data(1), a, 2 * sizeof(int));
|
||||
//! piCout << v; // {2, 12, 13, 2}
|
||||
//! \endcode
|
||||
inline T * data(size_t index = 0) {return &(piv_data[index]);}
|
||||
inline T * data(size_t index = 0) { return &(piv_data[index]); }
|
||||
|
||||
//! \~english Read only pointer to array
|
||||
//! \~russian Указатель на память массива только для чтения.
|
||||
@@ -1141,7 +1113,7 @@ public:
|
||||
//! 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 &(piv_data[index]);}
|
||||
inline const T * data(size_t index = 0) const { return &(piv_data[index]); }
|
||||
|
||||
//! \~english Creates sub-array of this array.
|
||||
//! \~russian Создает подмассив, то есть кусок из текущего массива.
|
||||
@@ -1172,17 +1144,13 @@ public:
|
||||
//! \~english 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>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & clear() {
|
||||
deleteT(piv_data, piv_size);
|
||||
piv_size = 0;
|
||||
return *this;
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & clear() {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, piv_size)
|
||||
piv_size = 0;
|
||||
@@ -1228,21 +1196,17 @@ public:
|
||||
//! \~english Same as \a fill().
|
||||
//! \~russian Тоже самое что и \a fill().
|
||||
//! \~\sa \a fill(), \a resize()
|
||||
inline PIVector<T> & assign(const T & e = T()) {return fill(e);}
|
||||
inline PIVector<T> & assign(const T & e = T()) { return fill(e); }
|
||||
|
||||
//! \~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>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & assign(size_t new_size, const T & f) {
|
||||
resize(new_size);
|
||||
return fill(f);
|
||||
}
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & assign(size_t new_size, const T & f) {
|
||||
_resizeRaw(new_size);
|
||||
return fill(f);
|
||||
@@ -1290,25 +1254,21 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector<T> & _resizeRaw(size_t new_size) {
|
||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||
if (new_size > piv_size) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-piv_size));
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size - piv_size));
|
||||
}
|
||||
if (new_size < piv_size) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size-new_size));
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, (piv_size - new_size));
|
||||
}
|
||||
#endif
|
||||
alloc(new_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) {
|
||||
newT(dst, src, size);
|
||||
}
|
||||
inline void _copyRaw(T * dst, const T * src, size_t size) { newT(dst, src, size); }
|
||||
|
||||
//! \~english Attempts to allocate memory for at least `new_size` elements.
|
||||
//! \~russian Резервируется память под как минимум `new_size` элементов.
|
||||
@@ -1347,7 +1307,7 @@ public:
|
||||
alloc(piv_size + 1);
|
||||
if (index < piv_size - 1) {
|
||||
size_t os = piv_size - index - 1;
|
||||
memmove((void*)(piv_data + index + 1), (const void*)(piv_data + index), os * sizeof(T));
|
||||
memmove((void *)(piv_data + index + 1), (const void *)(piv_data + index), os * sizeof(T));
|
||||
}
|
||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||
elementNew(piv_data + index, e);
|
||||
@@ -1364,7 +1324,7 @@ public:
|
||||
alloc(piv_size + 1);
|
||||
if (index < piv_size - 1) {
|
||||
size_t os = piv_size - index - 1;
|
||||
memmove((void*)(piv_data + index + 1), (const void*)(piv_data + index), os * sizeof(T));
|
||||
memmove((void *)(piv_data + index + 1), (const void *)(piv_data + index), os * sizeof(T));
|
||||
}
|
||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||
elementNew(piv_data + index, std::move(e));
|
||||
@@ -1388,7 +1348,7 @@ public:
|
||||
ssize_t os = piv_size - index;
|
||||
alloc(piv_size + v.piv_size);
|
||||
if (os > 0) {
|
||||
memmove((void*)(piv_data + index + v.piv_size), (const void*)(piv_data + index), os * sizeof(T));
|
||||
memmove((void *)(piv_data + index + v.piv_size), (const void *)(piv_data + index), os * sizeof(T));
|
||||
}
|
||||
newT(piv_data + index, v.piv_data, v.piv_size);
|
||||
return *this;
|
||||
@@ -1409,7 +1369,7 @@ public:
|
||||
ssize_t os = piv_size - index;
|
||||
alloc(piv_size + init_list.size());
|
||||
if (os > 0) {
|
||||
memmove((void*)(piv_data + index + init_list.size()), (const void*)(piv_data + index), os * sizeof(T));
|
||||
memmove((void *)(piv_data + index + init_list.size()), (const void *)(piv_data + index), os * sizeof(T));
|
||||
}
|
||||
newT(piv_data + index, init_list.begin(), init_list.size());
|
||||
return *this;
|
||||
@@ -1434,7 +1394,7 @@ public:
|
||||
} else {
|
||||
size_t os = piv_size - index - count;
|
||||
deleteT(piv_data + index, count);
|
||||
memmove((void*)(piv_data + index), (const void*)(piv_data + index + count), os * sizeof(T));
|
||||
memmove((void *)(piv_data + index), (const void *)(piv_data + index + count), os * sizeof(T));
|
||||
piv_size -= count;
|
||||
}
|
||||
return *this;
|
||||
@@ -1446,7 +1406,7 @@ public:
|
||||
//! \~english This operation is very fast and never fails.
|
||||
//! \~russian Эта операция выполняется мгновенно без копирования памяти и никогда не дает сбоев.
|
||||
inline void swap(PIVector<T> & v) {
|
||||
piSwap<T*>(piv_data, v.piv_data);
|
||||
piSwap<T *>(piv_data, v.piv_data);
|
||||
piSwap<size_t>(piv_size, v.piv_size);
|
||||
piSwap<size_t>(piv_rsize, v.piv_rsize);
|
||||
}
|
||||
@@ -1490,23 +1450,18 @@ public:
|
||||
//! Complexity `O(N·log(N))`.
|
||||
//! \~russian Сохранность порядка элементов, имеющих одинаковое значение, не гарантируется.
|
||||
//! Для сравнения элементов используется функция сравнения `comp`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше второго.
|
||||
//! Сигнатура функции сравнения должна быть эквивалентна следующей:
|
||||
//! \code
|
||||
//! bool comp(const T &a, const T &b);
|
||||
//! \endcode
|
||||
//! Сигнатура не обязана содержать const &, однако, функция не может изменять переданные объекты.
|
||||
//! Функция обязана возвращать `false` для одинаковых элементов,
|
||||
//! иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||
//! Для сортировки используется функция [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort).
|
||||
//! Сложность сортировки `O(N·log(N))`.
|
||||
//! Функция сравнения, возвращает `true` если первый аргумент меньше
|
||||
//! второго. Сигнатура функции сравнения должна быть эквивалентна следующей: \code bool comp(const T &a, const T &b); \endcode Сигнатура
|
||||
//! не обязана содержать const &, однако, функция не может изменять переданные объекты. Функция обязана возвращать `false` для
|
||||
//! одинаковых элементов, иначе это приведёт к неопределённому поведению программы и ошибкам памяти. Для сортировки используется функция
|
||||
//! [std::sort](https://ru.cppreference.com/w/cpp/algorithm/sort). Сложность сортировки `O(N·log(N))`.
|
||||
//! \~\code
|
||||
//! PIVector<int> v{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
|
||||
//! v.sort([](const int & a, const int & b){return a > b;});
|
||||
//! piCout << v; // {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
|
||||
//! \endcode
|
||||
//! \~\sa \a sort()
|
||||
inline PIVector<T> & sort(std::function<bool(const T &a, const T &b)> comp) {
|
||||
inline PIVector<T> & sort(std::function<bool(const T & a, const T & b)> comp) {
|
||||
std::sort(begin(), end(), comp);
|
||||
return *this;
|
||||
}
|
||||
@@ -1528,9 +1483,9 @@ public:
|
||||
//! \endcode
|
||||
//! \~\sa \a reversed()
|
||||
inline PIVector<T> & reverse() {
|
||||
size_t s2 = piv_size/2;
|
||||
size_t s2 = piv_size / 2;
|
||||
for (size_t i = 0; i < s2; ++i) {
|
||||
piSwap<T>(piv_data[i], piv_data[piv_size-i-1]);
|
||||
piSwap<T>(piv_data[i], piv_data[piv_size - i - 1]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -1560,8 +1515,10 @@ public:
|
||||
//! \~\sa \a resize()
|
||||
inline PIVector<T> & enlarge(ssize_t add_size, const T & e = T()) {
|
||||
ssize_t ns = size_s() + add_size;
|
||||
if (ns <= 0) clear();
|
||||
else resize(size_t(ns), e);
|
||||
if (ns <= 0)
|
||||
clear();
|
||||
else
|
||||
resize(size_t(ns), e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1731,7 +1688,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a prepend(), \a push_front(), \a push_back(), \a insert()
|
||||
inline PIVector<T> & append(const T & e) {return push_back(e);}
|
||||
inline PIVector<T> & append(const T & e) { return push_back(e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the end of the array.
|
||||
//! \~russian Добавляет элемент `e` в конец массива.
|
||||
@@ -1739,7 +1696,7 @@ public:
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & append(T && e) {return push_back(std::move(e));}
|
||||
inline PIVector<T> & append(T && e) { return push_back(std::move(e)); }
|
||||
|
||||
//! \~english Appends the given elements to the end of the array.
|
||||
//! \~russian Добавляет элементы в конец массива.
|
||||
@@ -1751,7 +1708,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & append(std::initializer_list<T> init_list) {return push_back(init_list);}
|
||||
inline PIVector<T> & append(std::initializer_list<T> init_list) { return push_back(init_list); }
|
||||
|
||||
//! \~english Appends the given array `v` to the end of the array.
|
||||
//! \~russian Добавляет массив `v` в конец массива.
|
||||
@@ -1764,7 +1721,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & append(const PIVector<T> & v) {return push_back(v);}
|
||||
inline PIVector<T> & append(const PIVector<T> & v) { return push_back(v); }
|
||||
|
||||
//! \~english Appends the given element `e` to the end of the array.
|
||||
//! \~russian Добавляет элемент `e` в конец массива.
|
||||
@@ -1775,7 +1732,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & operator <<(const T & e) {return push_back(e);}
|
||||
inline PIVector<T> & operator<<(const T & e) { return push_back(e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the end of the array.
|
||||
//! \~russian Добавляет элемент `e` в конец массива.
|
||||
@@ -1786,7 +1743,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & operator <<(T && e) {return push_back(std::move(e));}
|
||||
inline PIVector<T> & operator<<(T && e) { return push_back(std::move(e)); }
|
||||
|
||||
//! \~english Appends the given array `v` to the end of the array.
|
||||
//! \~russian Добавляет массив `v` в конец массива.
|
||||
@@ -1797,7 +1754,7 @@ public:
|
||||
//! piCout << v; // {1, 2, 3, 4, 5}
|
||||
//! \endcode
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & operator <<(const PIVector<T> & v) {return push_back(v);}
|
||||
inline PIVector<T> & operator<<(const PIVector<T> & v) { return push_back(v); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1815,9 +1772,7 @@ public:
|
||||
//! piCout << v; // {5, 4, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a push_back(), \a append(), \a prepend(), \a insert()
|
||||
inline PIVector<T> & push_front(const T & e) {
|
||||
return insert(0, e);
|
||||
}
|
||||
inline PIVector<T> & push_front(const T & e) { return insert(0, e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1825,9 +1780,7 @@ public:
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a push_front()
|
||||
inline PIVector<T> & push_front(T && e) {
|
||||
return insert(0, std::move(e));
|
||||
}
|
||||
inline PIVector<T> & push_front(T && e) { return insert(0, std::move(e)); }
|
||||
|
||||
//! \~english Appends the given array `v` to the begin of the array.
|
||||
//! \~russian Добавляет массив `v` в начало массива.
|
||||
@@ -1840,9 +1793,7 @@ public:
|
||||
//! piCout << v; // {4, 5, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a push_front()
|
||||
inline PIVector<T> & push_front(const PIVector<T> & v) {
|
||||
return insert(0, v);
|
||||
}
|
||||
inline PIVector<T> & push_front(const PIVector<T> & v) { return insert(0, v); }
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
@@ -1854,9 +1805,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & push_front(std::initializer_list<T> init_list) {
|
||||
return insert(0, init_list);
|
||||
}
|
||||
inline PIVector<T> & push_front(std::initializer_list<T> init_list) { return insert(0, init_list); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1874,7 +1823,7 @@ public:
|
||||
//! piCout << v; // {5, 4, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a append(), \a push_back(), \a push_front(), \a insert()
|
||||
inline PIVector<T> & prepend(const T & e) {return push_front(e);}
|
||||
inline PIVector<T> & prepend(const T & e) { return push_front(e); }
|
||||
|
||||
//! \~english Appends the given element `e` to the begin of the array.
|
||||
//! \~russian Добавляет элемент `e` в начало массива.
|
||||
@@ -1882,7 +1831,7 @@ public:
|
||||
//! \~english Overloaded function.
|
||||
//! \~russian Перегруженая функция.
|
||||
//! \~\sa \a prepend()
|
||||
inline PIVector<T> & prepend(T && e) {return push_front(std::move(e));}
|
||||
inline PIVector<T> & prepend(T && e) { return push_front(std::move(e)); }
|
||||
|
||||
//! \~english Appends the given array `v` to the begin of the array.
|
||||
//! \~russian Добавляет массив `v` в начало массива.
|
||||
@@ -1895,7 +1844,7 @@ public:
|
||||
//! piCout << v; // {4, 5, 1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a prepend()
|
||||
inline PIVector<T> & prepend(const PIVector<T> & v) {return push_front(v);}
|
||||
inline PIVector<T> & prepend(const PIVector<T> & v) { return push_front(v); }
|
||||
|
||||
//! \~english Appends the given elements to the begin of the array.
|
||||
//! \~russian Добавляет элементы в начало массива.
|
||||
@@ -1907,7 +1856,7 @@ public:
|
||||
//! Добавляет элементы из
|
||||
//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~\sa \a append()
|
||||
inline PIVector<T> & prepend(std::initializer_list<T> init_list) {return prepend(init_list);}
|
||||
inline PIVector<T> & prepend(std::initializer_list<T> init_list) { return prepend(init_list); }
|
||||
|
||||
//! \~english Remove one element from the end of the array.
|
||||
//! \~russian Удаляет один элемент с конца массива.
|
||||
@@ -1989,7 +1938,7 @@ public:
|
||||
//! piCout << v2; // {1, 2, 3}
|
||||
//! \endcode
|
||||
//! \~\sa \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIVector<ST> toType() const {
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
@@ -2104,7 +2053,7 @@ public:
|
||||
//! \~russian Аналогично \a forEachIndexed(), но позволяет изменять элементы массива.
|
||||
//! \~\sa \a forEach(), \a forEachIndexed()
|
||||
inline PIVector<T> & forEachIndexed(std::function<void(size_t index, T & e)> f) {
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
f(i, piv_data[i]);
|
||||
}
|
||||
return *this;
|
||||
@@ -2165,9 +2114,10 @@ public:
|
||||
//! piCout << sl; // {"1", "2", "3"}
|
||||
//! \endcode
|
||||
//! \~\sa \a forEach(), \a reduce()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIVector<ST> map(std::function<ST(const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
ret << f(piv_data[i]);
|
||||
}
|
||||
@@ -2182,9 +2132,10 @@ public:
|
||||
//! piCout << sl; // {"0", "1", "2"}
|
||||
//! \endcode
|
||||
//! \~\sa \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIVector<ST> mapIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
ret << f(i, piv_data[i]);
|
||||
}
|
||||
@@ -2199,9 +2150,10 @@ public:
|
||||
//! piCout << sl; // {"3", "2", "1"}
|
||||
//! \endcode
|
||||
//! \~\sa \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIVector<ST> mapReverse(std::function<ST(const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (ssize_t i = piv_size; i >= 0; --i) {
|
||||
ret << f(piv_data[i]);
|
||||
}
|
||||
@@ -2216,9 +2168,10 @@ public:
|
||||
//! piCout << sl; // {"2", "1", "0"}
|
||||
//! \endcode
|
||||
//! \~\sa \a mapReverse()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIVector<ST> mapReverseIndexed(std::function<ST(size_t index, const T & e)> f) const {
|
||||
PIVector<ST> ret; ret.reserve(piv_size);
|
||||
PIVector<ST> ret;
|
||||
ret.reserve(piv_size);
|
||||
for (ssize_t i = piv_size; i >= 0; --i) {
|
||||
ret << f(i, piv_data[i]);
|
||||
}
|
||||
@@ -2266,7 +2219,7 @@ public:
|
||||
//! piCout << s; // 15
|
||||
//! \endcode
|
||||
//! \~\sa \a forEach(), \a map()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
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 < piv_size; ++i) {
|
||||
@@ -2278,7 +2231,7 @@ public:
|
||||
//! \~english Same as \a reduce() but with `index` parameter in `f`.
|
||||
//! \~russian Аналогично \a reduce() но с параметром индекса `index` в функции `f`.
|
||||
//! \~\sa \a reduce()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline ST reduceIndexed(std::function<ST(size_t index, const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||
ST ret(initial);
|
||||
for (size_t i = 0; i < piv_size; ++i) {
|
||||
@@ -2290,7 +2243,7 @@ public:
|
||||
//! \~english Same as \a reduce() but from end to begin (from right to left).
|
||||
//! \~russian Аналогично \a reduce() но от конца до начала (справа на лево).
|
||||
//! \~\sa \a reduce()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline ST reduceReverse(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||
ST ret(initial);
|
||||
for (ssize_t i = piv_size; i >= 0; --i) {
|
||||
@@ -2302,7 +2255,7 @@ public:
|
||||
//! \~english Same as \a reduceReverse() but with `index` parameter in `f`.
|
||||
//! \~russian Аналогично \a reduceReverse() но с параметром индекса `index` в функции `f`.
|
||||
//! \~\sa \a reduceReverse()
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline ST reduceReverseIndexed(std::function<ST(size_t index, const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||
ST ret(initial);
|
||||
for (ssize_t i = piv_size; i >= 0; --i) {
|
||||
@@ -2332,24 +2285,24 @@ public:
|
||||
//! \~\sa \a map(), \a reduce(), \a flatten()
|
||||
inline PIVector<PIVector<T>> reshape(size_t rows, size_t cols, ReshapeOrder order = ReshapeByRow) const {
|
||||
#ifndef NDEBUG
|
||||
if (rows*cols != piv_size) {
|
||||
if (rows * cols != piv_size) {
|
||||
printf("error with PIVector<%s>::reshape\n", __PIP_TYPENAME__(T));
|
||||
}
|
||||
#endif
|
||||
assert(rows*cols == piv_size);
|
||||
assert(rows * cols == piv_size);
|
||||
PIVector<PIVector<T>> ret;
|
||||
if (isEmpty()) return ret;
|
||||
ret.expand(rows);
|
||||
if (order == ReshapeByRow) {
|
||||
for (size_t r = 0; r < rows; r++) {
|
||||
ret[r] = PIVector<T>(&(piv_data[r*cols]), cols);
|
||||
ret[r] = PIVector<T>(&(piv_data[r * cols]), cols);
|
||||
}
|
||||
}
|
||||
if (order == ReshapeByColumn) {
|
||||
for (size_t r = 0; r < rows; r++) {
|
||||
ret[r].resize(cols);
|
||||
for (size_t c = 0; c < cols; c++) {
|
||||
ret[r][c] = piv_data[c*rows + r];
|
||||
ret[r][c] = piv_data[c * rows + r];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2370,9 +2323,7 @@ public:
|
||||
//! 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, PIVector<C>>::value
|
||||
, int>::type = 0>
|
||||
template<typename C, typename std::enable_if<std::is_same<T, PIVector<C>>::value, int>::type = 0>
|
||||
inline PIVector<C> flatten(ReshapeOrder order = ReshapeByRow) const {
|
||||
PIVector<C> ret;
|
||||
if (isEmpty()) return ret;
|
||||
@@ -2413,9 +2364,7 @@ public:
|
||||
//! 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, PIVector<C>>::value
|
||||
, int>::type = 0>
|
||||
template<typename C, typename std::enable_if<std::is_same<T, PIVector<C>>::value, int>::type = 0>
|
||||
inline PIVector<PIVector<C>> reshape(size_t rows, size_t cols, ReshapeOrder order = ReshapeByRow) const {
|
||||
PIVector<C> fl = flatten<C>();
|
||||
return fl.reshape(rows, cols, order);
|
||||
@@ -2432,11 +2381,11 @@ public:
|
||||
PIVector<PIVector<T>> ret;
|
||||
if (isEmpty()) return ret;
|
||||
size_t start = 0;
|
||||
ssize_t ci = indexOf(separator, start);
|
||||
ssize_t ci = indexOf(separator, start);
|
||||
while (ci >= 0) {
|
||||
ret << PIVector<T>(piv_data + start, ci - start);
|
||||
start = ci + 1;
|
||||
ci = indexOf(separator, start);
|
||||
ci = indexOf(separator, start);
|
||||
}
|
||||
if (start < piv_size) {
|
||||
ret << PIVector<T>(piv_data + start, piv_size - start);
|
||||
@@ -2452,9 +2401,9 @@ public:
|
||||
if (isEmpty() || sz == 0) return ret;
|
||||
size_t ch = piv_size / sz;
|
||||
for (size_t i = 0; i < ch; ++i) {
|
||||
ret << PIVector<T>(piv_data + sz*i, sz);
|
||||
ret << PIVector<T>(piv_data + sz * i, sz);
|
||||
}
|
||||
size_t t = ch*sz;
|
||||
size_t t = ch * sz;
|
||||
if (t < piv_size) {
|
||||
ret << PIVector<T>(piv_data + t, piv_size - t);
|
||||
}
|
||||
@@ -2482,10 +2431,10 @@ public:
|
||||
if (index >= piv_size || count == 0) return ret;
|
||||
if (index + count > piv_size) count = piv_size - index;
|
||||
ret.alloc(count);
|
||||
memcpy((void*)ret.piv_data, (const void*)(piv_data + index), count * sizeof(T));
|
||||
memcpy((void *)ret.piv_data, (const void *)(piv_data + index), count * sizeof(T));
|
||||
size_t os = piv_size - index - count;
|
||||
if (os > 0) {
|
||||
memmove((void*)(piv_data + index), (const void*)(piv_data + index + count), os * sizeof(T));
|
||||
memmove((void *)(piv_data + index), (const void *)(piv_data + index + count), os * sizeof(T));
|
||||
piv_size -= count;
|
||||
} else {
|
||||
piv_size = index;
|
||||
@@ -2495,9 +2444,9 @@ public:
|
||||
|
||||
private:
|
||||
inline void _reset() {
|
||||
piv_size = 0;
|
||||
piv_size = 0;
|
||||
piv_rsize = 0;
|
||||
piv_data = nullptr;
|
||||
piv_data = nullptr;
|
||||
}
|
||||
|
||||
inline size_t asize(size_t s) {
|
||||
@@ -2506,13 +2455,12 @@ private:
|
||||
return piv_rsize * 2;
|
||||
}
|
||||
ssize_t t = _PIContainerConstants<T>::minCountPoT(), s_ = s - 1;
|
||||
while (s_ >> t) ++t;
|
||||
while (s_ >> t)
|
||||
++t;
|
||||
return (1 << t);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
for (size_t i = 0; i < s; ++i) {
|
||||
@@ -2520,17 +2468,13 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void newT(T * dst, const T * src, size_t s) {
|
||||
PIINTROSPECTION_CONTAINER_USED(T, s)
|
||||
memcpy((void*)(dst), (const void*)(src), s * sizeof(T));
|
||||
memcpy((void *)(dst), (const void *)(src), s * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
if (d != nullptr) {
|
||||
@@ -2540,56 +2484,42 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void deleteT(T * d, size_t sz) {
|
||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, const T & from) {
|
||||
new(to)T(from);
|
||||
new (to) T(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
new(to)T(std::move(from));
|
||||
new (to) T(std::move(from));
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T1 * to, const T & from) {
|
||||
(*to) = from;
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementNew(T * to, T && from) {
|
||||
(*to) = std::move(from);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
!std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<!std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {
|
||||
from.~T();
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline void elementDelete(T & from) {}
|
||||
|
||||
inline void dealloc() {
|
||||
if (piv_data != nullptr) {
|
||||
free((void*)piv_data);
|
||||
free((void *)piv_data);
|
||||
piv_data = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -2597,7 +2527,7 @@ private:
|
||||
inline void expand(size_t new_size, const T & e = T()) {
|
||||
size_t os = piv_size;
|
||||
alloc(new_size);
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size - os))
|
||||
for (size_t i = os; i < new_size; ++i) {
|
||||
elementNew(piv_data + i, e);
|
||||
}
|
||||
@@ -2606,7 +2536,7 @@ private:
|
||||
inline void expand(size_t new_size, std::function<T(size_t i)> f) {
|
||||
size_t os = piv_size;
|
||||
alloc(new_size);
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size - os))
|
||||
for (size_t i = os; i < new_size; ++i) {
|
||||
elementNew(piv_data + i, f(i));
|
||||
}
|
||||
@@ -2617,23 +2547,23 @@ private:
|
||||
piv_size = new_size;
|
||||
return;
|
||||
}
|
||||
piv_size = new_size;
|
||||
piv_size = new_size;
|
||||
size_t as = asize(new_size);
|
||||
if (as == piv_rsize) return;
|
||||
PIINTROSPECTION_CONTAINER_ALLOC(T, (as-piv_rsize))
|
||||
T * p_d = (T*)(realloc((void*)(piv_data), as*sizeof(T)));
|
||||
PIINTROSPECTION_CONTAINER_ALLOC(T, (as - piv_rsize))
|
||||
T * p_d = (T *)(realloc((void *)(piv_data), as * sizeof(T)));
|
||||
#ifndef NDEBUG
|
||||
if (!p_d) {
|
||||
printf("error with PIVector<%s>::alloc\n", __PIP_TYPENAME__(T));
|
||||
}
|
||||
#endif
|
||||
assert(p_d);
|
||||
piv_data = p_d;
|
||||
piv_data = p_d;
|
||||
piv_rsize = as;
|
||||
}
|
||||
|
||||
T * piv_data = nullptr;
|
||||
size_t piv_size = 0;
|
||||
T * piv_data = nullptr;
|
||||
size_t piv_size = 0;
|
||||
size_t piv_rsize = 0;
|
||||
};
|
||||
|
||||
@@ -2642,7 +2572,7 @@ private:
|
||||
//! \~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 PIVector<T> & v) {
|
||||
inline std::ostream & operator<<(std::ostream & s, const PIVector<T> & v) {
|
||||
s << "{";
|
||||
for (size_t i = 0; i < v.size(); ++i) {
|
||||
s << v[i];
|
||||
@@ -2657,7 +2587,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIVector<T> & v) {
|
||||
//! \~english Output operator to \a PICout
|
||||
//! \~russian Оператор вывода в \a PICout
|
||||
template<typename T>
|
||||
inline PICout operator <<(PICout s, const PIVector<T> & v) {
|
||||
inline PICout operator<<(PICout s, const PIVector<T> & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "{";
|
||||
@@ -2673,6 +2603,8 @@ inline PICout operator <<(PICout s, const PIVector<T> & v) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void piSwap(PIVector<T> & f, PIVector<T> & s) {f.swap(s);}
|
||||
inline void piSwap(PIVector<T> & f, PIVector<T> & s) {
|
||||
f.swap(s);
|
||||
}
|
||||
|
||||
#endif // PIVECTOR_H
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
* \brief 2D wrapper around PIVector
|
||||
*
|
||||
* This file declares PIVector
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
2D wrapper around PIVector
|
||||
Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
2D wrapper around PIVector
|
||||
Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIVECTOR2D_H
|
||||
@@ -35,154 +35,176 @@
|
||||
* PIVector2D has constructors from PIVector<T> and PIVector<PIVector<T> >
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class PIVector2D {
|
||||
public:
|
||||
inline PIVector2D() {rows_ = cols_ = 0;}
|
||||
inline PIVector2D() { rows_ = cols_ = 0; }
|
||||
|
||||
inline PIVector2D(size_t rows, size_t cols, const T & f = T()) {
|
||||
rows_ = rows;
|
||||
cols_ = cols;
|
||||
mat.resize(rows*cols, f);
|
||||
mat.resize(rows * cols, f);
|
||||
}
|
||||
|
||||
inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v) : rows_(rows), cols_(cols), mat(v) {
|
||||
mat.resize(rows*cols);
|
||||
}
|
||||
inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v): rows_(rows), cols_(cols), mat(v) { mat.resize(rows * cols); }
|
||||
|
||||
inline PIVector2D(size_t rows, size_t cols, PIVector<T> && v) : rows_(rows), cols_(cols), mat(std::move(v)) {
|
||||
mat.resize(rows*cols);
|
||||
}
|
||||
inline PIVector2D(size_t rows, size_t cols, PIVector<T> && v): rows_(rows), cols_(cols), mat(std::move(v)) { mat.resize(rows * cols); }
|
||||
|
||||
inline PIVector2D(const PIVector<PIVector<T>> & v) {
|
||||
rows_ = v.size();
|
||||
if (rows_) {
|
||||
cols_ = v[0].size();
|
||||
mat.reserve(rows_*cols_);
|
||||
mat.reserve(rows_ * cols_);
|
||||
for (size_t i = 0; i < rows_; i++) {
|
||||
mat.append(v[i]);
|
||||
}
|
||||
mat.resize(rows_*cols_);
|
||||
mat.resize(rows_ * cols_);
|
||||
}
|
||||
if (mat.isEmpty()) rows_ = cols_ = 0;
|
||||
}
|
||||
|
||||
inline size_t rows() const {return rows_;}
|
||||
inline size_t rows() const { return rows_; }
|
||||
|
||||
inline size_t cols() const {return cols_;}
|
||||
inline size_t cols() const { return cols_; }
|
||||
|
||||
inline size_t size() const {return mat.size();}
|
||||
inline size_t size() const { return mat.size(); }
|
||||
|
||||
inline ssize_t size_s() const {return mat.size_s();}
|
||||
inline ssize_t size_s() const { return mat.size_s(); }
|
||||
|
||||
inline size_t length() const {return mat.length();}
|
||||
inline size_t length() const { return mat.length(); }
|
||||
|
||||
inline size_t capacity() const {return mat.capacity();}
|
||||
inline size_t capacity() const { return mat.capacity(); }
|
||||
|
||||
inline bool isEmpty() const {return mat.isEmpty();}
|
||||
inline bool isEmpty() const { return mat.isEmpty(); }
|
||||
|
||||
inline bool isNotEmpty() const {return mat.isNotEmpty();}
|
||||
inline bool isNotEmpty() const { return mat.isNotEmpty(); }
|
||||
|
||||
class Row {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline Row(PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {st_ = p->cols_ * row; sz_ = p->cols_;}
|
||||
inline Row(PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
st_ = p->cols_ * row;
|
||||
sz_ = p->cols_;
|
||||
}
|
||||
PIVector<T> * p_;
|
||||
size_t st_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const {return sz_;}
|
||||
inline T & operator [](size_t index) {return (*p_)[st_ + index];}
|
||||
inline const T & operator [](size_t index) const {return (*p_)[st_ + index];}
|
||||
inline T * data(size_t index = 0) {return p_->data(st_ + index);}
|
||||
inline const T * data(size_t index = 0) const {return p_->data(st_ + index);}
|
||||
inline Row & operator =(const Row & other) {
|
||||
inline size_t size() const { return sz_; }
|
||||
inline T & operator[](size_t index) { return (*p_)[st_ + index]; }
|
||||
inline const T & operator[](size_t index) const { return (*p_)[st_ + index]; }
|
||||
inline T * data(size_t index = 0) { return p_->data(st_ + index); }
|
||||
inline const T * data(size_t index = 0) const { return p_->data(st_ + index); }
|
||||
inline Row & operator=(const Row & other) {
|
||||
if (p_ == other.p_ && st_ == other.st_) return *this;
|
||||
size_t sz = piMin<size_t>(sz_, other.sz_);
|
||||
p_->_copyRaw(p_->data(st_), other.data(), sz);
|
||||
return *this;
|
||||
}
|
||||
inline Row & operator =(const PIVector<T> & other) {
|
||||
inline Row & operator=(const PIVector<T> & other) {
|
||||
size_t sz = piMin<size_t>(sz, other.size());
|
||||
p_->_copyRaw(p_->data(st_), other.data(), sz);
|
||||
return *this;
|
||||
}
|
||||
inline PIVector<T> toVector() const {return PIVector<T>(p_->data(st_), sz_);}
|
||||
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
|
||||
};
|
||||
|
||||
class Col {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline Col(PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {step_ = p->cols_; row_ = row; sz_ = p->rows_;}
|
||||
inline Col(PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
step_ = p->cols_;
|
||||
row_ = row;
|
||||
sz_ = p->rows_;
|
||||
}
|
||||
PIVector<T> * p_;
|
||||
size_t step_, row_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const {return sz_;}
|
||||
inline T & operator [](size_t index) {return (*p_)[index * step_ + row_];}
|
||||
inline const T & operator [](size_t index) const {return (*p_)[index * step_ + row_];}
|
||||
inline T * data(size_t index = 0) {return p_->data(index * step_ + row_);}
|
||||
inline const T * data(size_t index = 0) const {return p_->data(index * step_ + row_);}
|
||||
inline Col & operator =(const Col & other) {
|
||||
inline size_t size() const { return sz_; }
|
||||
inline T & operator[](size_t index) { return (*p_)[index * step_ + row_]; }
|
||||
inline const T & operator[](size_t index) const { return (*p_)[index * step_ + row_]; }
|
||||
inline T * data(size_t index = 0) { return p_->data(index * step_ + row_); }
|
||||
inline const T * data(size_t index = 0) const { return p_->data(index * step_ + row_); }
|
||||
inline Col & operator=(const Col & other) {
|
||||
if (p_ == other.p_ && row_ == other.row_) return *this;
|
||||
size_t sz = piMin<size_t>(sz_, other.sz_);
|
||||
for (int i=0; i<sz; ++i) (*p_)[i * step_ + row_] = other[i];
|
||||
for (int i = 0; i < sz; ++i)
|
||||
(*p_)[i * step_ + row_] = other[i];
|
||||
return *this;
|
||||
}
|
||||
inline Row & operator =(const PIVector<T> & other) {
|
||||
inline Row & operator=(const PIVector<T> & other) {
|
||||
size_t sz = piMin<size_t>(sz_, other.size());
|
||||
for (int i=0; i<sz; ++i) (*p_)[i * step_ + row_] = other[i];
|
||||
for (int i = 0; i < sz; ++i)
|
||||
(*p_)[i * step_ + row_] = other[i];
|
||||
return *this;
|
||||
}
|
||||
inline PIVector<T> toVector() const {
|
||||
PIVector<T> ret;
|
||||
ret.reserve(sz_);
|
||||
for (size_t i=0; i<sz_; i++) ret << (*p_)[i * step_ + row_];
|
||||
for (size_t i = 0; i < sz_; i++)
|
||||
ret << (*p_)[i * step_ + row_];
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
class RowConst {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline RowConst(const PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {st_ = p->cols_ * row; sz_ = p->cols_;}
|
||||
inline RowConst(const PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
st_ = p->cols_ * row;
|
||||
sz_ = p->cols_;
|
||||
}
|
||||
const PIVector<T> * p_;
|
||||
size_t st_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const {return sz_;}
|
||||
inline const T & operator [](size_t index) const {return (*p_)[st_ + index];}
|
||||
inline const T * data(size_t index = 0) const {return p_->data(st_ + index);}
|
||||
inline PIVector<T> toVector() const {return PIVector<T>(p_->data(st_), sz_);}
|
||||
inline size_t size() const { return sz_; }
|
||||
inline const T & operator[](size_t index) const { return (*p_)[st_ + index]; }
|
||||
inline const T * data(size_t index = 0) const { return p_->data(st_ + index); }
|
||||
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
|
||||
};
|
||||
|
||||
class ColConst {
|
||||
friend class PIVector2D<T>;
|
||||
|
||||
private:
|
||||
inline ColConst(const PIVector2D<T> * p, size_t row) : p_(&(p->mat)) {step_ = p->cols_; row_ = row; sz_ = p->rows_;}
|
||||
inline ColConst(const PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
||||
step_ = p->cols_;
|
||||
row_ = row;
|
||||
sz_ = p->rows_;
|
||||
}
|
||||
const PIVector<T> * p_;
|
||||
size_t step_, row_, sz_;
|
||||
|
||||
public:
|
||||
inline size_t size() const {return p_->rows_;}
|
||||
inline const T & operator [](size_t index) const {return (*p_)[index * step_ + row_];}
|
||||
inline const T * data(size_t index = 0) const {return p_->data(index * step_ + row_);}
|
||||
inline size_t size() const { return p_->rows_; }
|
||||
inline const T & operator[](size_t index) const { return (*p_)[index * step_ + row_]; }
|
||||
inline const T * data(size_t index = 0) const { return p_->data(index * step_ + row_); }
|
||||
inline PIVector<T> toVector() const {
|
||||
PIVector<T> ret;
|
||||
ret.reserve(sz_);
|
||||
for (int i=0; i<size(); i++) ret << (*p_)[i * step_ + row_];
|
||||
for (int i = 0; i < size(); i++)
|
||||
ret << (*p_)[i * step_ + row_];
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
inline T & element(size_t row, size_t col) {return mat[row * cols_ + col];}
|
||||
inline const T & element(size_t row, size_t col) const {return mat[row * cols_ + col];}
|
||||
inline const T & at(size_t row, size_t col) const {return mat[row * cols_ + col];}
|
||||
inline Row operator[](size_t index) {return Row(this, index);}
|
||||
inline RowConst operator[](size_t index) const {return RowConst(this, index);}
|
||||
inline T * data(size_t index = 0) {return mat.data(index);}
|
||||
inline const T * data(size_t index = 0) const {return mat.data(index);}
|
||||
inline T & element(size_t row, size_t col) { return mat[row * cols_ + col]; }
|
||||
inline const T & element(size_t row, size_t col) const { return mat[row * cols_ + col]; }
|
||||
inline const T & at(size_t row, size_t col) const { return mat[row * cols_ + col]; }
|
||||
inline Row operator[](size_t index) { return Row(this, index); }
|
||||
inline RowConst operator[](size_t index) const { return RowConst(this, index); }
|
||||
inline T * data(size_t index = 0) { return mat.data(index); }
|
||||
inline const T * data(size_t index = 0) const { return mat.data(index); }
|
||||
|
||||
inline Row row(size_t index) {return Row(this, index);}
|
||||
inline RowConst row(size_t index) const {return RowConst(this, index);}
|
||||
inline Col col(size_t index) {return Col(this, index);}
|
||||
inline ColConst col(size_t index) const {return ColConst(this, index);}
|
||||
inline Row row(size_t index) { return Row(this, index); }
|
||||
inline RowConst row(size_t index) const { return RowConst(this, index); }
|
||||
inline Col col(size_t index) { return Col(this, index); }
|
||||
inline ColConst col(size_t index) const { return ColConst(this, index); }
|
||||
inline PIVector2D<T> & setRow(size_t row, const Row & other) {
|
||||
size_t sz = piMin<size_t>(cols_, other.sz_);
|
||||
mat._copyRaw(mat.data(cols_ * row), other.data(), sz);
|
||||
@@ -227,20 +249,20 @@ public:
|
||||
}
|
||||
|
||||
inline PIVector2D<T> & resize(size_t rows, size_t cols, const T & f = T()) {
|
||||
mat.resize(rows*cols_, f);
|
||||
rows_ = rows;
|
||||
mat.resize(rows * cols_, f);
|
||||
rows_ = rows;
|
||||
int cs = (cols - cols_);
|
||||
if (cs < 0) {
|
||||
for (size_t r=0; r<rows; ++r) {
|
||||
mat.remove(r*cols + cols, -cs);
|
||||
for (size_t r = 0; r < rows; ++r) {
|
||||
mat.remove(r * cols + cols, -cs);
|
||||
}
|
||||
}
|
||||
mat.resize(rows*cols, f);
|
||||
mat.resize(rows * cols, f);
|
||||
if (!mat.isEmpty()) {
|
||||
if (cs > 0) {
|
||||
for (size_t r=0; r<rows_; ++r) {
|
||||
for (int i=0; i<cs; ++i)
|
||||
mat.insert(r*cols + cols_, mat.take_back());
|
||||
for (size_t r = 0; r < rows_; ++r) {
|
||||
for (int i = 0; i < cs; ++i)
|
||||
mat.insert(r * cols + cols_, mat.take_back());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,26 +270,25 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator ==(const PIVector2D<T> & t) const {
|
||||
if (cols_ != t.cols_ || rows_ != t.rows_)
|
||||
return false;
|
||||
inline bool operator==(const PIVector2D<T> & t) const {
|
||||
if (cols_ != t.cols_ || rows_ != t.rows_) return false;
|
||||
return mat == t.mat;
|
||||
}
|
||||
inline bool operator !=(const PIVector2D<T> & t) const {return !(*this == t);}
|
||||
inline bool operator!=(const PIVector2D<T> & t) const { return !(*this == t); }
|
||||
|
||||
inline PIVector<PIVector<T> > toVectors() const {
|
||||
PIVector<PIVector<T> > ret;
|
||||
inline PIVector<PIVector<T>> toVectors() const {
|
||||
PIVector<PIVector<T>> ret;
|
||||
ret.reserve(rows_);
|
||||
for(size_t i = 0; i < rows_; ++i)
|
||||
ret << PIVector<T>(mat.data(i*cols_), cols_);
|
||||
for (size_t i = 0; i < rows_; ++i)
|
||||
ret << PIVector<T>(mat.data(i * cols_), cols_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline PIVector<T> toPlainVector() const {return mat;}
|
||||
inline PIVector<T> toPlainVector() const { return mat; }
|
||||
|
||||
inline PIVector<T> & plainVector() {return mat;}
|
||||
inline PIVector<T> & plainVector() { return mat; }
|
||||
|
||||
inline const PIVector<T> & plainVector() const {return mat;}
|
||||
inline const PIVector<T> & plainVector() const { return mat; }
|
||||
|
||||
inline void swap(PIVector2D<T> & other) {
|
||||
mat.swap(other.mat);
|
||||
@@ -275,13 +296,11 @@ public:
|
||||
piSwap<size_t>(cols_, other.cols_);
|
||||
}
|
||||
|
||||
template<typename T1 = T, typename std::enable_if<
|
||||
std::is_trivially_copyable<T1>::value
|
||||
, int>::type = 0>
|
||||
template<typename T1 = T, typename std::enable_if<std::is_trivially_copyable<T1>::value, int>::type = 0>
|
||||
inline PIVector2D<T> & _resizeRaw(size_t r, size_t c) {
|
||||
rows_ = r;
|
||||
cols_ = c;
|
||||
mat._resizeRaw(r*c);
|
||||
mat._resizeRaw(r * c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -290,14 +309,12 @@ public:
|
||||
mat.clear();
|
||||
}
|
||||
|
||||
template <typename ST>
|
||||
template<typename ST>
|
||||
inline PIVector2D<ST> map(std::function<ST(const T & e)> f) const {
|
||||
return PIVector2D<ST>(rows_, cols_, mat.map(f));
|
||||
}
|
||||
|
||||
inline void forEach(std::function<void(const T &)> f) const {
|
||||
mat.forEach(f);
|
||||
}
|
||||
inline void forEach(std::function<void(const T &)> f) const { mat.forEach(f); }
|
||||
|
||||
inline PIVector2D<T> & forEach(std::function<void(T &)> f) {
|
||||
mat.forEach(f);
|
||||
@@ -311,7 +328,7 @@ protected:
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline PICout operator <<(PICout s, const PIVector2D<T> & v) {
|
||||
inline PICout operator<<(PICout s, const PIVector2D<T> & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "{";
|
||||
for (size_t i = 0; i < v.rows(); ++i) {
|
||||
@@ -321,7 +338,7 @@ inline PICout operator <<(PICout s, const PIVector2D<T> & v) {
|
||||
if (j < v.cols() - 1) s << ", ";
|
||||
}
|
||||
s << " }";
|
||||
if (i < v.rows() - 1) s << PICoutManipulators::NewLine ;
|
||||
if (i < v.rows() - 1) s << PICoutManipulators::NewLine;
|
||||
}
|
||||
if (v.isEmpty()) s << "{ }";
|
||||
s << "}";
|
||||
|
||||
Reference in New Issue
Block a user