PIVector doc

This commit is contained in:
Andrey
2022-03-29 12:39:37 +03:00
parent 7a9c3f72ca
commit 9f1ae76d1e
4 changed files with 171 additions and 116 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -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,68 @@
#include "picontainers.h" #include "picontainers.h"
/*! \addtogroup Containers //! \addtogroup Containers
* \{ //! \{
* \class PIVector pivector.h //! \class PIVector pivector.h
* \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)
*/
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 +114,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,13 +123,9 @@ 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;
@@ -167,16 +162,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 +178,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 +190,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,21 +275,102 @@ 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 ![begin, end](doc/images/pivector_begin.png)
//!
//! \~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 ![begin, end](doc/images/pivector_begin.png)
//!
//! \~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 ![rbegin, rend](doc/images/pivector_rbegin.png)
//!
//! \~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 ![rbegin, rend](doc/images/pivector_rbegin.png)
//!
//! \~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 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);}
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;

View File

@@ -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;
} }