picontainers doc, PIVector doc

This commit is contained in:
Andrey
2022-03-30 17:32:34 +03:00
parent c2ceb710c5
commit 42fd417e34
3 changed files with 349 additions and 187 deletions

View File

@@ -1,17 +1,17 @@
/*! \addtogroup Containers
* \{
* \file picontainers.h
* \brief
* \~english Base macros for generic containers
* \~russian Базовые макросы для контейнеров
* \~\authors
* \~english
* Ivan Pelipenko peri4ko@yandex.ru;
* Andrey Bychkov work.a.b@yandex.ru;
* \~russian
* Иван Пелипенко peri4ko@yandex.ru;
* Андрей Бычков work.a.b@yandex.ru;
* \~\} */
//! \addtogroup Containers
//! \{
//! \file picontainers.h
//! \brief
//! \~english Base macros for generic containers
//! \~russian Базовые макросы для контейнеров
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
//! \~\}
/*
PIP - Platform Independent Primitives
Base macros for generic containers
@@ -61,105 +61,99 @@ private:
};
/*! \brief
* \~english Template reverse wrapper over any container
* \~russian Шаблонная функция обертки любого контейнера для обратного доступа через итераторы
*/
//! \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);}
/*! \brief
* \~english Macro for short replacement of standart "for"
* \~russian Макрос для короткой записи стандартного цикла "for"
* \~\param c
* \~english Iteration times in loop
* \~russian Количество итераций цикла
*/
//! \brief
//! \~english Macro for short replacement of standart "for"
//! \~russian Макрос для короткой записи стандартного цикла "for"
//! \~\param c
//! \~english Iteration times in loop
//! \~russian Количество итераций цикла
#define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c)
/*! \brief
* \~english Macro for iterate any container
* \~russian Макрос для перебора любых контейнеров
* \~\deprecated
* \~english Deprecated, using only for backward compatibility. Use
* [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
* \~russian Устарело, используется только для обратной совместимости. Используйте
* [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
* \~\details
* \~english Get read/write access to each element of container.
* Iterating in forward direction.
* Example of using:
* \~russian Перебор всех элементов контейнера с доступом на чтение и запись.
* Перебор осуществляется в прямом порядке.
* Пример использования:
* \~\code
* PIVector<int> vec;
* vec << 1 << 2 << 3;
* piForeach(int & i, vec) piCout << i;
* // 1
* // 2
* // 3
* piForeach(int & i, vec) i++;
* piForeach(int & i, vec) piCout << i;
* // 2
* // 3
* // 4
* \endcode
* \sa \a piForeachC, \a piForeachR, \a piForeachRC
*/
//! \brief
//! \~english Macro for iterate any container
//! \~russian Макрос для перебора любых контейнеров
//! \~\deprecated
//! \~english Deprecated, using only for backward compatibility. Use
//! [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
//! \~russian Устарело, используется только для обратной совместимости. Используйте
//! [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
//! \~\details
//! \~english Get read/write access to each element of container.
//! Iterating in forward direction.
//! Example of using:
//! \~russian Перебор всех элементов контейнера с доступом на чтение и запись.
//! Перебор осуществляется в прямом порядке.
//! Пример использования:
//! \~\code
//! PIVector<int> vec;
//! vec << 1 << 2 << 3;
//! piForeach(int & i, vec) piCout << i;
//! // 1
//! // 2
//! // 3
//! piForeach(int & i, vec) i++;
//! piForeach(int & i, vec) piCout << i;
//! // 2
//! // 3
//! // 4
//! \endcode
//! \sa \a piForeachC, \a piForeachR, \a piForeachRC
#define piForeach(i, c) for(i : c)
/*! \brief
* \~english Macro for iterate any container
* \~russian Макрос для перебора любых контейнеров
* \~\deprecated
* \~english Deprecated, using only for backward compatibility. Use
* [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
* \~russian Устарело, используется только для обратной совместимости. Используйте
* [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
* \~\details
* \~english Get read only access to each element of container.
* Iterating in forward direction.
* \~russian Перебор всех элементов контейнера с доступом только на чтение.
* Перебор осуществляется в прямом порядке.
* \~ \sa \a piForeach, \a piForeachR, \a piForeachRC
*/
//! \brief
//! \~english Macro for iterate any container
//! \~russian Макрос для перебора любых контейнеров
//! \~\deprecated
//! \~english Deprecated, using only for backward compatibility. Use
//! [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
//! \~russian Устарело, используется только для обратной совместимости. Используйте
//! [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
//! \~\details
//! \~english Get read only access to each element of container.
//! Iterating in forward direction.
//! \~russian Перебор всех элементов контейнера с доступом только на чтение.
//! Перебор осуществляется в прямом порядке.
//! \~ \sa \a piForeach, \a piForeachR, \a piForeachRC
#define piForeachC(i, c) for(const i : c)
/*! \brief
* \~english Macro for iterate any container
* \~russian Макрос для перебора любых контейнеров
* \~\deprecated
* \~english Deprecated, using only for backward compatibility. Use
* [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
* \~russian Устарело, используется только для обратной совместимости. Используйте
* [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
* \~\details
* \~english Get read/write access to each element of container.
* Iterating in backward direction.
* \~russian Перебор всех элементов контейнера с доступом на чтение и запись.
* Перебор осуществляется в обратном порядке.
* \~ \sa \a piForeach, \a piForeachC, \a piForeachRC
*/
//! \brief
//! \~english Macro for iterate any container
//! \~russian Макрос для перебора любых контейнеров
//! \~\deprecated
//! \~english Deprecated, using only for backward compatibility. Use
//! [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
//! \~russian Устарело, используется только для обратной совместимости. Используйте
//! [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
//! \~\details
//! \~english Get read/write access to each element of container.
//! Iterating in backward direction.
//! \~russian Перебор всех элементов контейнера с доступом на чтение и запись.
//! Перебор осуществляется в обратном порядке.
//! \~ \sa \a piForeach, \a piForeachC, \a piForeachRC
#define piForeachR(i, c) for(i : PIReverseWrap(c))
/*! \brief
* \~english Macro for iterate any container
* \~russian Макрос для перебора любых контейнеров
* \~\deprecated
* \~english Deprecated, using only for backward compatibility. Use
* [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
* \~russian Устарело, используется только для обратной совместимости. Используйте
* [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
* \~\details
* \~english Get read only access to each element of container.
* Iterating in backward direction. Also has alias **piForeachCR**
* \~russian Перебор всех элементов контейнера с доступом только на чтение.
* Перебор осуществляется в обратном порядке. Также можно писать **piForeachCR**
* \~ \sa \a piForeach, \a piForeachC, \a piForeachR
*/
//! \brief
//! \~english Macro for iterate any container
//! \~russian Макрос для перебора любых контейнеров
//! \~\deprecated
//! \~english Deprecated, using only for backward compatibility. Use
//! [C++ Range-based for loop](https://en.cppreference.com/w/cpp/language/range-for).
//! \~russian Устарело, используется только для обратной совместимости. Используйте
//! [C++ Range-based for loop](https://ru.cppreference.com/w/cpp/language/range-for).
//! \~\details
//! \~english Get read only access to each element of container.
//! Iterating in backward direction. Also has alias **piForeachCR**
//! \~russian Перебор всех элементов контейнера с доступом только на чтение.
//! Перебор осуществляется в обратном порядке. Также можно писать **piForeachCR**
//! \~ \sa \a piForeach, \a piForeachC, \a piForeachR
#define piForeachRC(i, c) for(const i : PIReverseWrap(c))
#define piForeachCR piForeachRC

