//! \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 . */ #ifndef PICONTAINERS_H #define PICONTAINERS_H #include "picout.h" #include "piintrospection_containers.h" #ifdef MAC_OS # include #else # include #endif #include #include #include #include #include #include //! \~english Reverse wrapper template class for iterating containers in reverse order. //! \~russian Класс-обертка для обратного обхода контейнера через итераторы. template 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)) {} //! \~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 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 _PIReverseWrapper PIReverseWrap(C & c) { return _PIReverseWrapper(c); } template _PIReverseWrapper PIReverseWrap(const C & c) { return _PIReverseWrapper(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 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