Compare commits
3 Commits
7c927da979
...
c2ceb710c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2ceb710c5 | ||
|
|
288062cfd6 | ||
|
|
9f1ae76d1e |
BIN
doc/images/pivector_begin.png
Normal file
BIN
doc/images/pivector_begin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
BIN
doc/images/pivector_rbegin.png
Normal file
BIN
doc/images/pivector_rbegin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -1,17 +1,17 @@
|
|||||||
/*! \addtogroup Containers
|
//! \addtogroup Containers
|
||||||
* \{
|
//! \{
|
||||||
* \file pivector.h
|
//! \file pivector.h
|
||||||
* \brief
|
//! \brief
|
||||||
* \~english Declares \a PIVector
|
//! \~english Declares \a PIVector
|
||||||
* \~russian Объявление \a PIVector
|
//! \~russian Объявление \a PIVector
|
||||||
* \~\authors
|
//! \~\authors
|
||||||
* \~english
|
//! \~english
|
||||||
* Ivan Pelipenko peri4ko@yandex.ru;
|
//! Ivan Pelipenko peri4ko@yandex.ru;
|
||||||
* Andrey Bychkov work.a.b@yandex.ru;
|
//! Andrey Bychkov work.a.b@yandex.ru;
|
||||||
* \~russian
|
//! \~russian
|
||||||
* Иван Пелипенко peri4ko@yandex.ru;
|
//! Иван Пелипенко peri4ko@yandex.ru;
|
||||||
* Андрей Бычков work.a.b@yandex.ru;
|
//! Андрей Бычков work.a.b@yandex.ru;
|
||||||
* \~\} */
|
//! \~\} */
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Sequence linear container aka dynamic size array of any type
|
Sequence linear container aka dynamic size array of any type
|
||||||
@@ -36,69 +36,70 @@
|
|||||||
|
|
||||||
#include "picontainers.h"
|
#include "picontainers.h"
|
||||||
|
|
||||||
/*! \addtogroup Containers
|
//! \addtogroup Containers
|
||||||
* \{
|
//! \{
|
||||||
* \class PIVector pivector.h
|
//! \class PIVector
|
||||||
* \brief
|
//! \brief
|
||||||
* \~english Sequence linear container - dynamic size array of any type
|
//! \~english Sequence linear container - dynamic size array of any type.
|
||||||
* \~russian Последовательный контейнер с линейной памятью - динамический массив любого типа
|
//! \~russian Последовательный контейнер с линейной памятью - динамический массив любого типа.
|
||||||
* \~\}
|
//! \~\}
|
||||||
* \details
|
//! \details
|
||||||
* \~english
|
//! \~english
|
||||||
* The elements are stored contiguously,
|
//! The elements are stored contiguously,
|
||||||
* which means that elements can be accessed not only through iterators,
|
//! which means that elements can be accessed not only through iterators,
|
||||||
* but also using offsets to regular pointers to elements.
|
//! but also using offsets to regular pointers to elements.
|
||||||
* This means that a pointer to an element of a vector may be passed to any function
|
//! This means that a pointer to an element of a vector may be passed to any function
|
||||||
* that expects a pointer to an element of an array.
|
//! that expects a pointer to an element of an array.
|
||||||
*
|
//!
|
||||||
* The storage of the vector is handled automatically,
|
//! The storage of the vector is handled automatically,
|
||||||
* being expanded and contracted as needed.
|
//! being expanded and contracted as needed.
|
||||||
* Vectors usually occupy more space than static arrays,
|
//! Vectors usually occupy more space than static arrays,
|
||||||
* because more memory is allocated to handle future growth.
|
//! because more memory is allocated to handle future growth.
|
||||||
* This way a vector does not need to reallocate each time an element is inserted,
|
//! This way a vector does not need to reallocate each time an element is inserted,
|
||||||
* but only when the additional memory is exhausted.
|
//! but only when the additional memory is exhausted.
|
||||||
* The total amount of allocated memory can be queried using \a capacity() function.
|
//! The total amount of allocated memory can be queried using \a capacity() function.
|
||||||
* Reallocations are usually costly operations in terms of performance.
|
//! Reallocations are usually costly operations in terms of performance.
|
||||||
* The \a reserve() function can be used to eliminate reallocations
|
//! The \a reserve() function can be used to eliminate reallocations
|
||||||
* if the number of elements is known beforehand.
|
//! if the number of elements is known beforehand.
|
||||||
*
|
//!
|
||||||
* The complexity (efficiency) of common operations on vectors is as follows:
|
//! The complexity (efficiency) of common operations on vectors is as follows:
|
||||||
* - Random access - constant 𝓞(1)
|
//! - Random access - constant 𝓞(1)
|
||||||
* - Insertion or removal of elements at the end - amortized constant 𝓞(1)
|
//! - Insertion or removal of elements at the end - amortized constant 𝓞(1)
|
||||||
* - Insertion or removal of elements - linear in the distance to the end of the vector 𝓞(n)
|
//! - Insertion or removal of elements - linear in the distance to the end of the vector 𝓞(n)
|
||||||
*
|
//!
|
||||||
* \~russian
|
//! \~russian
|
||||||
* Элементы хранятся непрерывно, а значит доступны не только через итераторы,
|
//! Элементы хранятся непрерывно, а значит доступны не только через итераторы,
|
||||||
* но и с помощью смещений для обычных указателей на элементы.
|
//! но и с помощью смещений для обычных указателей на элементы.
|
||||||
* Это означает, что указатель на элемент вектора может передаваться в любую функцию,
|
//! Это означает, что указатель на элемент вектора может передаваться в любую функцию,
|
||||||
* ожидающую указатель на элемент массива.
|
//! ожидающую указатель на элемент массива.
|
||||||
*
|
//!
|
||||||
* Память вектора обрабатывается автоматически,
|
//! Память вектора обрабатывается автоматически,
|
||||||
* расширяясь и сжимаясь по мере необходимости.
|
//! расширяясь и сжимаясь по мере необходимости.
|
||||||
* Векторы обычно занимают больше места, чем статические массивы,
|
//! Векторы обычно занимают больше места, чем статические массивы,
|
||||||
* поскольку больше памяти выделяется для обработки будущего роста.
|
//! поскольку больше памяти выделяется для обработки будущего роста.
|
||||||
* Таким образом, память для вектора требуется выделять
|
//! Таким образом, память для вектора требуется выделять
|
||||||
* не при каждой вставке элемента,
|
//! не при каждой вставке элемента,
|
||||||
* а только после исчерпания дополнительной памяти.
|
//! а только после исчерпания дополнительной памяти.
|
||||||
* Общий объём выделенной памяти можно получить с помощью функции \a capacity().
|
//! Общий объём выделенной памяти можно получить с помощью функции \a capacity().
|
||||||
*
|
//!
|
||||||
* Выделение памяти обычно является дорогостоящей операцией
|
//! Выделение памяти обычно является дорогостоящей операцией
|
||||||
* с точки зрения производительности.
|
//! с точки зрения производительности.
|
||||||
* Функцию \a reserve() можно использовать для исключения выделения памяти,
|
//! Функцию \a reserve() можно использовать для исключения выделения памяти,
|
||||||
* если количество элементов известно заранее.
|
//! если количество элементов известно заранее.
|
||||||
*
|
//!
|
||||||
* Сложность (эффективность) обычных операций над векторами следующая:
|
//! Сложность (эффективность) обычных операций над векторами следующая:
|
||||||
* - Произвольный доступ — постоянная 𝓞(1)
|
//! - Произвольный доступ — постоянная 𝓞(1)
|
||||||
* - Вставка и удаление элементов в конце — амортизированная постоянная 𝓞(1)
|
//! - Вставка и удаление элементов в конце — амортизированная постоянная 𝓞(1)
|
||||||
* - Вставка и удаление элементов — линейная по расстоянию до конца вектора 𝓞(n)
|
//! - Вставка и удаление элементов — линейная по расстоянию до конца вектора 𝓞(n)
|
||||||
*/
|
//!
|
||||||
|
//! \~\sa \a PIDeueue, \a PIMap
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class PIVector {
|
class PIVector {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Constructs an empty vector
|
//! \~english Constructs an empty vector.
|
||||||
//! \~russian Создает пустой массив
|
//! \~russian Создает пустой массив.
|
||||||
inline PIVector(): piv_data(0), piv_size(0), piv_rsize(0) {
|
inline PIVector(): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
}
|
}
|
||||||
@@ -115,8 +116,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Copy constructor
|
//! \~english Copy constructor.
|
||||||
//! \~russian Копирующий конструктор
|
//! \~russian Копирующий конструктор.
|
||||||
inline PIVector(const PIVector<T> & v): piv_data(0), piv_size(0), piv_rsize(0) {
|
inline PIVector(const PIVector<T> & v): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
alloc(v.piv_size);
|
alloc(v.piv_size);
|
||||||
@@ -124,15 +125,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Contructs vector from C++11 initializer list.
|
//! \~english Contructs vector from [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||||
//! \~russian Создает массив из списка инициализации C++11.
|
//! \~russian Создает массив из [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||||
//! \~\details
|
//! \~\details
|
||||||
//! \~english
|
|
||||||
//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~russian
|
|
||||||
//! [Список инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
|
||||||
//! \~\code
|
//! \~\code
|
||||||
//! PIVector <int> v{1,2,3};
|
//! PIVector <int> v{1,2,3};
|
||||||
//! piCout << v;
|
//! piCout << v;
|
||||||
//! // {1, 2, 3}
|
//! // {1, 2, 3}
|
||||||
//! \endcode
|
//! \endcode
|
||||||
@@ -157,7 +154,7 @@ public:
|
|||||||
//! \~english Can use [Lambda expressions](https://en.cppreference.com/w/cpp/language/lambda) as constructor argument.
|
//! \~english Can use [Lambda expressions](https://en.cppreference.com/w/cpp/language/lambda) as constructor argument.
|
||||||
//! \~russian Позволяет передавать [Лямбда-выражения](https://ru.cppreference.com/w/cpp/language/lambda) для создания элементов в конструкторе.
|
//! \~russian Позволяет передавать [Лямбда-выражения](https://ru.cppreference.com/w/cpp/language/lambda) для создания элементов в конструкторе.
|
||||||
//! \~\code
|
//! \~\code
|
||||||
//! PIVector <int> v(5, [](size_t i){return i*2;});
|
//! PIVector <int> v(5, [](size_t i){return i*2;});
|
||||||
//! piCout << v;
|
//! piCout << v;
|
||||||
//! // {0, 2, 4, 6, 8}
|
//! // {0, 2, 4, 6, 8}
|
||||||
//! \endcode
|
//! \endcode
|
||||||
@@ -167,16 +164,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Move constructor
|
//! \~english Move constructor.
|
||||||
//! \~russian Перемещающий конструктор
|
//! \~russian Перемещающий конструктор.
|
||||||
inline PIVector(PIVector<T> && v): piv_data(v.piv_data), piv_size(v.piv_size), piv_rsize(v.piv_rsize) {
|
inline PIVector(PIVector<T> && v): piv_data(v.piv_data), piv_size(v.piv_size), piv_rsize(v.piv_rsize) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
v._reset();
|
v._reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
inline virtual ~PIVector() {
|
inline virtual ~PIVector() {
|
||||||
PIINTROSPECTION_CONTAINER_DELETE(T)
|
PIINTROSPECTION_CONTAINER_DELETE(T)
|
||||||
PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize))
|
PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize))
|
||||||
@@ -186,8 +180,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Assign operator
|
//! \~english Assign operator.
|
||||||
//! \~russian Оператор присваивания
|
//! \~russian Оператор присваивания.
|
||||||
inline PIVector<T> & operator =(const PIVector<T> & v) {
|
inline PIVector<T> & operator =(const PIVector<T> & v) {
|
||||||
if (this == &v) return *this;
|
if (this == &v) return *this;
|
||||||
clear();
|
clear();
|
||||||
@@ -198,8 +192,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Assign move operator
|
//! \~english Assign move operator.
|
||||||
//! \~russian Оператор перемещающего присваивания
|
//! \~russian Оператор перемещающего присваивания.
|
||||||
inline PIVector<T> & operator =(PIVector<T> && v) {
|
inline PIVector<T> & operator =(PIVector<T> && v) {
|
||||||
swap(v);
|
swap(v);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -283,27 +277,143 @@ public:
|
|||||||
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);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Iterator to the first element.
|
||||||
|
//! \~russian Итератор на первый элемент.
|
||||||
|
//! \~\details 
|
||||||
|
//!
|
||||||
|
//! \~english If the vector is empty, the returned iterator is equal to \a end.
|
||||||
|
//! \~russian Если массив - пуст, возвращаемый итератор будет равен \a end.
|
||||||
|
//! \~\sa \a end, \a rbegin, \a rend
|
||||||
inline iterator begin() {return iterator(this, 0);}
|
inline iterator begin() {return iterator(this, 0);}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Iterator to the element following the last element.
|
||||||
|
//! \~russian Итератор на элемент, следующий за последним элементом.
|
||||||
|
//! \~\details 
|
||||||
|
//!
|
||||||
|
//! \~english This element acts as a placeholder; attempting to access it results in undefined behavior.
|
||||||
|
//! \~russian Этот элемент существует лишь условно,
|
||||||
|
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||||
|
//! \~\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 begin() const {return const_iterator(this, 0);}
|
||||||
inline const_iterator end() const {return const_iterator(this, piv_size);}
|
inline const_iterator end() const {return const_iterator(this, piv_size);}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Returns a reverse iterator to the first element of the reversed vector.
|
||||||
|
//! \~russian Обратный итератор на первый элемент.
|
||||||
|
//! \~\details 
|
||||||
|
//!
|
||||||
|
//! \~english It corresponds to the last element of the non-reversed vector.
|
||||||
|
//! If the vector is empty, the returned iterator is equal to \a rend.
|
||||||
|
//! \~russian Итератор для прохода массива в обратном порядке.
|
||||||
|
//! Указывает на последний элемент.
|
||||||
|
//! Если массив пустой, то совпадает с итератором \a rend.
|
||||||
|
//! \~\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);}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Returns a reverse iterator to the element following the last element of the reversed vector.
|
||||||
|
//! \~russian Обратный итератор на элемент, следующий за последним элементом.
|
||||||
|
//! \~\details 
|
||||||
|
//!
|
||||||
|
//! \~english It corresponds to the element preceding the first element of the non-reversed vector.
|
||||||
|
//! This element acts as a placeholder, attempting to access it results in undefined behavior.
|
||||||
|
//! \~russian Итератор для прохода массива в обратном порядке.
|
||||||
|
//! Указывает на элемент, предшествующий первому элементу.
|
||||||
|
//! Этот элемент существует лишь условно,
|
||||||
|
//! попытка доступа к нему приведёт к выходу за разрешенную память.
|
||||||
|
//! \~\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 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 rend() const {return const_reverse_iterator(this, -1);}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Number of elements in the container.
|
||||||
|
//! \~russian Количество элементов массива.
|
||||||
|
//! \~\sa \a size_s, \a capacity, \a isEmpty, \a isNotEmpty, \a resize, \a reserve
|
||||||
inline size_t size() const {return piv_size;}
|
inline size_t size() const {return piv_size;}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Number of elements in the container as signed value.
|
||||||
|
//! \~russian Количество элементов массива в виде знакового числа.
|
||||||
|
//! \~\sa \a size, \a capacity, \a isEmpty, \a isNotEmpty, \a resize, \a reserve
|
||||||
inline ssize_t size_s() const {return piv_size;}
|
inline ssize_t size_s() const {return piv_size;}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Same as \a size.
|
||||||
|
//! \~russian Синоним \a size.
|
||||||
|
//! \~\sa \a size \a size_s, \a capacity, \a isEmpty, \a isNotEmpty, \a resize, \a reserve
|
||||||
inline size_t length() const {return piv_size;}
|
inline size_t length() const {return piv_size;}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Number of elements that the container has currently allocated space for.
|
||||||
|
//! \~russian Количество элементов, для которого сейчас выделена память контейнером.
|
||||||
|
//! \~\sa \a size \a size_s, \a isEmpty, \a isNotEmpty, \a resize, \a reserve
|
||||||
inline size_t capacity() const {return piv_rsize;}
|
inline size_t capacity() const {return piv_rsize;}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Checks if the container has no elements.
|
||||||
|
//! \~russian Проверяет пуст ли контейнер.
|
||||||
|
//! \~\return
|
||||||
|
//! \~english **true** if the container is empty, **false** otherwise
|
||||||
|
//! \~russian **true** если контейнер пуст, **false** иначе.
|
||||||
|
//! \~\sa \a size \a size_s, \a isEmpty, \a isNotEmpty, \a resize, \a reserve
|
||||||
inline bool isEmpty() const {return (piv_size == 0);}
|
inline bool isEmpty() const {return (piv_size == 0);}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Checks if the container has elements.
|
||||||
|
//! \~russian Проверяет не пуст ли контейнер.
|
||||||
|
//! \~\return
|
||||||
|
//! \~english **true** if the container is not empty, **false** otherwise
|
||||||
|
//! \~russian **true** если контейнер не пуст, **false** иначе.
|
||||||
|
//! \~\sa \a size \a size_s, \a isEmpty, \a isNotEmpty, \a resize, \a reserve
|
||||||
inline bool isNotEmpty() const {return (piv_size > 0);}
|
inline bool isNotEmpty() const {return (piv_size > 0);}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Tests whether at least one element in the array passes the test implemented by the provided function `test`.
|
||||||
|
//! \~russian Проверяет, удовлетворяет ли какой-либо элемент массива условию, заданному в передаваемой функции `test`.
|
||||||
|
//! \~\return
|
||||||
|
//! \~english **true** if, in the array, it finds an element for which the provided function returns **true**;
|
||||||
|
//! otherwise it returns **false**. Always returns **false** if is empty.
|
||||||
|
//! \~russian **true** если хотя бы для одного элемента передаваемая функция возвращает **true**,
|
||||||
|
//! в остальных случаях **false**.
|
||||||
|
//! Метод возвращает **false** при любом условии для пустого массива.
|
||||||
|
//! \~\code
|
||||||
|
//! PIVector<int> v{1, 2, 8, 9};
|
||||||
|
//! piCout << v.any([](int e){return e % 2 == 0;});
|
||||||
|
//! // true
|
||||||
|
//! piCout << v.any([](int e){return e == 3;});
|
||||||
|
//! // false
|
||||||
|
//! \endcode
|
||||||
|
//! \~\sa \a every, \a contains, \a etries, \a forEach
|
||||||
inline bool any(std::function<bool(const T & e)> test) const {
|
inline bool any(std::function<bool(const T & e)> test) const {
|
||||||
for (size_t i = 0; i < piv_size; ++i) {
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
if (test(piv_data[i])) return true;
|
if (test(piv_data[i])) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Tests whether all elements in the array passes the test implemented by the provided function `test`.
|
||||||
|
//! \~russian Проверяет, удовлетворяют ли все элементы массива условию, заданному в передаваемой функции `test`.
|
||||||
|
//! \~\return
|
||||||
|
//! \~english **true** if, in the array, it finds an element for which the provided function returns **true**;
|
||||||
|
//! otherwise it returns **false**. Always returns **true** if is empty.
|
||||||
|
//! \~russian **true** если для всех элементов передаваемая функция возвращает **true**,
|
||||||
|
//! в остальных случаях **false**.
|
||||||
|
//! Метод возвращает **true** при любом условии для пустого массива.
|
||||||
|
//! \~\code
|
||||||
|
//! PIVector<int> v{1, 2, 8, 9};
|
||||||
|
//! piCout << v.every([](int e){return e % 2 == 0;});
|
||||||
|
//! // false
|
||||||
|
//! piCout << v.every([](int e){return e > 0;});
|
||||||
|
//! // true
|
||||||
|
//! \endcode
|
||||||
|
//! \~\sa \a any, \a contains, \a entries, \a forEach
|
||||||
inline bool every(std::function<bool(const T & e)> test) const {
|
inline bool every(std::function<bool(const T & e)> test) const {
|
||||||
for (size_t i = 0; i < piv_size; ++i) {
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
if (!test(piv_data[i])) return false;
|
if (!test(piv_data[i])) return false;
|
||||||
@@ -311,13 +421,69 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \~english Full access to element by `index`.
|
||||||
|
//! \~russian Полный доступ к элементу по индексу `index`.
|
||||||
|
//! \~\details
|
||||||
|
//! \~english Element index starts from `0`.
|
||||||
|
//! Element index must be in range from `0` to `size()-1`.
|
||||||
|
//! Otherwise will be undefined behavior.
|
||||||
|
//! \~russian Индекс элемента считается от `0`.
|
||||||
|
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
||||||
|
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||||
|
//! \~\code
|
||||||
|
//! PIVector<int> v{1, 2, 8, 9};
|
||||||
|
//! piCout << v[2];
|
||||||
|
//! // 8
|
||||||
|
//! v[2] = 5;
|
||||||
|
//! piCout << v;
|
||||||
|
//! // 1, 2, 5, 9
|
||||||
|
//! \endcode
|
||||||
|
//! \~\sa \a at
|
||||||
inline T & operator [](size_t index) {return 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];}
|
inline const T & operator [](size_t index) const {return piv_data[index];}
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \~english Read only access to element by `index`.
|
||||||
|
//! \~russian Доступ исключительно на чтение к элементу по индексу `index`.
|
||||||
|
//! \~\details
|
||||||
|
//! \~english Element index starts from `0`.
|
||||||
|
//! Element index must be in range from `0` to `size()-1`.
|
||||||
|
//! Otherwise will be undefined behavior.
|
||||||
|
//! \~russian Индекс элемента считается от `0`.
|
||||||
|
//! Индекс элемента должен лежать в пределах от `0` до `size()-1`.
|
||||||
|
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||||
inline const T & at(size_t index) const {return piv_data[index];}
|
inline const T & at(size_t index) const {return piv_data[index];}
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \~english Last element.
|
||||||
|
//! \~russian Последний элемент массива.
|
||||||
|
//! \~\details
|
||||||
|
//! \~english Returns a reference to the last item in the vector.
|
||||||
|
//! This function assumes that the vector isn't empty.
|
||||||
|
//! Otherwise will be undefined behavior.
|
||||||
|
//! \~russian Возвращает ссылку на последний элемент в массиве.
|
||||||
|
//! Эта функция предполагает, что массив не пустой.
|
||||||
|
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||||
inline T & back() {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];}
|
inline const T & back() const {return piv_data[piv_size - 1];}
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \~english Last element.
|
||||||
|
//! \~russian Первый элемент массива.
|
||||||
|
//! \~\details
|
||||||
|
//! \~english Returns a reference to the last item in the vector.
|
||||||
|
//! This function assumes that the vector isn't empty.
|
||||||
|
//! Otherwise will be undefined behavior.
|
||||||
|
//! \~russian Возвращает ссылку на пенрвый элемент в массиве.
|
||||||
|
//! Эта функция предполагает, что массив не пустой.
|
||||||
|
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
|
||||||
inline T & front() {return piv_data[0];}
|
inline T & front() {return piv_data[0];}
|
||||||
inline const T & front() const {return piv_data[0];}
|
inline const T & front() const {return piv_data[0];}
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \~english Compare operator with vector `t`.
|
||||||
|
//! \~russian Оператор сравнения с массивом `t`.
|
||||||
inline bool operator ==(const PIVector<T> & t) const {
|
inline bool operator ==(const PIVector<T> & t) const {
|
||||||
if (piv_size != t.piv_size) {
|
if (piv_size != t.piv_size) {
|
||||||
return false;
|
return false;
|
||||||
@@ -329,7 +495,12 @@ public:
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \brief
|
||||||
|
//! \~english Compare operator with vector `t`.
|
||||||
|
//! \~russian Оператор сравнения с массивом `t`.
|
||||||
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);}
|
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);}
|
||||||
|
|
||||||
inline bool operator <(const PIVector<T> & t) const {
|
inline bool operator <(const PIVector<T> & t) const {
|
||||||
if (piv_size != t.piv_size) return piv_size < t.piv_size;
|
if (piv_size != t.piv_size) return piv_size < t.piv_size;
|
||||||
for (size_t i = 0; i < piv_size; ++i) {
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
@@ -344,6 +515,21 @@ public:
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Tests if element `e` exists in the array.
|
||||||
|
//! \~russian Проверяет наличие элемента `e` в массиве.
|
||||||
|
//! \~\return
|
||||||
|
//! \~english **true** if the array contains an occurrence of element `e`,
|
||||||
|
//! otherwise it returns **false**.
|
||||||
|
//! \~russian **true** если элемент `e` присутствует в массиве,
|
||||||
|
//! в остальных случаях **false**.
|
||||||
|
//! \~\code
|
||||||
|
//! PIVector<int> v{1, 2, 3, 4};
|
||||||
|
//! piCout << v.contains(3);
|
||||||
|
//! // true
|
||||||
|
//! \endcode
|
||||||
|
//! \~\sa \a every, \a any, \a etries, \a forEach
|
||||||
inline bool contains(const T & e) const {
|
inline bool contains(const T & e) const {
|
||||||
for (size_t i = 0; i < piv_size; ++i) {
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
if (e == piv_data[i]) {
|
if (e == piv_data[i]) {
|
||||||
@@ -352,7 +538,8 @@ public:
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline int etries(const T & e, size_t start = 0) const {
|
|
||||||
|
inline int entries(const T & e, size_t start = 0) const {
|
||||||
int ec = 0;
|
int ec = 0;
|
||||||
if (start >= piv_size) return ec;
|
if (start >= piv_size) return ec;
|
||||||
for (size_t i = start; i < piv_size; ++i) {
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
@@ -360,7 +547,8 @@ public:
|
|||||||
}
|
}
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
inline int etries(std::function<bool(const T & e)> test, size_t start = 0) const {
|
|
||||||
|
inline int entries(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
int ec = 0;
|
int ec = 0;
|
||||||
if (start >= piv_size) return ec;
|
if (start >= piv_size) return ec;
|
||||||
for (size_t i = start; i < piv_size; ++i) {
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
@@ -368,6 +556,7 @@ public:
|
|||||||
}
|
}
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ssize_t indexOf(const T & e, size_t start = 0) const {
|
inline ssize_t indexOf(const T & e, size_t start = 0) const {
|
||||||
if (start >= piv_size) return -1;
|
if (start >= piv_size) return -1;
|
||||||
for (size_t i = start; i < piv_size; ++i) {
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
@@ -377,6 +566,7 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ssize_t indexWhere(std::function<bool(const T & e)> test, size_t start = 0) const {
|
inline ssize_t indexWhere(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
if (start >= piv_size) return -1;
|
if (start >= piv_size) return -1;
|
||||||
for (size_t i = start; i < piv_size; ++i) {
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
@@ -386,6 +576,7 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
||||||
if (start < 0) start = piv_size - 1;
|
if (start < 0) start = piv_size - 1;
|
||||||
else start = piMin<ssize_t>(piv_size - 1, start);
|
else start = piMin<ssize_t>(piv_size - 1, start);
|
||||||
@@ -396,6 +587,7 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
||||||
if (start < 0) start = piv_size - 1;
|
if (start < 0) start = piv_size - 1;
|
||||||
else start = piMin<ssize_t>(piv_size - 1, start);
|
else start = piMin<ssize_t>(piv_size - 1, start);
|
||||||
@@ -448,6 +640,7 @@ public:
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
inline PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
||||||
template<typename T1 = T, typename std::enable_if<
|
template<typename T1 = T, typename std::enable_if<
|
||||||
!std::is_trivially_copyable<T1>::value
|
!std::is_trivially_copyable<T1>::value
|
||||||
@@ -480,6 +673,7 @@ public:
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIVector<T> & resize(size_t new_size, std::function<T(size_t i)> f) {
|
inline PIVector<T> & resize(size_t new_size, std::function<T(size_t i)> f) {
|
||||||
if (new_size < piv_size) {
|
if (new_size < piv_size) {
|
||||||
T * de = &(piv_data[new_size]);
|
T * de = &(piv_data[new_size]);
|
||||||
@@ -496,6 +690,7 @@ public:
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T1 = T, typename std::enable_if<
|
template<typename T1 = T, typename std::enable_if<
|
||||||
std::is_trivially_copyable<T1>::value
|
std::is_trivially_copyable<T1>::value
|
||||||
, int>::type = 0>
|
, int>::type = 0>
|
||||||
|
|||||||
32
main.cpp
32
main.cpp
@@ -2,30 +2,12 @@
|
|||||||
|
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
PIThreadNotifier n;
|
PIVector <int> v(5, [](size_t i){return i*2;});
|
||||||
int cnt1 = 0;
|
v.prepend({1, 2, 3});
|
||||||
int cnt2 = 0;
|
piCout << v;
|
||||||
int cnt3 = 0;
|
piCout << v.reduce<int>([](int v, int s){return v+s;});
|
||||||
PIThread t1([&n, &cnt1](){n.wait(); cnt1++; piMSleep(1);}, true);
|
piCout << v.reduce<PIString>([](int v, PIString s){return s+PIString::fromNumber(v);});
|
||||||
PIThread t2([&n, &cnt2](){n.wait(); cnt2++; piMSleep(2);}, true);
|
PIStringList sl = v.map<PIString>([](int v){return PIString::fromNumber(v);});
|
||||||
piCout << "created";
|
piCout << sl;
|
||||||
piMSleep(10);
|
|
||||||
piCout << "unlock" << cnt1 << cnt2 << cnt3;
|
|
||||||
n.notifyOnce(); cnt3++;
|
|
||||||
piMSleep(10);
|
|
||||||
piCout << "unlock" << cnt1 << cnt2 << cnt3;
|
|
||||||
n.notifyOnce(); cnt3++;
|
|
||||||
piMSleep(10);
|
|
||||||
piCout << "run" << cnt1 << cnt2 << cnt3;
|
|
||||||
PIThread t3([&n, &cnt3](){n.notifyOnce(); cnt3++; piMSleep(1);}, true);
|
|
||||||
piMSleep(20);
|
|
||||||
t3.stop();
|
|
||||||
piMSleep(100);
|
|
||||||
piCout << "exit" << cnt1 << cnt2 << cnt3;
|
|
||||||
PIByteArray ba = PIByteArray::fromHex("00aabbcc");
|
|
||||||
PIByteArray ba2 = ba.getRange(1, 2);
|
|
||||||
piCout << ba2.toHex();
|
|
||||||
// m.unlock();
|
|
||||||
// piMSleep(10);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user