View File

@@ -16,30 +16,139 @@
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
* \~\brief
* \~english This module contains various standart containers realization.
* \~russian Модуль содержит основные классы контейнеров.
*
* \~\details
* Scope | Use
* ----- | -------
* C++ | #include <picontainersmodule.h>
* CMake | PIP
*
* \~english This includes
* \~russian В него входят
* \~ \a PIVector, \a PIDeque, \a PIMap, \a PISet,
* \a PIStack, \a PIQueue, \a PIPair, \a PIVector2D.
*
* \authors
* \~english
* Ivan Pelipenko peri4ko@yandex.ru;
* Andrey Bychkov work.a.b@yandex.ru;
* \~russian
* Иван Пелипенко peri4ko@yandex.ru;
* Андрей Бычков work.a.b@yandex.ru;
*/
//! \defgroup Containers
//! \~\brief
//! \~english This module contains various standart containers realization.
//! \~russian Модуль содержит основные классы контейнеров.
//! \~\details
//! Scope | Use
//! ----- | -------
//! C++ | `#include <picontainersmodule.h>`
//! CMake | PIP
//!
//! \~english This includes
//! \~russian В него входят
//! \~ \a PIVector, \a PIDeque, \a PIMap, \a PISet,
//! \a PIStack, \a PIQueue, \a PIPair, \a PIVector2D.
//!
//! \~english \section stl_iterators STL-Style Iterators
//! \~russian \section stl_iterators Итераторы в стиле STL
//! \~\addindex stl_iterators
//! \~english
//! \brief They are compatible with Qt's and STL's generic algorithms and are optimized for speed.
//! \details
//! For each container class, there are two STL-style iterator types:
//! one that provides read-only access and one that provides read-write access.
//! Read-only iterators should be used wherever possible
//! because they are faster than read-write iterators.
//! Read-only iterator - `const_iterator.`
//! Read-write iterator - `iterator.`
//!
//! The API of the STL iterators is modelled on pointers in an array.
//! For example, the `++` operator advances the iterator to the next item,
//! and the `*` operator returns the item that the iterator points to.
//! The `iterator` type is just a `typedef` for `T *`,
//! and the `const_iterator` type is just a `typedef` for `const T *`.
//! STL-style iterators point directly at items.
//! The `begin()` function of a container
//! returns an iterator that points to the first item in the container.
//! The `end()` function of a container returns an iterator to the imaginary item
//! one position past the last item in the container.
//! `end()` marks an invalid position; it must never be dereferenced.
//! It is typically used in a loop's break condition.
//!
//! Example:
//! \code
//! for (PIVector<int>::const_iterator i = v.begin(); i != v.end(); ++i) piCout << *i;
//! std::for_each(v.begin(), v.end(), [](int n){std::cout << n << ' ';});
//! \endcode
//!
//! If the list is empty, `begin()` equals `end()`, so we never execute the loop.
//!
//! ![iterators](doc/images/pivector_rbegin.png)
//!
//! The following table summarizes the STL-style iterators' API:
//! Expression | Behavior
//! ---------- | --------------------
//! `*i` | Returns the current item
//! `++i` | Advances the iterator to the next item
//! `i += n` | Advances the iterator by `n` items
//! `--i` | Moves the iterator back by one item
//! `i -= n` | Moves the iterator back by `n` items
//! `i - j` | Returns the number of items between iterators `i` and `j`
//!
//! The `++` and `--` operators are available both as prefix `(++i, --i)`
//! and postfix `(i++, i--)` operators.
//! The prefix versions modify the iterators
//! and return a reference to the modified iterator;
//! the postfix versions take a copy of the iterator before they modify it, and return that copy.
//! In expressions where the return value is ignored,
//! we recommend that you use the prefix operators `(++i, --i)`, as these are slightly faster.
//! For non-const iterator types, the return value of the unary `*` operator
//! can be used on the left side of the assignment operator.
//!
//! \~russian
//! \brief Они совместимы с базовыми алгоритмами Qt и STL и оптимизированы по скорости.
//! \details
//! Для каждого контейнерного класса есть два типа итераторов в стиле STL:
//! один из них предоставляет доступ только для чтения, а другой - доступ для чтения-записи.
//! Итераторы только для чтения должны использоваться везде, где это только возможно,
//! так как они быстрее, чем итераторы для чтения-записи.
//! Итератор только для чтения - `const_iterator.`
//! Итератор для чтения-записи - `iterator.`
//!
//! API итераторов в стиле STL сделан по образцу указателей в массиве.
//! Например, оператор `++` перемещает итератор к следующему элементу,
//! а оператор `*` возвращает элемент, на который позиционирован итератор.
//! Тип `iterator` - это как `typedef` для `T *`,
//! а тип `const_iterator` - как `typedef` для `const T *`.
//! Итераторы в стиле STL указывают непосредственно на элемент.
//! Функция контейнера `begin()` возвращает итератор, указывающий на первый элемент контейнера.
//! Функция контейнера `end()` возвращает итератор, указывающий на воображаемый элемент,
//! находящийся в позиции, следующей за последним элементом контейнера.
//! `end()` обозначает несуществующую позицию;
//! он никогда не должен разыменовываться.
//! Обычно, он используется, как условие выхода из цикла.
//!
//! Например:
//! \code
//! for (PIVector<int>::const_iterator i = v.begin(); i != v.end(); ++i) piCout << *i;
//! std::for_each(v.begin(), v.end(), [](int n){std::cout << n << ' ';});
//! \endcode
//!
//! Если список пуст, то begin() равен end(), поэтому цикл никогда не выполнится.
//!
//! ![итераторы](doc/images/pivector_rbegin.png)
//!
//! В следующей таблице подводится итог API итераторов в стиле STL:
//! Выражение | Поведение
//! --------- | --------------------
//! `*i` | Возвращает текущий элемент
//! `++i` | Перемещает итератор к следующему элементу
//! `i += n` | Перемещает итератор вперед на `n` элементов
//! `--i` | Перемещает итератор на один элемент назад
//! `i -= n` | Перемещает итератор назад на `n` элементов
//! `i - j` | Возвращает количество элементов, находящихся между итераторами `i` и `j`
//!
//! Оба оператора `++` и `--` могут использоваться и как префиксные `(++i, --i)`
//! и как постфиксные `(i++, i--)` операторы.
//! Префиксная версия изменяет итератор, и возвращает ссылку на измененный итератор;
//! постфиксная версия, берет копию итератора перед его изменением, и возвращает эту копию.
//! В выражениях, в которых возвращаемое значение игнорируется,
//! мы рекомендуем использовать префиксную версию `(++i, --i)`,
//! так как она несколько быстрее.
//!
//! Для неконстантных итераторов, возвращаемое значение унарного оператора `*`
//! может быть использовано с левой стороны от оператора присваивания.
//!
//! \authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
#ifndef PICONTAINERSMODULE_H
#define PICONTAINERSMODULE_H
@@ -52,4 +161,5 @@
#include "pistack.h"
#include "pivector2d.h"
#endif // PICONTAINERSMODULE_H

