Files
pip/libs/main/containers/picontainers.h

259 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \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
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 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/>.
*/
#ifndef PICONTAINERS_H
#define PICONTAINERS_H
#include "picout.h"
#include "piintrospection_containers.h"
#ifdef MAC_OS
# include <stdlib.h>
#else
# include <malloc.h>
#endif
#include <algorithm>
#include <functional>
#include <initializer_list>
#include <new>
#include <string.h>
#include <type_traits>
//! \~english Reverse wrapper template class for iterating containers in reverse order.
//! \~russian Класс-обертка для обратного обхода контейнера через итераторы.
template<typename C>
class _PIReverseWrapper {
public:
//! \~english Constructor from non-const container reference.
//! \~russian Конструктор из неконстантной ссылки на контейнер.
_PIReverseWrapper(C & c): c_(c) {}
//! \~english Constructor from const container reference.
//! \~russian Конструктор из константной ссылки на контейнер.
_PIReverseWrapper(const C & c): c_(const_cast<C &>(c)) {}
//! \~english Returns reverse iterator to the first element.
//! \~russian Возвращает обратный итератор на первый элемент.
typename C::reverse_iterator begin() { return c_.rbegin(); }
//! \~english Returns reverse iterator past the last element.
//! \~russian Возвращает обратный итератор за последний элемент.
typename C::reverse_iterator end() { return c_.rend(); }
//! \~english Returns const reverse iterator to the first element.
//! \~russian Возвращает константный обратный итератор на первый элемент.
typename C::const_reverse_iterator begin() const { return c_.rbegin(); }
//! \~english Returns const reverse iterator past the last element.
//! \~russian Возвращает константный обратный итератор за последний элемент.
typename C::const_reverse_iterator end() const { return c_.rend(); }
private:
C & c_;
};
//! \~english Base class for container constants calculation.
//! \~russian Базовый класс для вычисления констант контейнера.
class PIP_EXPORT _PIContainerConstantsBase {
public:
//! \~english Calculate minimum elements count for power of two growth.
//! \~russian Вычисляет минимальное количество элементов для роста кратного двум.
static size_t calcMinCountPoT(size_t szof);
//! \~english Calculate maximum elements count for power of two growth.
//! \~russian Вычисляет максимальное количество элементов для роста кратного двум.
static size_t calcMaxCountForPoT(size_t szof);
//! \~english Calculate step size after power of two growth.
//! \~russian Вычисляет размер шага после роста кратного двум.
static size_t calcStepAfterPoT(size_t szof);
};
//! \~english Template class for container constants based on element type size.
//! \~russian Шаблонный класс для констант контейнера на основе размера типа элемента.
template<typename T>
class _PIContainerConstants {
public:
//! \~english Get minimum elements count for power of two growth.
//! \~russian Возвращает минимальное количество элементов для роста кратного двум.
static size_t minCountPoT() {
static const size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T));
return ret;
}
//! \~english Get maximum elements count for power of two growth.
//! \~russian Возвращает максимальное количество элементов для роста кратного двум.
static size_t maxCountForPoT() {
static const size_t ret = _PIContainerConstantsBase::calcMaxCountForPoT(sizeof(T));
return ret;
}
//! \~english Get step size after power of two growth.
//! \~russian Возвращает размер шага после роста кратного двум.
static size_t stepAfterPoT() {
static const size_t ret = _PIContainerConstantsBase::calcStepAfterPoT(sizeof(T));
return ret;
}
//! \~english Calculate new container size based on old and requested size.
//! \~russian Вычисляет новый размер контейнера на основе старого и запрошенного размера.
static size_t calcNewSize(size_t old_size, size_t new_size) {
if (new_size == 0) return 0;
if (new_size < maxCountForPoT()) {
if (old_size * 2 >= new_size && old_size < new_size) {
return old_size * 2;
}
ssize_t t = minCountPoT();
new_size -= 1;
while (new_size >> t)
++t;
return (1 << t);
} else {
size_t ret = old_size;
while (ret < new_size)
ret += stepAfterPoT();
return ret;
}
return 0;
}
};
//! \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 Количество итераций цикла
#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
#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
#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
#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
#define piForeachRC(i, c) for (const i: PIReverseWrap(c))
#define piForeachCR piForeachRC
//! \~\brief
//! \~english Reshape order enum for reshape() function.
//! \~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 Обход элементов по столбцам */,
};
#endif // PICONTAINERS_H