224 lines
8.4 KiB
C++
224 lines
8.4 KiB
C++
//! \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>
|
|
|
|
|
|
template<typename C>
|
|
class _PIReverseWrapper {
|
|
public:
|
|
_PIReverseWrapper(C & c): c_(c) {}
|
|
_PIReverseWrapper(const C & c): c_(const_cast<C &>(c)) {}
|
|
typename C::reverse_iterator begin() { return c_.rbegin(); }
|
|
typename C::reverse_iterator end() { return c_.rend(); }
|
|
typename C::const_reverse_iterator begin() const { return c_.rbegin(); }
|
|
typename C::const_reverse_iterator end() const { return c_.rend(); }
|
|
|
|
private:
|
|
C & c_;
|
|
};
|
|
|
|
|
|
class PIP_EXPORT _PIContainerConstantsBase {
|
|
public:
|
|
static size_t calcMinCountPoT(size_t szof);
|
|
static size_t calcMaxCountForPoT(size_t szof);
|
|
static size_t calcStepAfterPoT(size_t szof);
|
|
};
|
|
|
|
template<typename T>
|
|
class _PIContainerConstants {
|
|
public:
|
|
static size_t minCountPoT() {
|
|
static const size_t ret = _PIContainerConstantsBase::calcMinCountPoT(sizeof(T));
|
|
return ret;
|
|
}
|
|
static size_t maxCountForPoT() {
|
|
static const size_t ret = _PIContainerConstantsBase::calcMaxCountForPoT(sizeof(T));
|
|
return ret;
|
|
}
|
|
static size_t stepAfterPoT() {
|
|
static const size_t ret = _PIContainerConstantsBase::calcStepAfterPoT(sizeof(T));
|
|
return ret;
|
|
}
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
|
|
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
|