View File

@@ -11,7 +11,7 @@
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
//! \~\} */
//! \~\}
/*
PIP - Platform Independent Primitives
Sequence linear container aka dynamic size array of any type
@@ -130,8 +130,7 @@ public:
//! \~\details
//! \~\code
//! PIVector <int> v{1,2,3};
//! piCout << v;
//! // {1, 2, 3}
//! piCout << v; // {1, 2, 3}
//! \endcode
inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
@@ -155,8 +154,7 @@ public:
//! \~russian Позволяет передавать [Лямбда-выражения](https://ru.cppreference.com/w/cpp/language/lambda) для создания элементов в конструкторе.
//! \~\code
//! PIVector <int> v(5, [](size_t i){return i*2;});
//! piCout << v;
//! // {0, 2, 4, 6, 8}
//! piCout << v; // {0, 2, 4, 6, 8}
//! \endcode
inline PIVector(size_t size, std::function<T(size_t i)> f): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
@@ -284,6 +282,7 @@ public:
//!
//! \~english If the vector is empty, the returned iterator is equal to \a end.
//! \~russian Если массив - пуст, возвращаемый итератор будет равен \a end.
//! \~\return \ref stl_iterators
//! \~\sa \a end, \a rbegin, \a rend
inline iterator begin() {return iterator(this, 0);}
@@ -292,9 +291,11 @@ public:
//! \~russian Итератор на элемент, следующий за последним элементом.
//! \~\details ![begin, end](doc/images/pivector_begin.png)
//!
//! \~english This element acts as a placeholder; attempting to access it results in undefined behavior.
//! \~english This element acts as a placeholder;
//! attempting to access it results in undefined behavior.
//! \~russian Этот элемент существует лишь условно,
//! попытка доступа к нему приведёт к выходу за разрешенную память.
//! \~\return \ref stl_iterators
//! \~\sa \a begin, \a rbegin, \a rend
inline iterator end() {return iterator(this, piv_size);}
@@ -311,6 +312,7 @@ public:
//! \~russian Итератор для прохода массива в обратном порядке.
//! Указывает на последний элемент.
//! Если массив пустой, то совпадает с итератором \a rend.
//! \~\return \ref stl_iterators
//! \~\sa \a rend, \a begin, \a end
inline reverse_iterator rbegin() {return reverse_iterator(this, piv_size - 1);}
@@ -325,6 +327,7 @@ public:
//! Указывает на элемент, предшествующий первому элементу.
//! Этот элемент существует лишь условно,
//! попытка доступа к нему приведёт к выходу за разрешенную память.
//! \~\return \ref stl_iterators
//! \~\sa \a rbegin, \a begin, \a end
inline reverse_iterator rend() {return reverse_iterator(this, -1);}
@@ -382,12 +385,11 @@ public:
//! \~russian **true** если хотя бы для одного элемента передаваемая функция возвращает **true**,
//! в остальных случаях **false**.
//! Метод возвращает **false** при любом условии для пустого массива.
//! \~\details
//! \~\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
//! 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 {
@@ -406,12 +408,11 @@ public:
//! \~russian **true** если для всех элементов передаваемая функция возвращает **true**,
//! в остальных случаях **false**.
//! Метод возвращает **true** при любом условии для пустого массива.
//! \~\details
//! \~\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
//! 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 {
@@ -433,11 +434,9 @@ public:
//! Иначе это приведёт к неопределённому поведению программы и ошибкам памяти.
//! \~\code
//! PIVector<int> v{1, 2, 8, 9};
//! piCout << v[2];
//! // 8
//! piCout << v[2]; // 8
//! v[2] = 5;
//! piCout << v;
//! // 1, 2, 5, 9
//! piCout << v; // 1, 2, 5, 9
//! \endcode
//! \~\sa \a at
inline T & operator [](size_t index) {return piv_data[index];}
@@ -501,78 +500,141 @@ public:
//! \~russian Оператор сравнения с массивом `t`.
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);}
inline bool operator <(const PIVector<T> & t) const {
if (piv_size != t.piv_size) return piv_size < t.piv_size;
for (size_t i = 0; i < piv_size; ++i) {
if ((*this)[i] != t[i]) return (*this)[i] < t[i];
}
return false;
}
inline bool operator >(const PIVector<T> & t) const {
if (piv_size != t.piv_size) return piv_size > t.piv_size;
for (size_t i = 0; i < piv_size; ++i) {
if ((*this)[i] != t[i]) return (*this)[i] > t[i];
}
return false;
}
//! \~\brief
//! \~english Tests if element `e` exists in the array.
//! \~russian Проверяет наличие элемента `e` в массиве.
//! \~\details
//! \~english Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! **false** is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается **false**, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\code
//! PIVector<int> v{1, 2, 3, 4};
//! piCout << v.contains(3); // true
//! piCout << v.contains(5); // false
//! piCout << v.contains(3, 3); // false
//! piCout << v.contains(3, -2); // true
//! piCout << v.contains(3, -99); // true
//! \endcode
//! \~\return
//! \~english **true** if the array contains an occurrence of element `e`,
//! otherwise it returns **false**.
//! \~russian **true** если элемент `e` присутствует в массиве,
//! в остальных случаях **false**.
//! \~\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 {
for (size_t i = 0; i < piv_size; ++i) {
if (e == piv_data[i]) {
return true;
}
inline bool contains(const T & e, ssize_t start = 0) const {
if (start < 0) {
start = piv_size + start;
if (start < 0) start = 0;
}
for (size_t i = start; i < piv_size; ++i) {
if (e == piv_data[i]) return true;
}
return false;
}
inline int entries(const T & e, size_t start = 0) const {
//! \~\brief
//! \~english Count elements equal `e` in the array.
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
//! \~\details
//! \~english Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! 0 is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается 0, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\code
//! PIVector<int> v{2, 2, 4, 2, 6};
//! piCout << v.entries(2); // 3
//! piCout << v.entries(2, 2); // 1
//! piCout << v.entries(2, -4); // 2
//! \endcode
//! \~\sa \a every, \a any, \a contains, \a forEach
inline int entries(const T & e, ssize_t start = 0) const {
int ec = 0;
if (start >= piv_size) return ec;
if (start < 0) {
start = piv_size + start;
if (start < 0) start = 0;
}
for (size_t i = start; i < piv_size; ++i) {
if (e == piv_data[i]) ++ec;
}
return ec;
}
inline int entries(std::function<bool(const T & e)> test, size_t start = 0) const {
//! \~\brief
//! \~english Count elements in the array passes the test implemented by the provided function `test`.
//! \~russian Подсчитывает количество элементов в массиве, проходящих по условию, заданному в передаваемой функции `test`.
//! \~\details
//! \~english Overloaded function.
//! Optional argument `start` - the position in this array at which to begin searching.
//! If the index is greater than or equal to the array's size,
//! 0 is returned, which means the array will not be searched.
//! If the provided index value is a negative number,
//! it is taken as the offset from the end of the array.
//! Note: if the provided index is negative,
//! the array is still searched from front to back.
//! Default: 0 (entire array is searched).
//! \~russian Перегруженная функция.
//! Опциональный аргумент `start` указывает на индекс в массиве, откуда будет начинаться поиск.
//! Если индекс больше или равен длине массива,
//! возвращается 0, что означает, что массив даже не просматривается.
//! Если индекс является отрицательным числом, он трактуется как смещение с конца массива.
//! Если рассчитанный индекс все равно оказывается меньше 0, просматривается весь массив.
//! Обратите внимание: если индекс отрицателен, массив всё равно просматривается от начала к концу.
//! Значение по умолчанию равно 0, что означает, что просматривается весь массив.
//! \~\sa \a every, \a any, \a contains, \a forEach
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
int ec = 0;
if (start >= piv_size) return ec;
if (start < 0) {
start = piv_size + start;
if (start < 0) start = 0;
}
for (size_t i = start; i < piv_size; ++i) {
if (test(piv_data[i])) ++ec;
}
return ec;
}
inline ssize_t indexOf(const T & e, size_t start = 0) const {
if (start >= piv_size) return -1;
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
if (start < 0) {
start = piv_size + start;
if (start < 0) start = 0;
}
for (size_t i = start; i < piv_size; ++i) {
if (e == piv_data[i]) {
return i;
}
if (e == piv_data[i]) return i;
}
return -1;
}
inline ssize_t indexWhere(std::function<bool(const T & e)> test, size_t start = 0) const {
if (start >= piv_size) return -1;
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) {
start = piv_size + start;
if (start < 0) start = 0;
}
for (size_t i = start; i < piv_size; ++i) {
if (test(piv_data[i])) {
return i;
}
if (test(piv_data[i])) return i;
}
return -1;
}
@@ -581,9 +643,7 @@ public:
if (start < 0) start = piv_size - 1;
else start = piMin<ssize_t>(piv_size - 1, start);
for (ssize_t i = start; i >= 0; --i) {
if (e == piv_data[i]) {
return i;
}
if (e == piv_data[i]) return i;
}
return -1;
}
@@ -592,9 +652,7 @@ public:
if (start < 0) start = piv_size - 1;
else start = piMin<ssize_t>(piv_size - 1, start);
for (ssize_t i = start; i >= 0; --i) {
if (test(piv_data[i])) {
return i;
}
if (test(piv_data[i])) return i;
}
return -1;
}