Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9588b48105 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,3 +6,5 @@ CMakeLists.txt.user*
|
|||||||
/include
|
/include
|
||||||
/release
|
/release
|
||||||
/build*
|
/build*
|
||||||
|
/AGENTS.md
|
||||||
|
/plans
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ if (POLICY CMP0177)
|
|||||||
endif()
|
endif()
|
||||||
project(PIP)
|
project(PIP)
|
||||||
set(PIP_MAJOR 5)
|
set(PIP_MAJOR 5)
|
||||||
set(PIP_MINOR 5)
|
set(PIP_MINOR 6)
|
||||||
set(PIP_REVISION 5)
|
set(PIP_REVISION 0)
|
||||||
set(PIP_SUFFIX )
|
set(PIP_SUFFIX )
|
||||||
set(PIP_COMPANY SHS)
|
set(PIP_COMPANY SHS)
|
||||||
set(PIP_DOMAIN org.SHS)
|
set(PIP_DOMAIN org.SHS)
|
||||||
|
|||||||
115
README.md
115
README.md
@@ -40,3 +40,118 @@ You should add ${<out_var>} to your target.
|
|||||||
[🇷🇺 Онлайн документация](https://shstk.ru/pip/html/ru/index.html)
|
[🇷🇺 Онлайн документация](https://shstk.ru/pip/html/ru/index.html)
|
||||||
|
|
||||||
[🇷🇺 Qt-help](https://shstk.ru/pip/pip_ru.qch)
|
[🇷🇺 Qt-help](https://shstk.ru/pip/pip_ru.qch)
|
||||||
|
|
||||||
|
## Основные опции сборки
|
||||||
|
|
||||||
|
### Стандартные опции (option())
|
||||||
|
| Опция | Описание | По умолчанию |
|
||||||
|
|-------|----------|--------------|
|
||||||
|
| `ICU` | ICU support для конвертации кодовых страниц | ON (кроме Win/Android/Apple) |
|
||||||
|
| `STD_IOSTREAM` | Поддержка std::iostream операторов | OFF |
|
||||||
|
| `INTROSPECTION` | Сборка с интроспекцией | OFF |
|
||||||
|
| `TESTS` | Сборка тестов | OFF |
|
||||||
|
| `COVERAGE` | Сборка с информацией о покрытии | OFF |
|
||||||
|
| `PIP_FFTW_F` | Поддержка FFTW для float | ON |
|
||||||
|
| `PIP_FFTW_L` | Поддержка FFTW для long double | ON |
|
||||||
|
| `PIP_FFTW_Q` | Поддержка FFTW для quad double | OFF |
|
||||||
|
|
||||||
|
### Опции модулей (PIP_BUILD_*)
|
||||||
|
| Опция | Модуль |
|
||||||
|
|-------|--------|
|
||||||
|
| `PIP_BUILD_CONSOLE` | console |
|
||||||
|
| `PIP_BUILD_CRYPT` | crypt (требует libsodium) |
|
||||||
|
| `PIP_BUILD_COMPRESS` | compress (требует zlib) |
|
||||||
|
| `PIP_BUILD_USB` | usb |
|
||||||
|
| `PIP_BUILD_FFTW` | fftw |
|
||||||
|
| `PIP_BUILD_OPENCL` | opencl |
|
||||||
|
| `PIP_BUILD_IO_UTILS` | io_utils |
|
||||||
|
| `PIP_BUILD_CLIENT_SERVER` | client_server |
|
||||||
|
| `PIP_BUILD_CLOUD` | cloud |
|
||||||
|
| `PIP_BUILD_LUA` | lua |
|
||||||
|
| `PIP_BUILD_HTTP_CLIENT` | http_client (требует libcurl) |
|
||||||
|
| `PIP_BUILD_HTTP_SERVER` | http_server (требует libmicrohttpd) |
|
||||||
|
|
||||||
|
### Дополнительные переменные
|
||||||
|
| Переменная | Описание |
|
||||||
|
|------------|----------|
|
||||||
|
| `PIP_BUILD_DEBUG` | Сборка debug версии |
|
||||||
|
| `PIP_FREERTOS` | Режим сборки для FreeRTOS |
|
||||||
|
| `CROSSTOOLS` | Собрать инструменты кросс-сборки под хостовую систему (pip_cmg, pip_rc, ...) |
|
||||||
|
| `LOCAL` | Локальная установка (bin/lib/include) |
|
||||||
|
| `PIP_CONTAINERS_MIN_ALLOC` | Переопределить минимальный размер аллокации контейнеров |
|
||||||
|
| `PIP_CONTAINERS_MAX_POT_ALLOC` | Переопределить максимальный размер дополнительной аллокации (поддерживает X_KiB, X_MiB) |
|
||||||
|
|
||||||
|
### Примеры использования
|
||||||
|
```bash
|
||||||
|
# Базовая сборка с тестами
|
||||||
|
cmake -B build -DTESTS=ON
|
||||||
|
|
||||||
|
# Сборка с покрытием и ICU
|
||||||
|
cmake -B build -DTESTS=ON -DCOVERAGE=ON -DICU=ON
|
||||||
|
|
||||||
|
# Отключение отдельных модулей
|
||||||
|
cmake -B build -DPIP_BUILD_CRYPT=OFF -DPIP_BUILD_OPENCL=OFF
|
||||||
|
|
||||||
|
# Переопределение параметров контейнеров
|
||||||
|
cmake -B build -DPIP_CONTAINERS_MIN_ALLOC=64
|
||||||
|
|
||||||
|
# Локальная установка
|
||||||
|
cmake -B build -DLOCAL=ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## PIP Dependencies
|
||||||
|
|
||||||
|
### Встроенные (included in 3rd/)
|
||||||
|
|
||||||
|
| Библиотека | Назначение | Модуль PIP |
|
||||||
|
|------------|------------|------------|
|
||||||
|
| **PCRE2** | Регулярные выражения | main (internal) |
|
||||||
|
| **BLAKE2** | Хеширование | main (internal) |
|
||||||
|
| **SipHash** | Хеширование | main (internal) |
|
||||||
|
| **Lua** | Lua scripting | lua |
|
||||||
|
| **LuaBridge** | Lua bindings | lua |
|
||||||
|
|
||||||
|
### Внешние (системные)
|
||||||
|
|
||||||
|
| Библиотека | Опция | Модуль PIP |
|
||||||
|
|------------|-------|------------|
|
||||||
|
| **ICU** | `-DICU=ON` | main (string conversion) |
|
||||||
|
| **zlib** | `PIP_BUILD_COMPRESS` | compress |
|
||||||
|
| **libsodium** | `PIP_BUILD_CRYPT` | crypt, io_utils, cloud |
|
||||||
|
| **libusb** | `PIP_BUILD_USB` | usb |
|
||||||
|
| **FFTW3** (+ threads) | `PIP_BUILD_FFTW` | fftw |
|
||||||
|
| **OpenCL** | `PIP_BUILD_OPENCL` | opencl |
|
||||||
|
| **libmicrohttpd** | `PIP_BUILD_HTTP_SERVER` | http_server |
|
||||||
|
| **libcurl** | `PIP_BUILD_HTTP_CLIENT` | http_client |
|
||||||
|
|
||||||
|
### Опциональные (тесты/документация)
|
||||||
|
|
||||||
|
| Инструмент | Назначение |
|
||||||
|
|------------|------------|
|
||||||
|
| **Google Test** | Тестирование (fetched automatically) |
|
||||||
|
| **Doxygen** | Генерация документации |
|
||||||
|
|
||||||
|
|
||||||
|
### Схема зависимостей модулей
|
||||||
|
|
||||||
|
```
|
||||||
|
main (core)
|
||||||
|
├── PCRE2 (встроен)
|
||||||
|
├── BLAKE2 (встроен)
|
||||||
|
├── SipHash (встроен)
|
||||||
|
└── ICU (опционально)
|
||||||
|
|
||||||
|
console → main
|
||||||
|
compress → zlib
|
||||||
|
crypt → libsodium
|
||||||
|
usb → libusb
|
||||||
|
fftw → FFTW3
|
||||||
|
opencl → OpenCL
|
||||||
|
io_utils → [crypt, если доступен]
|
||||||
|
client_server → io_utils
|
||||||
|
cloud → io_utils, crypt
|
||||||
|
lua → Lua (встроен), LuaBridge (встроен)
|
||||||
|
http_server → libmicrohttpd
|
||||||
|
http_client → libcurl
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piclientserver_client.h
|
/*! \file piclientserver_client.h
|
||||||
//! \ingroup ClientServer
|
* \ingroup ClientServer
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Client and ServerClient classes
|
* \~english
|
||||||
//! \~russian Классы Client и ServerClient
|
* \~russian
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides client implementation for connecting to servers and server-side client representation.
|
|
||||||
//! \~russian Обеспечивает реализацию клиента для подключения к серверам и представление клиента на стороне сервера.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piclientserver_client_base.h
|
/*! \file piclientserver_client_base.h
|
||||||
//! \ingroup ClientServer
|
* \ingroup ClientServer
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Base class for client-server communication
|
* \~english
|
||||||
//! \~russian Базовый класс для клиент-серверного взаимодействия
|
* \~russian
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides base functionality for client-server communication with diagnostics support.
|
|
||||||
//! \~russian Обеспечивает базовую функциональность для клиент-серверного взаимодействия с поддержкой диагностики.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
@@ -39,112 +37,77 @@ class Server;
|
|||||||
|
|
||||||
class ClientInterface {};
|
class ClientInterface {};
|
||||||
|
|
||||||
//! \brief
|
//! ~english Base class for client-server communication with diagnostics support
|
||||||
//! \~english Base class for client and server-side client
|
//! ~russian Базовый класс для клиент-серверного взаимодействия с поддержкой диагностики
|
||||||
//! \~russian Базовый класс для клиента и клиента на стороне сервера
|
|
||||||
// template<bool EnableDiagnostics = false>
|
// template<bool EnableDiagnostics = false>
|
||||||
class PIP_CLIENT_SERVER_EXPORT ClientBase {
|
class PIP_CLIENT_SERVER_EXPORT ClientBase {
|
||||||
friend class Server;
|
friend class Server;
|
||||||
NO_COPY_CLASS(ClientBase);
|
NO_COPY_CLASS(ClientBase);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs ClientBase
|
|
||||||
//! \~russian Создает ClientBase
|
|
||||||
ClientBase();
|
ClientBase();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~ClientBase();
|
virtual ~ClientBase();
|
||||||
|
|
||||||
//! \brief
|
//! ~english Gets underlying TCP connection
|
||||||
//! \~english Gets underlying TCP connection
|
//! ~russian Возвращает TCP-соединение
|
||||||
//! \~russian Возвращает TCP-соединение
|
|
||||||
const PIEthernet * getTCP() const { return tcp; }
|
const PIEthernet * getTCP() const { return tcp; }
|
||||||
|
|
||||||
//! \brief
|
//! ~english Closes the connection
|
||||||
//! \~english Closes the connection
|
//! ~russian Закрывает соединение
|
||||||
//! \~russian Закрывает соединение
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
//! \brief
|
//! ~english Gracefully stops and waits for completion
|
||||||
//! \~english Gracefully stops and waits for completion
|
//! ~russian Плавно останавливает и ожидает завершения
|
||||||
//! \~russian Плавно останавливает и ожидает завершения
|
|
||||||
void stopAndWait();
|
void stopAndWait();
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
//! ~english Writes byte array to the connection
|
||||||
//! \~english Writes byte array to the connection
|
//! ~russian Записывает массив байтов в соединение
|
||||||
//! \~russian Записывает массив байтов в соединение
|
|
||||||
int write(const void * d, const size_t s);
|
int write(const void * d, const size_t s);
|
||||||
|
|
||||||
//! \brief
|
//! ~english Writes byte array to the connection
|
||||||
//! \~english Writes byte array to the connection
|
//! ~russian Записывает массив байтов в соединение
|
||||||
//! \~russian Записывает массив байтов в соединение
|
|
||||||
int write(const PIByteArray & ba) { return write(ba.data(), ba.size()); }
|
int write(const PIByteArray & ba) { return write(ba.data(), ba.size()); }
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
//! ~english Enables diagnostics collection
|
||||||
//! \~english Enables diagnostics collection
|
//! ~russian Включает сбор диагностики
|
||||||
//! \~russian Включает сбор диагностики
|
|
||||||
void enableDiagnostics();
|
void enableDiagnostics();
|
||||||
|
|
||||||
//! \brief
|
//! ~english Gets current diagnostics state
|
||||||
//! \~english Gets current diagnostics state
|
//! ~russian Возвращает текущее состояние диагностики
|
||||||
//! \~russian Возвращает текущее состояние диагностики
|
|
||||||
PIDiagnostics::State diagnostics() const;
|
PIDiagnostics::State diagnostics() const;
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
//! ~english Gets current received packet bytes already received (all bytes count passed in \a receivePacketStart())
|
||||||
//! \~english Gets current received packet bytes already received (all bytes count passed in \a receivePacketStart())
|
//! ~russian Возвращает сколько байт принимаемого пакета получено (общее количество передается в \a receivePacketStart())
|
||||||
//! \~russian Возвращает сколько байт принимаемого пакета получено (общее количество передается в \a receivePacketStart())
|
|
||||||
int receivePacketProgress() const;
|
int receivePacketProgress() const;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns stream configuration
|
|
||||||
//! \~russian Возвращает конфигурацию стрима
|
|
||||||
const PIStreamPackerConfig & configuration() const { return stream.configuration(); }
|
const PIStreamPackerConfig & configuration() const { return stream.configuration(); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns stream configuration
|
|
||||||
//! \~russian Возвращает конфигурацию стрима
|
|
||||||
PIStreamPackerConfig & configuration() { return stream.configuration(); }
|
PIStreamPackerConfig & configuration() { return stream.configuration(); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets stream configuration
|
|
||||||
//! \~russian Устанавливает конфигурацию стрима
|
|
||||||
void setConfiguration(const PIStreamPackerConfig & config) { stream.setConfiguration(config); }
|
void setConfiguration(const PIStreamPackerConfig & config) { stream.setConfiguration(config); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
//! ~english Called when data is received
|
||||||
//! \~english Called when data is received
|
//! ~russian Вызывается при получении данных
|
||||||
//! \~russian Вызывается при получении данных
|
|
||||||
virtual void readed(PIByteArray data) {}
|
virtual void readed(PIByteArray data) {}
|
||||||
|
|
||||||
//! \brief
|
//! ~english Called when connection is established
|
||||||
//! \~english Called when connection is established
|
//! ~russian Вызывается при установке соединения
|
||||||
//! \~russian Вызывается при установке соединения
|
|
||||||
virtual void connected() {}
|
virtual void connected() {}
|
||||||
|
|
||||||
//! \brief
|
//! ~english Called when connection is closed
|
||||||
//! \~english Called when connection is closed
|
//! ~russian Вызывается при закрытии соединения
|
||||||
//! \~russian Вызывается при закрытии соединения
|
|
||||||
virtual void disconnected() {}
|
virtual void disconnected() {}
|
||||||
|
|
||||||
//! \brief
|
//! ~english Called when packet receiving starts
|
||||||
//! \~english Called when packet receiving starts
|
//! ~russian Вызывается при начале получения пакета
|
||||||
//! \~russian Вызывается при начале получения пакета
|
|
||||||
virtual void receivePacketStart(int size) {}
|
virtual void receivePacketStart(int size) {}
|
||||||
|
|
||||||
//! \brief
|
//! ~english Called when packet receiving ends
|
||||||
//! \~english Called when packet receiving ends
|
//! ~russian Вызывается при завершении получения пакета
|
||||||
//! \~russian Вызывается при завершении получения пакета
|
|
||||||
virtual void receivePacketEnd() {}
|
virtual void receivePacketEnd() {}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Initializes the client
|
|
||||||
//! \~russian Инициализирует клиента
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
bool own_tcp = false;
|
bool own_tcp = false;
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piclientserver_server.h
|
/*! \file piclientserver_server.h
|
||||||
//! \ingroup ClientServer
|
* \ingroup ClientServer
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english TCP Server
|
* \~english
|
||||||
//! \~russian TCP Сервер
|
* \~russian
|
||||||
//! \details
|
*/
|
||||||
//! \~english TCP server implementation for client-server communication.
|
|
||||||
//! \~russian Реализация TCP сервера для клиент-серверного взаимодействия.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Module includes
|
Module includes
|
||||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file picloudbase.h
|
/*! \file picloudbase.h
|
||||||
//! \ingroup Cloud
|
* \ingroup Cloud
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Base class for PICloudClient and PICloudServer
|
* \~english Base class for PICloudClient and PICloudServer
|
||||||
//! \~russian Базовый класс для PICloudClient и PICloudServer
|
* \~russian Базовый класс для PICloudClient и PICloudServer
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides common functionality for cloud client and server implementations.
|
|
||||||
//! \~russian Обеспечивает общую функциональность для реализаций облачного клиента и сервера.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
PICloud Base - Base class for PICloudClient and PICloud Server
|
PICloud Base - Base class for PICloudClient and PICloud Server
|
||||||
@@ -33,20 +31,10 @@
|
|||||||
#include "pistreampacker.h"
|
#include "pistreampacker.h"
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Base class for cloud client and server
|
|
||||||
//! \~russian Базовый класс для облачного клиента и сервера
|
|
||||||
|
|
||||||
class PIP_CLOUD_EXPORT PICloudBase {
|
class PIP_CLOUD_EXPORT PICloudBase {
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs PICloudBase
|
|
||||||
//! \~russian Создает PICloudBase
|
|
||||||
PICloudBase();
|
PICloudBase();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns server name
|
|
||||||
//! \~russian Возвращает имя сервера
|
|
||||||
PIString serverName() const;
|
PIString serverName() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file picloudclient.h
|
/*! \file picloudclient.h
|
||||||
//! \ingroup Cloud
|
* \ingroup Cloud
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english PICloud Client
|
* \~english PICloud Client
|
||||||
//! \~russian Клиент PICloud
|
* \~russian Клиент PICloud
|
||||||
//! \details
|
*/
|
||||||
//! \~english Client implementation for connecting to PICloud servers over TCP.
|
|
||||||
//! \~russian Реализация клиента для подключения к серверам PICloud по TCP.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
PICloud Client
|
PICloud Client
|
||||||
@@ -32,9 +30,7 @@
|
|||||||
#include "piconditionvar.h"
|
#include "piconditionvar.h"
|
||||||
|
|
||||||
|
|
||||||
//! \brief PICloud client implementation
|
//! \brief PICloudClient
|
||||||
//! \~english PICloud client for connecting to servers
|
|
||||||
//! \~russian Клиент PICloud для подключения к серверам
|
|
||||||
|
|
||||||
class PIP_CLOUD_EXPORT PICloudClient
|
class PIP_CLOUD_EXPORT PICloudClient
|
||||||
: public PIIODevice
|
: public PIIODevice
|
||||||
@@ -42,75 +38,23 @@ class PIP_CLOUD_EXPORT PICloudClient
|
|||||||
PIIODEVICE(PICloudClient, "");
|
PIIODEVICE(PICloudClient, "");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs PICloudClient
|
|
||||||
//! \~russian Создает PICloudClient
|
|
||||||
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PICloudClient();
|
virtual ~PICloudClient();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets server name
|
|
||||||
//! \~russian Устанавливает имя сервера
|
|
||||||
void setServerName(const PIString & server_name);
|
void setServerName(const PIString & server_name);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets keep connection mode
|
|
||||||
//! \~russian Устанавливает режим поддержания соединения
|
|
||||||
void setKeepConnection(bool on);
|
void setKeepConnection(bool on);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checks if connected to server
|
|
||||||
//! \~russian Проверяет подключение к серверу
|
|
||||||
bool isConnected() const { return is_connected; }
|
bool isConnected() const { return is_connected; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns number of bytes available
|
|
||||||
//! \~russian Возвращает количество доступных байт
|
|
||||||
ssize_t bytesAvailable() const override { return buff.size(); }
|
ssize_t bytesAvailable() const override { return buff.size(); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Interrupts connection
|
|
||||||
//! \~russian Прерывает соединение
|
|
||||||
void interrupt() override;
|
void interrupt() override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Raised when connected to server
|
|
||||||
//! \~russian Вызывается при подключении к серверу
|
|
||||||
EVENT(connected);
|
EVENT(connected);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Raised when disconnected from server
|
|
||||||
//! \~russian Вызывается при отключении от сервера
|
|
||||||
EVENT(disconnected);
|
EVENT(disconnected);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Opens device
|
|
||||||
//! \~russian Открывает устройство
|
|
||||||
bool openDevice() override;
|
bool openDevice() override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Closes device
|
|
||||||
//! \~russian Закрывает устройство
|
|
||||||
bool closeDevice() override;
|
bool closeDevice() override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Reads data from device
|
|
||||||
//! \~russian Читает данные из устройства
|
|
||||||
ssize_t readDevice(void * read_to, ssize_t max_size) override;
|
ssize_t readDevice(void * read_to, ssize_t max_size) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Writes data to device
|
|
||||||
//! \~russian Записывает данные в устройство
|
|
||||||
ssize_t writeDevice(const void * data, ssize_t size) override;
|
ssize_t writeDevice(const void * data, ssize_t size) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns device info flags
|
|
||||||
//! \~russian Возвращает флаги информации об устройстве
|
|
||||||
DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; }
|
DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file picloudserver.h
|
/*! \file picloudserver.h
|
||||||
//! \ingroup Cloud
|
* \ingroup Cloud
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english PICloud Server
|
* \~english PICloud Server
|
||||||
//! \~russian Сервер PICloud
|
* \~russian Сервер PICloud
|
||||||
//! \details
|
*/
|
||||||
//! \~english Server implementation for accepting PICloud client connections over TCP.
|
|
||||||
//! \~russian Реализация сервера для приема подключений клиентов PICloud по TCP.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
PICloud Server
|
PICloud Server
|
||||||
@@ -38,70 +36,25 @@ class PIP_CLOUD_EXPORT PICloudServer
|
|||||||
PIIODEVICE(PICloudServer, "");
|
PIIODEVICE(PICloudServer, "");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
//! PICloudServer
|
||||||
//! \~english Constructs PICloudServer
|
|
||||||
//! \~russian Создает PICloudServer
|
|
||||||
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PICloudServer();
|
virtual ~PICloudServer();
|
||||||
|
|
||||||
//! \brief Connected client representation
|
|
||||||
//! \~english Represents a client connected to the server
|
|
||||||
//! \~russian Представляет клиента, подключенного к серверу
|
|
||||||
class Client: public PIIODevice {
|
class Client: public PIIODevice {
|
||||||
PIIODEVICE(PICloudServer::Client, "");
|
PIIODEVICE(PICloudServer::Client, "");
|
||||||
friend class PICloudServer;
|
friend class PICloudServer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs Client
|
|
||||||
//! \~russian Создает Client
|
|
||||||
//! \param srv Parent server / Родительский сервер
|
|
||||||
//! \param id Client ID / ID клиента
|
|
||||||
Client(PICloudServer * srv = nullptr, uint id = 0);
|
Client(PICloudServer * srv = nullptr, uint id = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~Client();
|
virtual ~Client();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Opens device
|
|
||||||
//! \~russian Открывает устройство
|
|
||||||
bool openDevice() override;
|
bool openDevice() override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Closes device
|
|
||||||
//! \~russian Закрывает устройство
|
|
||||||
bool closeDevice() override;
|
bool closeDevice() override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Reads data from device
|
|
||||||
//! \~russian Читает данные из устройства
|
|
||||||
ssize_t readDevice(void * read_to, ssize_t max_size) override;
|
ssize_t readDevice(void * read_to, ssize_t max_size) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Writes data to device
|
|
||||||
//! \~russian Записывает данные в устройство
|
|
||||||
ssize_t writeDevice(const void * data, ssize_t size) override;
|
ssize_t writeDevice(const void * data, ssize_t size) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns device info flags
|
|
||||||
//! \~russian Возвращает флаги информации об устройстве
|
|
||||||
DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; }
|
DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns number of bytes available
|
|
||||||
//! \~russian Возвращает количество доступных байт
|
|
||||||
ssize_t bytesAvailable() const override { return buff.size(); }
|
ssize_t bytesAvailable() const override { return buff.size(); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Interrupts connection
|
|
||||||
//! \~russian Прерывает соединение
|
|
||||||
void interrupt() override;
|
void interrupt() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -114,45 +67,17 @@ public:
|
|||||||
std::atomic_bool is_connected;
|
std::atomic_bool is_connected;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets server name
|
|
||||||
//! \~russian Устанавливает имя сервера
|
|
||||||
void setServerName(const PIString & server_name);
|
void setServerName(const PIString & server_name);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns list of connected clients
|
|
||||||
//! \~russian Возвращает список подключенных клиентов
|
|
||||||
PIVector<PICloudServer::Client *> clients() const;
|
PIVector<PICloudServer::Client *> clients() const;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Raised when new client connects
|
|
||||||
//! \~russian Вызывается при подключении нового клиента
|
|
||||||
EVENT1(newConnection, PICloudServer::Client *, client);
|
EVENT1(newConnection, PICloudServer::Client *, client);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Opens device
|
|
||||||
//! \~russian Открывает устройство
|
|
||||||
bool openDevice() override;
|
bool openDevice() override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Closes device
|
|
||||||
//! \~russian Закрывает устройство
|
|
||||||
bool closeDevice() override;
|
bool closeDevice() override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Reads data from device
|
|
||||||
//! \~russian Читает данные из устройства
|
|
||||||
ssize_t readDevice(void * read_to, ssize_t max_size) override;
|
ssize_t readDevice(void * read_to, ssize_t max_size) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Writes data to device
|
|
||||||
//! \~russian Записывает данные в устройство
|
|
||||||
ssize_t writeDevice(const void * data, ssize_t max_size) override;
|
ssize_t writeDevice(const void * data, ssize_t max_size) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Interrupts connection
|
|
||||||
//! \~russian Прерывает соединение
|
|
||||||
void interrupt() override;
|
void interrupt() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file picloudtcp.h
|
/*! \file picloudtcp.h
|
||||||
//! \ingroup Cloud
|
* \ingroup Cloud
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english PICloud TCP transport
|
* \~english PICloud TCP transport
|
||||||
//! \~russian TCP слой PICloud
|
* \~russian TCP слой PICloud
|
||||||
//! \details
|
*/
|
||||||
//! \~english Low-level TCP protocol implementation for PICloud communication.
|
|
||||||
//! \~russian Реализация низкоуровневого TCP-протокола для коммуникации PICloud.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
PICloud TCP transport
|
PICloud TCP transport
|
||||||
@@ -38,118 +36,45 @@ class PIStreamPacker;
|
|||||||
|
|
||||||
namespace PICloud {
|
namespace PICloud {
|
||||||
|
|
||||||
//! \brief TCP transport protocol
|
|
||||||
//! \~english TCP transport protocol for cloud communication
|
|
||||||
//! \~russian TCP транспортный протокол для облачной коммуникации
|
|
||||||
|
|
||||||
class PIP_CLOUD_EXPORT TCP {
|
class PIP_CLOUD_EXPORT TCP {
|
||||||
public:
|
public:
|
||||||
//! \brief Protocol version
|
|
||||||
enum Version {
|
enum Version {
|
||||||
Version_1 = 1, //!< Version 1 / Версия 1
|
Version_1 = 1,
|
||||||
Version_2 = 2, //!< Version 2 / Версия 2
|
Version_2 = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Connection role
|
|
||||||
enum Role {
|
enum Role {
|
||||||
InvalidRole = 0, //!< Invalid role / Неверная роль
|
InvalidRole = 0,
|
||||||
Server = 1, //!< Server role / Роль сервера
|
Server = 1,
|
||||||
Client = 2, //!< Client role / Роль клиента
|
Client = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Message type
|
|
||||||
enum Type {
|
enum Type {
|
||||||
InvalidType = 0, //!< Invalid type / Неверный тип
|
InvalidType = 0,
|
||||||
Connect = 1, //!< Connect message / Сообщение о подключении
|
Connect = 1,
|
||||||
Disconnect = 2, //!< Disconnect message / Сообщение об отключении
|
Disconnect = 2,
|
||||||
Data = 3, //!< Data message / Сообщение с данными
|
Data = 3,
|
||||||
Ping = 4, //!< Ping message / Сообщение ping
|
Ping = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TCP transport
|
|
||||||
//! \~russian Создает TCP транспорт
|
|
||||||
//! \param s Stream packer instance / Экземпляр стримового упаковщика
|
|
||||||
TCP(PIStreamPacker * s);
|
TCP(PIStreamPacker * s);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets connection role
|
|
||||||
//! \~russian Устанавливает роль соединения
|
|
||||||
void setRole(Role r);
|
void setRole(Role r);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns connection role
|
|
||||||
//! \~russian Возвращает роль соединения
|
|
||||||
Role role() const { return (Role)header.role; }
|
Role role() const { return (Role)header.role; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets server name
|
|
||||||
//! \~russian Устанавливает имя сервера
|
|
||||||
void setServerName(const PIString & server_name_);
|
void setServerName(const PIString & server_name_);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns server name
|
|
||||||
//! \~russian Возвращает имя сервера
|
|
||||||
PIString serverName() const;
|
PIString serverName() const;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sends start message
|
|
||||||
//! \~russian Отправляет сообщение о старте
|
|
||||||
void sendStart();
|
void sendStart();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sends connected message
|
|
||||||
//! \~russian Отправляет сообщение о подключении
|
|
||||||
void sendConnected(uint client_id);
|
void sendConnected(uint client_id);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sends disconnected message
|
|
||||||
//! \~russian Отправляет сообщение об отключении
|
|
||||||
void sendDisconnected(uint client_id);
|
void sendDisconnected(uint client_id);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sends data to all clients
|
|
||||||
//! \~russian Отправляет данные всем клиентам
|
|
||||||
int sendData(const PIByteArray & data);
|
int sendData(const PIByteArray & data);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sends data to specific client
|
|
||||||
//! \~russian Отправляет данные конкретному клиенту
|
|
||||||
int sendData(const PIByteArray & data, uint client_id);
|
int sendData(const PIByteArray & data, uint client_id);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sends ping message
|
|
||||||
//! \~russian Отправляет сообщение ping
|
|
||||||
void sendPing();
|
void sendPing();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Parses header from buffer
|
|
||||||
//! \~russian Парсит заголовок из буфера
|
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checks if data can be parsed
|
|
||||||
//! \~russian Проверяет возможность парсинга данных
|
|
||||||
bool canParseData(PIByteArray & ba);
|
bool canParseData(PIByteArray & ba);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Parses data for server
|
|
||||||
//! \~russian Парсит данные для сервера
|
|
||||||
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
|
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Parses connect data
|
|
||||||
//! \~russian Парсит данные подключения
|
|
||||||
PIByteArray parseConnect_d(PIByteArray & ba);
|
PIByteArray parseConnect_d(PIByteArray & ba);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Parses connect message
|
|
||||||
//! \~russian Парсит сообщение подключения
|
|
||||||
uint parseConnect(PIByteArray & ba);
|
uint parseConnect(PIByteArray & ba);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Parses disconnect message
|
|
||||||
//! \~russian Парсит сообщение отключения
|
|
||||||
uint parseDisconnect(PIByteArray & ba);
|
uint parseDisconnect(PIByteArray & ba);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -29,12 +29,12 @@
|
|||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "pitime.h"
|
#include "pitime.h"
|
||||||
|
|
||||||
#define WAIT_FOR_EXIT \
|
#define WAIT_FOR_EXIT \
|
||||||
while (!PIKbdListener::exiting) \
|
while (!PIKbdListener::exiting) \
|
||||||
piMSleep(PIP_MIN_MSLEEP * 5); \
|
piMSleep(PIP_MIN_MSLEEP * 5); \
|
||||||
if (PIKbdListener::instance()) { \
|
if (PIKbdListener::instance()) { \
|
||||||
if (!PIKbdListener::instance()->stopAndWait(PISystemTime::fromSeconds(1))) PIKbdListener::instance()->terminate(); \
|
if (!PIKbdListener::instance()->stopAndWait(PISystemTime::fromSeconds(1))) PIKbdListener::instance()->terminate(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PIP_EXPORT PIKbdListener: public PIThread {
|
class PIP_EXPORT PIKbdListener: public PIThread {
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piscreen.h
|
/*! \file piscreen.h
|
||||||
//! \ingroup Console
|
* \ingroup Console
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Console tiling manager
|
* \~english Console tiling manager
|
||||||
//! \~russian Консольный тайловый менеджер
|
* \~russian Консольный тайловый менеджер
|
||||||
//! \details
|
*/
|
||||||
//! \~english Main console screen manager providing tile-based UI rendering and keyboard input.
|
|
||||||
//! \~russian Основной менеджер консольного экрана, обеспечивающий отрисовку UI на основе тайлов и ввод с клавиатуры.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Console GUI
|
Console GUI
|
||||||
@@ -40,126 +38,46 @@ class PIP_CONSOLE_EXPORT PIScreen
|
|||||||
class SystemConsole;
|
class SystemConsole;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
//! Constructs %PIScreen with key handler "slot" and if "startNow" start it
|
||||||
//! \~english Constructs PIScreen
|
|
||||||
//! \~russian Создает PIScreen
|
|
||||||
//! \param startNow Start immediately / Запустить немедленно
|
|
||||||
//! \param slot Keyboard handler function / Обработчик клавиатуры
|
|
||||||
PIScreen(bool startNow = true, PIKbdListener::KBFunc slot = 0);
|
PIScreen(bool startNow = true, PIKbdListener::KBFunc slot = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
~PIScreen();
|
~PIScreen();
|
||||||
|
|
||||||
//! \brief
|
//! Directly call function from \a PIKbdListener
|
||||||
//! \~english Enables exit capture with key
|
|
||||||
//! \~russian Включает захват выхода по клавише
|
|
||||||
void enableExitCapture(int key = 'Q') { listener->enableExitCapture(key); }
|
void enableExitCapture(int key = 'Q') { listener->enableExitCapture(key); }
|
||||||
|
|
||||||
//! \brief
|
//! Directly call function from \a PIKbdListener
|
||||||
//! \~english Disables exit capture
|
|
||||||
//! \~russian Отключает захват выхода
|
|
||||||
void disableExitCapture() { listener->disableExitCapture(); }
|
void disableExitCapture() { listener->disableExitCapture(); }
|
||||||
|
|
||||||
//! \brief
|
//! Directly call function from \a PIKbdListener
|
||||||
//! \~english Checks if exit is captured
|
|
||||||
//! \~russian Проверяет, захвачен ли выход
|
|
||||||
bool exitCaptured() const { return listener->exitCaptured(); }
|
bool exitCaptured() const { return listener->exitCaptured(); }
|
||||||
|
|
||||||
//! \brief
|
//! Directly call function from \a PIKbdListener
|
||||||
//! \~english Returns exit key
|
|
||||||
//! \~russian Возвращает клавишу выхода
|
|
||||||
int exitKey() const { return listener->exitKey(); }
|
int exitKey() const { return listener->exitKey(); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns window width
|
|
||||||
//! \~russian Возвращает ширину окна
|
|
||||||
int windowWidth() const { return console.width; }
|
int windowWidth() const { return console.width; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns window height
|
|
||||||
//! \~russian Возвращает высоту окна
|
|
||||||
int windowHeight() const { return console.height; }
|
int windowHeight() const { return console.height; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checks if mouse is enabled
|
|
||||||
//! \~russian Проверяет, включена ли мышь
|
|
||||||
bool isMouseEnabled() const { return mouse_; }
|
bool isMouseEnabled() const { return mouse_; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets mouse enabled state
|
|
||||||
//! \~russian Устанавливает состояние мыши
|
|
||||||
void setMouseEnabled(bool on);
|
void setMouseEnabled(bool on);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns root tile
|
|
||||||
//! \~russian Возвращает корневой тайл
|
|
||||||
PIScreenTile * rootTile() { return &root; }
|
PIScreenTile * rootTile() { return &root; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Finds tile by name
|
|
||||||
//! \~russian Находит тайл по имени
|
|
||||||
PIScreenTile * tileByName(const PIString & name);
|
PIScreenTile * tileByName(const PIString & name);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets dialog tile
|
|
||||||
//! \~russian Устанавливает диалоговый тайл
|
|
||||||
void setDialogTile(PIScreenTile * t);
|
void setDialogTile(PIScreenTile * t);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns current dialog tile
|
|
||||||
//! \~russian Возвращает текущий диалоговый тайл
|
|
||||||
PIScreenTile * dialogTile() const { return tile_dialog; }
|
PIScreenTile * dialogTile() const { return tile_dialog; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns screen drawer
|
|
||||||
//! \~russian Возвращает отрисовщик экрана
|
|
||||||
PIScreenDrawer * drawer() { return &drawer_; }
|
PIScreenDrawer * drawer() { return &drawer_; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Clears the screen
|
|
||||||
//! \~russian Очищает экран
|
|
||||||
void clear() { drawer_.clear(); }
|
void clear() { drawer_.clear(); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Resizes screen
|
|
||||||
//! \~russian Изменяет размер экрана
|
|
||||||
void resize(int w, int h) { console.resize(w, h); }
|
void resize(int w, int h) { console.resize(w, h); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Waits for finish
|
|
||||||
//! \~russian Ожидает завершения
|
|
||||||
EVENT_HANDLER0(void, waitForFinish);
|
EVENT_HANDLER0(void, waitForFinish);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Starts screen
|
|
||||||
//! \~russian Запускает экран
|
|
||||||
EVENT_HANDLER0(void, start) { start(false); }
|
EVENT_HANDLER0(void, start) { start(false); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Starts screen
|
|
||||||
//! \~russian Запускает экран
|
|
||||||
EVENT_HANDLER1(void, start, bool, wait);
|
EVENT_HANDLER1(void, start, bool, wait);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Stops screen
|
|
||||||
//! \~russian Останавливает экран
|
|
||||||
EVENT_HANDLER0(void, stop) { stop(false); }
|
EVENT_HANDLER0(void, stop) { stop(false); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Stops screen
|
|
||||||
//! \~russian Останавливает экран
|
|
||||||
EVENT_HANDLER1(void, stop, bool, clear);
|
EVENT_HANDLER1(void, stop, bool, clear);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Raised on key pressed
|
|
||||||
//! \~russian Вызывается при нажатии клавиши
|
|
||||||
EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void *, data);
|
EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void *, data);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Raised on tile event
|
|
||||||
//! \~russian Вызывается при событии тайла
|
|
||||||
EVENT2(tileEvent, PIScreenTile *, tile, PIScreenTypes::TileEvent, e);
|
EVENT2(tileEvent, PIScreenTile *, tile, PIScreenTypes::TileEvent, e);
|
||||||
|
|
||||||
//! \handlers
|
//! \handlers
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piscreenconsole.h
|
/*! \file piscreenconsole.h
|
||||||
//! \ingroup Console
|
* \ingroup Console
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Tile for PIScreen with PIConsole API
|
* \~english Tile for PIScreen with PIConsole API
|
||||||
//! \~russian Тайл для PIScreen с API PIConsole
|
* \~russian Тайл для PIScreen с API PIConsole
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides tiles for displaying variable data and console-like content.
|
|
||||||
//! \~russian Обеспечивает тайлы для отображения данных переменных и консольного контента.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Tile for PIScreen with PIConsole API
|
Tile for PIScreen with PIConsole API
|
||||||
@@ -34,30 +32,17 @@
|
|||||||
/// NOTE: incomplete class
|
/// NOTE: incomplete class
|
||||||
/// TODO: write TileVars
|
/// TODO: write TileVars
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Tile for displaying variable data
|
|
||||||
//! \~russian Тайл для отображения данных переменных
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileVars: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileVars: public PIScreenTile {
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileVars
|
|
||||||
//! \~russian Создает TileVars
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileVars(const PIString & n = PIString());
|
TileVars(const PIString & n = PIString());
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Variable data structure
|
|
||||||
struct PIP_CONSOLE_EXPORT Variable {
|
struct PIP_CONSOLE_EXPORT Variable {
|
||||||
Variable() {
|
Variable() {
|
||||||
nx = ny = type = offset = bitFrom = bitCount = size = 0;
|
nx = ny = type = offset = bitFrom = bitCount = size = 0;
|
||||||
format = PIScreenTypes::CellFormat();
|
format = PIScreenTypes::CellFormat();
|
||||||
ptr = 0;
|
ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checks if variable is empty
|
|
||||||
//! \~russian Проверяет, пустая ли переменная
|
|
||||||
bool isEmpty() const { return (ptr == 0); }
|
bool isEmpty() const { return (ptr == 0); }
|
||||||
PIString name;
|
PIString name;
|
||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
@@ -82,34 +67,15 @@ protected:
|
|||||||
ptr = src.ptr;
|
ptr = src.ptr;
|
||||||
}*/
|
}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns variables
|
|
||||||
//! \~russian Возвращает переменные
|
|
||||||
PIVector<Variable> variables;
|
PIVector<Variable> variables;
|
||||||
PIScreenTypes::Alignment alignment;
|
PIScreenTypes::Alignment alignment;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Console-style tile for PIScreen
|
|
||||||
//! \~russian Консольный тайл для PIScreen
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT PIScreenConsoleTile: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT PIScreenConsoleTile: public PIScreenTile {
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs PIScreenConsoleTile
|
|
||||||
//! \~russian Создает PIScreenConsoleTile
|
|
||||||
PIScreenConsoleTile();
|
PIScreenConsoleTile();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piscreendrawer.h
|
/*! \file piscreendrawer.h
|
||||||
//! \ingroup Console
|
* \ingroup Console
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Drawer for PIScreen
|
* \~english Drawer for PIScreen
|
||||||
//! \~russian Отрисовщик для PIScreen
|
* \~russian Отрисовщик для PIScreen
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides drawing primitives for console screen rendering.
|
|
||||||
//! \~russian Обеспечивает примитивы отрисовки для рендеринга консольного экрана.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Drawer for PIScreen
|
Drawer for PIScreen
|
||||||
@@ -32,51 +30,31 @@
|
|||||||
#include "piscreentypes.h"
|
#include "piscreentypes.h"
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
//! \brief Screen drawer for console rendering
|
|
||||||
//! \~english Console screen drawer for rendering graphics
|
|
||||||
//! \~russian Отрисовщик консольного экрана для рендеринга графики
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT PIScreenDrawer {
|
class PIP_CONSOLE_EXPORT PIScreenDrawer {
|
||||||
friend class PIScreen;
|
friend class PIScreen;
|
||||||
PIScreenDrawer(PIVector<PIVector<PIScreenTypes::Cell>> & c);
|
PIScreenDrawer(PIVector<PIVector<PIScreenTypes::Cell>> & c);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief ASCII art characters
|
|
||||||
enum ArtChar {
|
enum ArtChar {
|
||||||
LineVertical = 1, //!< Vertical line / Вертикальная линия
|
LineVertical = 1,
|
||||||
LineHorizontal, //!< Horizontal line / Горизонтальная линия
|
LineHorizontal,
|
||||||
Cross, //!< Cross / Крест
|
Cross,
|
||||||
CornerTopLeft, //!< Top-left corner / Угол сверху-слева
|
CornerTopLeft,
|
||||||
CornerTopRight, //!< Top-right corner / Угол сверху-справа
|
CornerTopRight,
|
||||||
CornerBottomLeft, //!< Bottom-left corner / Угол снизу-слева
|
CornerBottomLeft,
|
||||||
CornerBottomRight, //!< Bottom-right corner / Угол снизу-справа
|
CornerBottomRight,
|
||||||
Unchecked, //!< Unchecked box / Неотмеченная клетка
|
Unchecked,
|
||||||
Checked //!< Checked box / Отмеченная клетка
|
Checked
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Clears the screen
|
|
||||||
//! \~russian Очищает экран
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Clears rectangle
|
|
||||||
//! \~russian Очищает прямоугольник
|
|
||||||
void clearRect(int x0, int y0, int x1, int y1) { fillRect(x0, y0, x1, y1, ' '); }
|
void clearRect(int x0, int y0, int x1, int y1) { fillRect(x0, y0, x1, y1, ' '); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws pixel
|
|
||||||
//! \~russian Рисует пиксель
|
|
||||||
void drawPixel(int x,
|
void drawPixel(int x,
|
||||||
int y,
|
int y,
|
||||||
const PIChar & c,
|
const PIChar & c,
|
||||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||||
PIScreenTypes::CharFlags flags_char = 0);
|
PIScreenTypes::CharFlags flags_char = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws line
|
|
||||||
//! \~russian Рисует линию
|
|
||||||
void drawLine(int x0,
|
void drawLine(int x0,
|
||||||
int y0,
|
int y0,
|
||||||
int x1,
|
int x1,
|
||||||
@@ -85,10 +63,6 @@ public:
|
|||||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||||
PIScreenTypes::CharFlags flags_char = 0);
|
PIScreenTypes::CharFlags flags_char = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws rectangle
|
|
||||||
//! \~russian Рисует прямоугольник
|
|
||||||
void drawRect(int x0,
|
void drawRect(int x0,
|
||||||
int y0,
|
int y0,
|
||||||
int x1,
|
int x1,
|
||||||
@@ -97,10 +71,6 @@ public:
|
|||||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||||
PIScreenTypes::CharFlags flags_char = 0);
|
PIScreenTypes::CharFlags flags_char = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws frame
|
|
||||||
//! \~russian Рисует рамку
|
|
||||||
void drawFrame(int x0,
|
void drawFrame(int x0,
|
||||||
int y0,
|
int y0,
|
||||||
int x1,
|
int x1,
|
||||||
@@ -108,20 +78,12 @@ public:
|
|||||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||||
PIScreenTypes::CharFlags flags_char = 0);
|
PIScreenTypes::CharFlags flags_char = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws text
|
|
||||||
//! \~russian Рисует текст
|
|
||||||
void drawText(int x,
|
void drawText(int x,
|
||||||
int y,
|
int y,
|
||||||
const PIString & s,
|
const PIString & s,
|
||||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||||
PIScreenTypes::Color col_back = PIScreenTypes::Transparent,
|
PIScreenTypes::Color col_back = PIScreenTypes::Transparent,
|
||||||
PIScreenTypes::CharFlags flags_char = 0);
|
PIScreenTypes::CharFlags flags_char = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Fills rectangle
|
|
||||||
//! \~russian Заполняет прямоугольник
|
|
||||||
void fillRect(int x0,
|
void fillRect(int x0,
|
||||||
int y0,
|
int y0,
|
||||||
int x1,
|
int x1,
|
||||||
@@ -130,20 +92,10 @@ public:
|
|||||||
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
PIScreenTypes::Color col_char = PIScreenTypes::Default,
|
||||||
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
PIScreenTypes::Color col_back = PIScreenTypes::Default,
|
||||||
PIScreenTypes::CharFlags flags_char = 0);
|
PIScreenTypes::CharFlags flags_char = 0);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Fills rectangle with content
|
|
||||||
//! \~russian Заполняет прямоугольник содержимым
|
|
||||||
void fillRect(int x0, int y0, int x1, int y1, PIVector<PIVector<PIScreenTypes::Cell>> & content);
|
void fillRect(int x0, int y0, int x1, int y1, PIVector<PIVector<PIScreenTypes::Cell>> & content);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns art character by type
|
|
||||||
//! \~russian Возвращает символ искусства по типу
|
|
||||||
PIChar artChar(const ArtChar type) const { return arts_.value(type, PIChar(' ')); }
|
PIChar artChar(const ArtChar type) const { return arts_.value(type, PIChar(' ')); }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Clears cell matrix
|
|
||||||
//! \~russian Очищает матрицу ячеек
|
|
||||||
static void clear(PIVector<PIVector<PIScreenTypes::Cell>> & cells);
|
static void clear(PIVector<PIVector<PIScreenTypes::Cell>> & cells);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piscreentile.h
|
/*! \file piscreentile.h
|
||||||
//! \ingroup Console
|
* \ingroup Console
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Basic PIScreen tile
|
* \~english Basic PIScreen tile
|
||||||
//! \~russian Базовый тайл для PIScreen
|
* \~russian Базовый тайл для PIScreen
|
||||||
//! \details
|
*/
|
||||||
//! \~english Base class for all screen tiles providing layout and event handling.
|
|
||||||
//! \~russian Базовый класс для всех экранных тайлов, обеспечивающий компоновку и обработку событий.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Basic PIScreen tile
|
Basic PIScreen tile
|
||||||
@@ -34,89 +32,27 @@
|
|||||||
|
|
||||||
class PIScreenDrawer;
|
class PIScreenDrawer;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Base tile class for console screen
|
|
||||||
//! \~russian Базовый класс тайла для консольного экрана
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject {
|
class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject {
|
||||||
friend class PIScreen;
|
friend class PIScreen;
|
||||||
PIOBJECT_SUBCLASS(PIScreenTile, PIObject);
|
PIOBJECT_SUBCLASS(PIScreenTile, PIObject);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs PIScreenTile
|
|
||||||
//! \~russian Создает PIScreenTile
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
//! \param d Layout direction / Направление компоновки
|
|
||||||
//! \param p Size policy / Политика размера
|
|
||||||
PIScreenTile(const PIString & n = PIString(),
|
PIScreenTile(const PIString & n = PIString(),
|
||||||
PIScreenTypes::Direction d = PIScreenTypes::Vertical,
|
PIScreenTypes::Direction d = PIScreenTypes::Vertical,
|
||||||
PIScreenTypes::SizePolicy p = PIScreenTypes::Preferred);
|
PIScreenTypes::SizePolicy p = PIScreenTypes::Preferred);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PIScreenTile();
|
virtual ~PIScreenTile();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Adds child tile
|
|
||||||
//! \~russian Добавляет дочерний тайл
|
|
||||||
void addTile(PIScreenTile * t);
|
void addTile(PIScreenTile * t);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Takes ownership of tile
|
|
||||||
//! \~russian Забирает владение тайла
|
|
||||||
void takeTile(PIScreenTile * t);
|
void takeTile(PIScreenTile * t);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Removes child tile
|
|
||||||
//! \~russian Удаляет дочерний тайл
|
|
||||||
void removeTile(PIScreenTile * t);
|
void removeTile(PIScreenTile * t);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns parent tile
|
|
||||||
//! \~russian Возвращает родительский тайл
|
|
||||||
PIScreenTile * parentTile() const { return parent; }
|
PIScreenTile * parentTile() const { return parent; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns child tiles
|
|
||||||
//! \~russian Возвращает дочерние тайлы
|
|
||||||
//! \param only_visible Only visible tiles / Только видимые тайлы
|
|
||||||
PIVector<PIScreenTile *> children(bool only_visible = false);
|
PIVector<PIScreenTile *> children(bool only_visible = false);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns child under mouse position
|
|
||||||
//! \~russian Возвращает тайл под мышью
|
|
||||||
PIScreenTile * childUnderMouse(int x, int y);
|
PIScreenTile * childUnderMouse(int x, int y);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Shows tile
|
|
||||||
//! \~russian Показывает тайл
|
|
||||||
void show() { visible = true; }
|
void show() { visible = true; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Hides tile
|
|
||||||
//! \~russian Скрывает тайл
|
|
||||||
void hide() { visible = false; }
|
void hide() { visible = false; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets focus to this tile
|
|
||||||
//! \~russian Устанавливает фокус на этот тайл
|
|
||||||
void setFocus();
|
void setFocus();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checks if tile has focus
|
|
||||||
//! \~russian Проверяет, имеет ли тайл фокус
|
|
||||||
bool hasFocus() const { return has_focus; }
|
bool hasFocus() const { return has_focus; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets all margins
|
|
||||||
//! \~russian Устанавливает все отступы
|
|
||||||
void setMargins(int m) { marginLeft = marginRight = marginTop = marginBottom = m; }
|
void setMargins(int m) { marginLeft = marginRight = marginTop = marginBottom = m; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets individual margins
|
|
||||||
//! \~russian Устанавливает отдельные отступы
|
|
||||||
void setMargins(int l, int r, int t, int b) {
|
void setMargins(int l, int r, int t, int b) {
|
||||||
marginLeft = l;
|
marginLeft = l;
|
||||||
marginRight = r;
|
marginRight = r;
|
||||||
@@ -124,24 +60,9 @@ public:
|
|||||||
marginBottom = b;
|
marginBottom = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns tile X position
|
|
||||||
//! \~russian Возвращает позицию X тайла
|
|
||||||
int x() const { return x_; }
|
int x() const { return x_; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns tile Y position
|
|
||||||
//! \~russian Возвращает позицию Y тайла
|
|
||||||
int y() const { return y_; }
|
int y() const { return y_; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns tile width
|
|
||||||
//! \~russian Возвращает ширину тайла
|
|
||||||
int width() const { return width_; }
|
int width() const { return width_; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns tile height
|
|
||||||
//! \~russian Возвращает высоту тайла
|
|
||||||
int height() const { return height_; }
|
int height() const { return height_; }
|
||||||
|
|
||||||
PIScreenTypes::Direction direction;
|
PIScreenTypes::Direction direction;
|
||||||
@@ -156,64 +77,29 @@ public:
|
|||||||
bool visible;
|
bool visible;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
//! Returns desired tile size in "w" and "h"
|
||||||
//! \~english Returns desired tile size in "w" and "h"
|
|
||||||
//! \~russian Возвращает желаемый размер тайла в "w" и "h"
|
|
||||||
virtual void sizeHint(int & w, int & h) const;
|
virtual void sizeHint(int & w, int & h) const;
|
||||||
|
|
||||||
//! \brief
|
//! Tile has been resized to "w"x"h"
|
||||||
//! \~english Tile has been resized to "w"x"h"
|
|
||||||
//! \~russian Тайл был изменен на "w"x"h"
|
|
||||||
virtual void resizeEvent(int w, int h) {}
|
virtual void resizeEvent(int w, int h) {}
|
||||||
|
|
||||||
//! \brief
|
//! Draw tile with drawer "d" in world-space coordinates
|
||||||
//! \~english Draw tile with drawer "d" in world-space coordinates
|
|
||||||
//! \~russian Рисует тайл отрисовщиком "d" в мировых координатах
|
|
||||||
virtual void drawEvent(PIScreenDrawer * d) {}
|
virtual void drawEvent(PIScreenDrawer * d) {}
|
||||||
|
|
||||||
//! \brief
|
//! Return "true" if you process key
|
||||||
//! \~english Return "true" if you process key
|
|
||||||
//! \~russian Возвращает "true" если вы обрабатываете клавишу
|
|
||||||
virtual bool keyEvent(PIKbdListener::KeyEvent key) { return false; }
|
virtual bool keyEvent(PIKbdListener::KeyEvent key) { return false; }
|
||||||
|
|
||||||
//! \brief
|
//! Return "true" if you process event
|
||||||
//! \~english Return "true" if you process event
|
|
||||||
//! \~russian Возвращает "true" если вы обрабатываете событие
|
|
||||||
virtual bool mouseEvent(PIKbdListener::MouseEvent me) { return false; }
|
virtual bool mouseEvent(PIKbdListener::MouseEvent me) { return false; }
|
||||||
|
|
||||||
//! \brief
|
//! Return "true" if you process wheel
|
||||||
//! \~english Return "true" if you process wheel
|
|
||||||
//! \~russian Возвращает "true" если вы обрабатываете колесо
|
|
||||||
virtual bool wheelEvent(PIKbdListener::WheelEvent we) { return false; }
|
virtual bool wheelEvent(PIKbdListener::WheelEvent we) { return false; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Raises tile event
|
|
||||||
//! \~russian Вызывает событие тайла
|
|
||||||
void raiseEvent(PIScreenTypes::TileEvent e);
|
void raiseEvent(PIScreenTypes::TileEvent e);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets screen reference
|
|
||||||
//! \~russian Устанавливает ссылку на экран
|
|
||||||
void setScreen(PIScreenTypes::PIScreenBase * s);
|
void setScreen(PIScreenTypes::PIScreenBase * s);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Deletes all children
|
|
||||||
//! \~russian Удаляет всех потомков
|
|
||||||
void deleteChildren();
|
void deleteChildren();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Internal draw event
|
|
||||||
//! \~russian Внутреннее событие отрисовки
|
|
||||||
void drawEventInternal(PIScreenDrawer * d);
|
void drawEventInternal(PIScreenDrawer * d);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Performs layout
|
|
||||||
//! \~russian Выполняет компоновку
|
|
||||||
void layout();
|
void layout();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checks if layout is needed
|
|
||||||
//! \~russian Проверяет, нужна ли компоновка
|
|
||||||
bool needLayout() { return size_policy != PIScreenTypes::Ignore; }
|
bool needLayout() { return size_policy != PIScreenTypes::Ignore; }
|
||||||
|
|
||||||
PIVector<PIScreenTile *> tiles;
|
PIVector<PIScreenTile *> tiles;
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piscreentiles.h
|
/*! \file piscreentiles.h
|
||||||
//! \ingroup Console
|
* \ingroup Console
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Various tiles for PIScreen
|
* \~english Various tiles for PIScreen
|
||||||
//! \~russian Различные тайлы для PIScreen
|
* \~russian Различные тайлы для PIScreen
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides ready-to-use tile implementations for common UI elements.
|
|
||||||
//! \~russian Обеспечивает готовые к использованию реализации тайлов для общих элементов UI.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Various tiles for PIScreen
|
Various tiles for PIScreen
|
||||||
@@ -32,326 +30,125 @@
|
|||||||
#include "piscreentile.h"
|
#include "piscreentile.h"
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Tile for displaying simple text content
|
|
||||||
//! \~russian Тайл для отображения простого текстового контента
|
|
||||||
class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileSimple, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileSimple, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief Row type
|
|
||||||
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileSimple
|
|
||||||
//! \~russian Создает TileSimple
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileSimple(const PIString & n = PIString());
|
TileSimple(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileSimple with row
|
|
||||||
//! \~russian Создает TileSimple со строкой
|
|
||||||
//! \param r Row content / Содержимое строки
|
|
||||||
TileSimple(const Row & r);
|
TileSimple(const Row & r);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileSimple() {}
|
virtual ~TileSimple() {}
|
||||||
|
|
||||||
//! \brief Tile content rows
|
|
||||||
PIVector<Row> content;
|
PIVector<Row> content;
|
||||||
|
|
||||||
//! \brief Text alignment
|
|
||||||
PIScreenTypes::Alignment alignment;
|
PIScreenTypes::Alignment alignment;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TileList;
|
class TileList;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Scrollbar for list containers
|
|
||||||
//! \~russian Полоса прокрутки для списков
|
|
||||||
class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile);
|
||||||
friend class TileList;
|
friend class TileList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileScrollBar
|
|
||||||
//! \~russian Создает TileScrollBar
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileScrollBar(const PIString & n = PIString());
|
TileScrollBar(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileScrollBar() {}
|
virtual ~TileScrollBar() {}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets minimum value
|
|
||||||
//! \~russian Устанавливает минимальное значение
|
|
||||||
void setMinimum(int v);
|
void setMinimum(int v);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets maximum value
|
|
||||||
//! \~russian Устанавливает максимальное значение
|
|
||||||
void setMaximum(int v);
|
void setMaximum(int v);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Sets current value
|
|
||||||
//! \~russian Устанавливает текущее значение
|
|
||||||
void setValue(int v);
|
void setValue(int v);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns minimum value
|
|
||||||
//! \~russian Возвращает минимальное значение
|
|
||||||
int minimum() const { return minimum_; }
|
int minimum() const { return minimum_; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns maximum value
|
|
||||||
//! \~russian Возвращает максимальное значение
|
|
||||||
int maximum() const { return maximum_; }
|
int maximum() const { return maximum_; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns current value
|
|
||||||
//! \~russian Возвращает текущее значение
|
|
||||||
int value() const { return value_; }
|
int value() const { return value_; }
|
||||||
|
|
||||||
//! \brief Scrollbar thickness
|
|
||||||
int thickness;
|
int thickness;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Validates scrollbar state
|
|
||||||
//! \~english Validates scrollbar state
|
|
||||||
//! \~russian Проверяет состояние полосы прокрутки
|
|
||||||
void _check();
|
void _check();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles mouse events
|
|
||||||
//! \~russian Обрабатывает события мыши
|
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
||||||
int minimum_, maximum_, value_;
|
int minimum_, maximum_, value_;
|
||||||
PIChar line_char;
|
PIChar line_char;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Scrollable list tile
|
|
||||||
//! \~russian Прокручиваемый список
|
|
||||||
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileList, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileList, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief Selection mode
|
|
||||||
enum SelectionMode {
|
enum SelectionMode {
|
||||||
NoSelection, //!< No selection / Без выделения
|
NoSelection,
|
||||||
SingleSelection, //!< Single item selection / Выделение одного элемента
|
SingleSelection,
|
||||||
MultiSelection //!< Multiple items selection / Выделение нескольких элементов
|
MultiSelection
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Event type
|
|
||||||
enum EventType {
|
enum EventType {
|
||||||
SelectionChanged, //!< Selection changed / Выделение изменено
|
SelectionChanged,
|
||||||
RowPressed //!< Row pressed / Строка нажата
|
RowPressed
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileList
|
|
||||||
//! \~russian Создает TileList
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
//! \param sm Selection mode / Режим выделения
|
|
||||||
TileList(const PIString & n = PIString(), SelectionMode sm = NoSelection);
|
TileList(const PIString & n = PIString(), SelectionMode sm = NoSelection);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileList() {}
|
virtual ~TileList() {}
|
||||||
|
|
||||||
//! \brief Row type
|
|
||||||
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
|
||||||
|
|
||||||
//! \brief List content
|
|
||||||
PIDeque<Row> content;
|
PIDeque<Row> content;
|
||||||
|
|
||||||
//! \brief Text alignment
|
|
||||||
PIScreenTypes::Alignment alignment;
|
PIScreenTypes::Alignment alignment;
|
||||||
|
|
||||||
//! \brief Selection mode
|
|
||||||
SelectionMode selection_mode;
|
SelectionMode selection_mode;
|
||||||
|
|
||||||
//! \brief Selected indices
|
|
||||||
PISet<int> selected;
|
PISet<int> selected;
|
||||||
|
|
||||||
//! \brief Line height
|
|
||||||
int lhei, cur, offset;
|
int lhei, cur, offset;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Called when resized
|
|
||||||
//! \~russian Вызывается при изменении размера
|
|
||||||
void resizeEvent(int w, int h) override;
|
void resizeEvent(int w, int h) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles key events
|
|
||||||
//! \~russian Обрабатывает события клавиатуры
|
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles mouse events
|
|
||||||
//! \~russian Обрабатывает события мыши
|
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles wheel events
|
|
||||||
//! \~russian Обрабатывает события колеса
|
|
||||||
bool wheelEvent(PIKbdListener::WheelEvent we) override;
|
bool wheelEvent(PIKbdListener::WheelEvent we) override;
|
||||||
TileScrollBar * scroll;
|
TileScrollBar * scroll;
|
||||||
bool mouse_sel;
|
bool mouse_sel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Clickable button tile
|
|
||||||
//! \~russian Кликабельная кнопка
|
|
||||||
class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileButton, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileButton, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileButton
|
|
||||||
//! \~russian Создает TileButton
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileButton(const PIString & n = PIString());
|
TileButton(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileButton() {}
|
virtual ~TileButton() {}
|
||||||
|
|
||||||
//! \brief Event type
|
|
||||||
enum EventType {
|
enum EventType {
|
||||||
ButtonClicked //!< Button clicked / Кнопка нажата
|
ButtonClicked
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Button format
|
|
||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
|
|
||||||
//! \brief Button text
|
|
||||||
PIString text;
|
PIString text;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles key events
|
|
||||||
//! \~russian Обрабатывает события клавиатуры
|
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles mouse events
|
|
||||||
//! \~russian Обрабатывает события мыши
|
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Group of buttons with selection
|
|
||||||
//! \~russian Группа кнопок с выбором
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileButtons, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileButtons, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileButtons
|
|
||||||
//! \~russian Создает TileButtons
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileButtons(const PIString & n = PIString());
|
TileButtons(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileButtons() {}
|
virtual ~TileButtons() {}
|
||||||
|
|
||||||
//! \brief Event type
|
|
||||||
enum EventType {
|
enum EventType {
|
||||||
ButtonSelected //!< Button selected / Кнопка выбрана
|
ButtonSelected
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Button type
|
|
||||||
typedef PIPair<PIString, PIScreenTypes::CellFormat> Button;
|
typedef PIPair<PIString, PIScreenTypes::CellFormat> Button;
|
||||||
|
|
||||||
//! \brief Button alignment
|
|
||||||
PIScreenTypes::Alignment alignment;
|
PIScreenTypes::Alignment alignment;
|
||||||
|
|
||||||
//! \brief Button content
|
|
||||||
PIVector<Button> content;
|
PIVector<Button> content;
|
||||||
|
|
||||||
//! \brief Current selection
|
|
||||||
int cur;
|
int cur;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles key events
|
|
||||||
//! \~russian Обрабатывает события клавиатуры
|
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles mouse events
|
|
||||||
//! \~russian Обрабатывает события мыши
|
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
||||||
|
|
||||||
//! \brief Button rectangle
|
|
||||||
struct Rect {
|
struct Rect {
|
||||||
Rect(int _x0 = 0, int _y0 = 0, int _x1 = 0, int _y1 = 0): x0(_x0), y0(_y0), x1(_x1), y1(_y1) {}
|
Rect(int _x0 = 0, int _y0 = 0, int _x1 = 0, int _y1 = 0): x0(_x0), y0(_y0), x1(_x1), y1(_y1) {}
|
||||||
int x0, y0, x1, y1;
|
int x0, y0, x1, y1;
|
||||||
@@ -360,192 +157,74 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checkbox with toggle state
|
|
||||||
//! \~russian Флажок с переключаемым состоянием
|
|
||||||
class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileCheck, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileCheck, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileCheck
|
|
||||||
//! \~russian Создает TileCheck
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileCheck(const PIString & n = PIString());
|
TileCheck(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileCheck() {}
|
virtual ~TileCheck() {}
|
||||||
|
|
||||||
//! \brief Event type
|
|
||||||
enum EventType {
|
enum EventType {
|
||||||
Toggled //!< State toggled / Состояние переключено
|
Toggled
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Checkbox format
|
|
||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
|
|
||||||
//! \brief Checkbox text
|
|
||||||
PIString text;
|
PIString text;
|
||||||
|
|
||||||
//! \brief Checkbox state
|
|
||||||
bool toggled;
|
bool toggled;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles key events
|
|
||||||
//! \~russian Обрабатывает события клавиатуры
|
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles mouse events
|
|
||||||
//! \~russian Обрабатывает события мыши
|
|
||||||
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
bool mouseEvent(PIKbdListener::MouseEvent me) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Progress bar for displaying progress
|
|
||||||
//! \~russian Индикатор прогресса
|
|
||||||
class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileProgress, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileProgress, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileProgress
|
|
||||||
//! \~russian Создает TileProgress
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileProgress(const PIString & n = PIString());
|
TileProgress(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileProgress() {}
|
virtual ~TileProgress() {}
|
||||||
|
|
||||||
//! \brief Progress format
|
|
||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
|
|
||||||
//! \brief Prefix text
|
|
||||||
PIString prefix;
|
PIString prefix;
|
||||||
|
|
||||||
//! \brief Suffix text
|
|
||||||
PIString suffix;
|
PIString suffix;
|
||||||
|
|
||||||
//! \brief Maximum value
|
|
||||||
double maximum;
|
double maximum;
|
||||||
|
|
||||||
//! \brief Current value
|
|
||||||
double value;
|
double value;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Tile for displaying console output
|
|
||||||
//! \~russian Тайл для отображения консольного вывода
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TilePICout: public TileList {
|
class PIP_CONSOLE_EXPORT TilePICout: public TileList {
|
||||||
PIOBJECT_SUBCLASS(TilePICout, PIScreenTile);
|
PIOBJECT_SUBCLASS(TilePICout, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TilePICout
|
|
||||||
//! \~russian Создает TilePICout
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TilePICout(const PIString & n = PIString());
|
TilePICout(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TilePICout() {}
|
virtual ~TilePICout() {}
|
||||||
|
|
||||||
//! \brief Output format
|
|
||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
|
|
||||||
//! \brief Maximum lines
|
|
||||||
int max_lines;
|
int max_lines;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles key events
|
|
||||||
//! \~russian Обрабатывает события клавиатуры
|
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Text input tile
|
|
||||||
//! \~russian Тайл текстового ввода
|
|
||||||
|
|
||||||
class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile {
|
class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile {
|
||||||
PIOBJECT_SUBCLASS(TileInput, PIScreenTile);
|
PIOBJECT_SUBCLASS(TileInput, PIScreenTile);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileInput
|
|
||||||
//! \~russian Создает TileInput
|
|
||||||
//! \param n Tile name / Имя тайла
|
|
||||||
TileInput(const PIString & n = PIString());
|
TileInput(const PIString & n = PIString());
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~TileInput() {}
|
virtual ~TileInput() {}
|
||||||
|
|
||||||
//! \brief Input format
|
|
||||||
PIScreenTypes::CellFormat format;
|
PIScreenTypes::CellFormat format;
|
||||||
|
|
||||||
//! \brief Input text
|
|
||||||
PIString text;
|
PIString text;
|
||||||
|
|
||||||
//! \brief Maximum text length
|
|
||||||
int max_length;
|
int max_length;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief
|
|
||||||
//! \~english Calculates tile size hint
|
|
||||||
//! \~russian Вычисляет рекомендуемый размер тайла
|
|
||||||
void sizeHint(int & w, int & h) const override;
|
void sizeHint(int & w, int & h) const override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Draws tile content
|
|
||||||
//! \~russian Рисует содержимое тайла
|
|
||||||
void drawEvent(PIScreenDrawer * d) override;
|
void drawEvent(PIScreenDrawer * d) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles key events
|
|
||||||
//! \~russian Обрабатывает события клавиатуры
|
|
||||||
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
bool keyEvent(PIKbdListener::KeyEvent key) override;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Resets cursor position
|
|
||||||
//! \~russian Сбрасывает позицию курсора
|
|
||||||
void reserCursor();
|
void reserCursor();
|
||||||
int cur, offset;
|
int cur, offset;
|
||||||
bool inv;
|
bool inv;
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piscreentypes.h
|
/*! \file piscreentypes.h
|
||||||
//! \ingroup Console
|
* \ingroup Console
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Types for PIScreen
|
* \~english Types for PIScreen
|
||||||
//! \~russian Типы для PIScreen
|
* \~russian Типы для PIScreen
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides common types used by screen tiles and drawer.
|
|
||||||
//! \~russian Обеспечивает общие типы, используемые тайлами и отрисовщиком экрана.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Types for PIScreen
|
Types for PIScreen
|
||||||
@@ -36,9 +34,7 @@ class PIScreenTile;
|
|||||||
|
|
||||||
namespace PIScreenTypes {
|
namespace PIScreenTypes {
|
||||||
|
|
||||||
//! \brief Color for chars or background
|
//! Color for chars or background
|
||||||
//! \~english Console color values
|
|
||||||
//! \~russian Значения цветов консоли
|
|
||||||
enum Color {
|
enum Color {
|
||||||
Default /** Default */,
|
Default /** Default */,
|
||||||
Black /** Black */,
|
Black /** Black */,
|
||||||
@@ -52,9 +48,7 @@ enum Color {
|
|||||||
Transparent /** Save previous color */
|
Transparent /** Save previous color */
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Flags for chars
|
//! Flags for chars
|
||||||
//! \~english Character formatting flags
|
|
||||||
//! \~russian Флаги форматирования символов
|
|
||||||
enum CharFlag {
|
enum CharFlag {
|
||||||
Bold /** Bold or bright */ = 0x1,
|
Bold /** Bold or bright */ = 0x1,
|
||||||
Blink /** Blink text */ = 0x2,
|
Blink /** Blink text */ = 0x2,
|
||||||
@@ -62,18 +56,14 @@ enum CharFlag {
|
|||||||
Inverse = 0x08
|
Inverse = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Alignment
|
//! Alignment
|
||||||
//! \~english Text alignment modes
|
|
||||||
//! \~russian Режимы выравнивания текста
|
|
||||||
enum Alignment {
|
enum Alignment {
|
||||||
Left /** Left */,
|
Left /** Left */,
|
||||||
Center /** Center */,
|
Center /** Center */,
|
||||||
Right /** Right */
|
Right /** Right */
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Size policy
|
//! Size policy
|
||||||
//! \~english Tile sizing policies
|
|
||||||
//! \~russian Политики размеров тайлов
|
|
||||||
enum SizePolicy {
|
enum SizePolicy {
|
||||||
Fixed /** Fixed size */,
|
Fixed /** Fixed size */,
|
||||||
Preferred /** Preferred size */,
|
Preferred /** Preferred size */,
|
||||||
@@ -81,17 +71,13 @@ enum SizePolicy {
|
|||||||
Ignore /** Ignore layout logic */
|
Ignore /** Ignore layout logic */
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Direction
|
//! Direction
|
||||||
//! \~english Layout directions
|
|
||||||
//! \~russian Направления компоновки
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
Horizontal /** Horizontal */,
|
Horizontal /** Horizontal */,
|
||||||
Vertical /** Vertical */
|
Vertical /** Vertical */
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Focus flags
|
//! Focus flags
|
||||||
//! \~english Tile focus behavior flags
|
|
||||||
//! \~russian Флаги поведения фокуса тайла
|
|
||||||
enum FocusFlag {
|
enum FocusFlag {
|
||||||
CanHasFocus /** Tile can has focus */ = 0x1,
|
CanHasFocus /** Tile can has focus */ = 0x1,
|
||||||
NextByTab /** Focus passed to next tile by tab key */ = 0x2,
|
NextByTab /** Focus passed to next tile by tab key */ = 0x2,
|
||||||
@@ -106,19 +92,8 @@ enum FocusFlag {
|
|||||||
typedef PIFlags<CharFlag> CharFlags;
|
typedef PIFlags<CharFlag> CharFlags;
|
||||||
typedef PIFlags<FocusFlag> FocusFlags;
|
typedef PIFlags<FocusFlag> FocusFlags;
|
||||||
|
|
||||||
//! \brief Cell format union
|
|
||||||
//! \~english Packed cell formatting data
|
|
||||||
//! \~russian Упакованные данные форматирования ячейки
|
|
||||||
|
|
||||||
union PIP_CONSOLE_EXPORT CellFormat {
|
union PIP_CONSOLE_EXPORT CellFormat {
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs CellFormat from raw value
|
|
||||||
//! \~russian Создает CellFormat из сырого значения
|
|
||||||
CellFormat(ushort f = 0) { raw_format = f; }
|
CellFormat(ushort f = 0) { raw_format = f; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs CellFormat from color and flags
|
|
||||||
//! \~russian Создает CellFormat из цвета и флагов
|
|
||||||
CellFormat(Color col_char, Color col_back = Default, CharFlags flags_ = 0) {
|
CellFormat(Color col_char, Color col_back = Default, CharFlags flags_ = 0) {
|
||||||
color_char = col_char;
|
color_char = col_char;
|
||||||
color_back = col_back;
|
color_back = col_back;
|
||||||
@@ -130,49 +105,19 @@ union PIP_CONSOLE_EXPORT CellFormat {
|
|||||||
ushort color_back: 4;
|
ushort color_back: 4;
|
||||||
ushort flags : 8;
|
ushort flags : 8;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Equality operator
|
|
||||||
//! \~russian Оператор равенства
|
|
||||||
bool operator==(const CellFormat & c) const { return raw_format == c.raw_format; }
|
bool operator==(const CellFormat & c) const { return raw_format == c.raw_format; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Inequality operator
|
|
||||||
//! \~russian Оператор неравенства
|
|
||||||
bool operator!=(const CellFormat & c) const { return raw_format != c.raw_format; }
|
bool operator!=(const CellFormat & c) const { return raw_format != c.raw_format; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Screen cell
|
|
||||||
//! \~english Single character cell with formatting
|
|
||||||
//! \~russian Одна символьная ячейка с форматированием
|
|
||||||
struct PIP_CONSOLE_EXPORT Cell {
|
struct PIP_CONSOLE_EXPORT Cell {
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs Cell
|
|
||||||
//! \~russian Создает Cell
|
|
||||||
Cell(PIChar c = PIChar(' '), CellFormat f = CellFormat()) {
|
Cell(PIChar c = PIChar(' '), CellFormat f = CellFormat()) {
|
||||||
symbol = c;
|
symbol = c;
|
||||||
format = f;
|
format = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Cell format
|
|
||||||
CellFormat format;
|
CellFormat format;
|
||||||
|
|
||||||
//! \brief Cell character
|
|
||||||
PIChar symbol;
|
PIChar symbol;
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Equality operator
|
|
||||||
//! \~russian Оператор равенства
|
|
||||||
bool operator==(const Cell & c) const { return format == c.format && symbol == c.symbol; }
|
bool operator==(const Cell & c) const { return format == c.format && symbol == c.symbol; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Inequality operator
|
|
||||||
//! \~russian Оператор неравенства
|
|
||||||
bool operator!=(const Cell & c) const { return format != c.format || symbol != c.symbol; }
|
bool operator!=(const Cell & c) const { return format != c.format || symbol != c.symbol; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Assignment operator
|
|
||||||
//! \~russian Оператор присваивания
|
|
||||||
Cell & operator=(const Cell & c) {
|
Cell & operator=(const Cell & c) {
|
||||||
symbol = c.symbol;
|
symbol = c.symbol;
|
||||||
if (c.format.color_back == Transparent) {
|
if (c.format.color_back == Transparent) {
|
||||||
@@ -184,52 +129,18 @@ struct PIP_CONSOLE_EXPORT Cell {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Tile event data
|
|
||||||
//! \~english Event data passed to tiles
|
|
||||||
//! \~russian Данные события, передаваемые тайлам
|
|
||||||
struct PIP_CONSOLE_EXPORT TileEvent {
|
struct PIP_CONSOLE_EXPORT TileEvent {
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs TileEvent
|
|
||||||
//! \~russian Создает TileEvent
|
|
||||||
//! \param t Event type / Тип события
|
|
||||||
//! \param d Event data / Данные события
|
|
||||||
TileEvent(int t = -1, const PIVariant & d = PIVariant()): type(t), data(d) {}
|
TileEvent(int t = -1, const PIVariant & d = PIVariant()): type(t), data(d) {}
|
||||||
|
|
||||||
//! \brief Event type
|
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
//! \brief Event data
|
|
||||||
PIVariant data;
|
PIVariant data;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Base screen interface
|
|
||||||
//! \~english Base interface for screen tiles
|
|
||||||
//! \~russian Базовый интерфейс для экранных тайлов
|
|
||||||
class PIP_CONSOLE_EXPORT PIScreenBase {
|
class PIP_CONSOLE_EXPORT PIScreenBase {
|
||||||
public:
|
public:
|
||||||
//! \brief
|
|
||||||
//! \~english Constructs PIScreenBase
|
|
||||||
//! \~russian Создает PIScreenBase
|
|
||||||
PIScreenBase() {}
|
PIScreenBase() {}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PIScreenBase() {}
|
virtual ~PIScreenBase() {}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles internal tile event
|
|
||||||
//! \~russian Обрабатывает внутреннее событие тайла
|
|
||||||
virtual void tileEventInternal(PIScreenTile *, TileEvent) {}
|
virtual void tileEventInternal(PIScreenTile *, TileEvent) {}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles tile removal
|
|
||||||
//! \~russian Обрабатывает удаление тайла
|
|
||||||
virtual void tileRemovedInternal(PIScreenTile *) {}
|
virtual void tileRemovedInternal(PIScreenTile *) {}
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Handles tile focus change
|
|
||||||
//! \~russian Обрабатывает изменение фокуса тайла
|
|
||||||
virtual void tileSetFocusInternal(PIScreenTile *) {}
|
virtual void tileSetFocusInternal(PIScreenTile *) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
//! \file piterminal.h
|
/*! \file piterminal.h
|
||||||
//! \ingroup Console
|
* \ingroup Console
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Virtual terminal
|
* \~english Virtual terminal
|
||||||
//! \~russian Виртуальный терминал
|
* \~russian Виртуальный терминал
|
||||||
//! \details
|
*/
|
||||||
//! \~english Provides terminal emulation for reading console input and output.
|
|
||||||
//! \~russian Обеспечивает эмуляцию терминала для чтения ввода и вывода консоли.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Virtual terminal
|
Virtual terminal
|
||||||
@@ -37,66 +35,22 @@ class PIP_CONSOLE_EXPORT PITerminal: public PIThread {
|
|||||||
PIOBJECT_SUBCLASS(PITerminal, PIThread);
|
PIOBJECT_SUBCLASS(PITerminal, PIThread);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \brief
|
//! Constructs %PITerminal
|
||||||
//! \~english Constructs PITerminal
|
|
||||||
//! \~russian Создает PITerminal
|
|
||||||
PITerminal();
|
PITerminal();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
~PITerminal();
|
~PITerminal();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns number of columns
|
|
||||||
//! \~russian Возвращает количество колонок
|
|
||||||
int columns() const { return size_x; }
|
int columns() const { return size_x; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns number of rows
|
|
||||||
//! \~russian Возвращает количество строк
|
|
||||||
int rows() const { return size_y; }
|
int rows() const { return size_y; }
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Resizes terminal
|
|
||||||
//! \~russian Изменяет размер терминала
|
|
||||||
//! \param cols Number of columns / Количество колонок
|
|
||||||
//! \param rows Number of rows / Количество строк
|
|
||||||
bool resize(int cols, int rows);
|
bool resize(int cols, int rows);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Writes data to terminal
|
|
||||||
//! \~russian Записывает данные в терминал
|
|
||||||
void write(const PIByteArray & d);
|
void write(const PIByteArray & d);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Writes special key to terminal
|
|
||||||
//! \~russian Записывает специальную клавишу в терминал
|
|
||||||
void write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers m);
|
void write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers m);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Writes key event to terminal
|
|
||||||
//! \~russian Записывает событие клавиши в терминал
|
|
||||||
void write(PIKbdListener::KeyEvent ke);
|
void write(PIKbdListener::KeyEvent ke);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns terminal content
|
|
||||||
//! \~russian Возвращает содержимое терминала
|
|
||||||
PIVector<PIVector<PIScreenTypes::Cell>> content();
|
PIVector<PIVector<PIScreenTypes::Cell>> content();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Checks if key is special
|
|
||||||
//! \~russian Проверяет, является ли клавиша специальной
|
|
||||||
static bool isSpecialKey(int k);
|
static bool isSpecialKey(int k);
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Initializes terminal
|
|
||||||
//! \~russian Инициализирует терминал
|
|
||||||
bool initialize();
|
bool initialize();
|
||||||
|
|
||||||
//! \brief
|
|
||||||
//! \~english Destroys terminal
|
|
||||||
//! \~russian Уничтожает терминал
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
//! \addtogroup Containers
|
/*! \file piset.h
|
||||||
//! \{
|
* \brief Set container
|
||||||
//! \file piset.h
|
*
|
||||||
//! \brief
|
* This file declare PISet
|
||||||
//! \~english Declares \a PISet
|
*/
|
||||||
//! \~russian Объявление \a PISet
|
|
||||||
//! \~\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
|
PIP - Platform Independent Primitives
|
||||||
Set container
|
Set container
|
||||||
@@ -36,33 +27,13 @@
|
|||||||
|
|
||||||
#include "pimap.h"
|
#include "pimap.h"
|
||||||
|
|
||||||
//! \addtogroup Containers
|
/*! \brief Set of any type
|
||||||
//! \{
|
* \details This class used to store collection of unique elements
|
||||||
//! \class PISet
|
* of any type. You can only add values to set with \a operator<< or
|
||||||
//! \brief
|
* with function \a insert(). You can discover if value already in
|
||||||
//! \~english A set is a collection of unique elements.
|
* set with \a operator[] or with function \a find(). These function
|
||||||
//! \~russian Множество - это коллекция уникальных элементов.
|
* has logarithmic complexity.
|
||||||
//! \~\}
|
*/
|
||||||
//! \details
|
|
||||||
//! \~english
|
|
||||||
//! This class is used to store a collection of unique elements of any type.
|
|
||||||
//! You can add values to the set using \a operator<< or the \a insert() function.
|
|
||||||
//! You can check if a value already exists in the set using \a operator[] or the \a contains() function.
|
|
||||||
//! These operations have logarithmic complexity.
|
|
||||||
//! To iterate over all elements, use STL-style iterators \a begin() and \a end().
|
|
||||||
//!
|
|
||||||
//! The set is implemented as a wrapper around \a PIMap, where keys are the elements
|
|
||||||
//! and values are dummy byte values (used only for storage).
|
|
||||||
//! \~russian
|
|
||||||
//! Этот класс используется для хранения коллекции уникальных элементов любого типа.
|
|
||||||
//! Вы можете добавлять значения в множество с помощью \a operator<< или функции \a insert().
|
|
||||||
//! Вы можете проверить, существует ли значение в множестве, используя \a operator[] или функцию \a contains().
|
|
||||||
//! Эти операции имеют логарифмическую сложность.
|
|
||||||
//! Для перебора всех элементов используйте итераторы в стиле STL \a begin() и \a end().
|
|
||||||
//!
|
|
||||||
//! Множество реализовано как обёртка над \a PIMap, где ключами являются элементы,
|
|
||||||
//! а значениями являются фиктивные байтовые значения (используются только для хранения).
|
|
||||||
//! \~\sa \a PIMap, \a PIVector
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class PISet: public PIMap<T, uchar> {
|
class PISet: public PIMap<T, uchar> {
|
||||||
typedef PIMap<T, uchar> _CSet;
|
typedef PIMap<T, uchar> _CSet;
|
||||||
@@ -72,31 +43,26 @@ class PISet: public PIMap<T, uchar> {
|
|||||||
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PISet<T1> & v);
|
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PISet<T1> & v);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs an empty set.
|
//! Contructs an empty set
|
||||||
//! \~russian Создает пустое множество.
|
|
||||||
PISet() {}
|
PISet() {}
|
||||||
|
|
||||||
//! \~english Constructs a set with one element `value`.
|
//! Contructs set with one element "value"
|
||||||
//! \~russian Создает множество с одним элементом `value`.
|
|
||||||
explicit PISet(const T & value) { _CSet::insert(value, 0); }
|
explicit PISet(const T & value) { _CSet::insert(value, 0); }
|
||||||
|
|
||||||
//! \~english Constructs a set with two elements `v0` and `v1`.
|
//! Contructs set with elements "v0" and "v1"
|
||||||
//! \~russian Создает множество с двумя элементами `v0` и `v1`.
|
|
||||||
PISet(const T & v0, const T & v1) {
|
PISet(const T & v0, const T & v1) {
|
||||||
_CSet::insert(v0, 0);
|
_CSet::insert(v0, 0);
|
||||||
_CSet::insert(v1, 0);
|
_CSet::insert(v1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Constructs a set with three elements `v0`, `v1` and `v2`.
|
//! Contructs set with elements "v0", "v1" and "v2"
|
||||||
//! \~russian Создает множество с тремя элементами `v0`, `v1` и `v2`.
|
|
||||||
PISet(const T & v0, const T & v1, const T & v2) {
|
PISet(const T & v0, const T & v1, const T & v2) {
|
||||||
_CSet::insert(v0, 0);
|
_CSet::insert(v0, 0);
|
||||||
_CSet::insert(v1, 0);
|
_CSet::insert(v1, 0);
|
||||||
_CSet::insert(v2, 0);
|
_CSet::insert(v2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Constructs a set with four elements `v0`, `v1`, `v2` and `v3`.
|
//! Contructs set with elements "v0", "v1", "v2" and "v3"
|
||||||
//! \~russian Создает множество с четырьмя элементами `v0`, `v1`, `v2` и `v3`.
|
|
||||||
PISet(const T & v0, const T & v1, const T & v2, const T & v3) {
|
PISet(const T & v0, const T & v1, const T & v2, const T & v3) {
|
||||||
_CSet::insert(v0, 0);
|
_CSet::insert(v0, 0);
|
||||||
_CSet::insert(v1, 0);
|
_CSet::insert(v1, 0);
|
||||||
@@ -188,8 +154,7 @@ public:
|
|||||||
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, _CSet::size()); }
|
inline const_iterator end() const { return const_iterator(this, _CSet::size()); }
|
||||||
|
|
||||||
//! \~english Constructs a set from a vector of elements.
|
//! Contructs set from vector of elements
|
||||||
//! \~russian Создает множество из вектора элементов.
|
|
||||||
explicit PISet(const PIVector<T> & values) {
|
explicit PISet(const PIVector<T> & values) {
|
||||||
if (values.isEmpty()) return;
|
if (values.isEmpty()) return;
|
||||||
for (int i = 0; i < values.size_s(); ++i) {
|
for (int i = 0; i < values.size_s(); ++i) {
|
||||||
@@ -197,8 +162,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Constructs a set from a deque of elements.
|
//! Contructs set from deque of elements
|
||||||
//! \~russian Создает множество из deque элементов.
|
|
||||||
explicit PISet(const PIDeque<T> & values) {
|
explicit PISet(const PIDeque<T> & values) {
|
||||||
if (values.isEmpty()) return;
|
if (values.isEmpty()) return;
|
||||||
for (int i = 0; i < values.size_s(); ++i) {
|
for (int i = 0; i < values.size_s(); ++i) {
|
||||||
@@ -208,8 +172,6 @@ public:
|
|||||||
|
|
||||||
typedef T key_type;
|
typedef T key_type;
|
||||||
|
|
||||||
//! \~english Inserts element `t` into the set.
|
|
||||||
//! \~russian Вставляет элемент `t` в множество.
|
|
||||||
PISet<T> & operator<<(const T & t) {
|
PISet<T> & operator<<(const T & t) {
|
||||||
_CSet::insert(t, 0);
|
_CSet::insert(t, 0);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -223,62 +185,52 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Tests if element `t` exists in the set.
|
//! \~english Tests if element `key` exists in the set.
|
||||||
//! \~russian Проверяет наличие элемента `t` в множестве.
|
//! \~russian Проверяет наличие элемента `key` в массиве.
|
||||||
inline bool contains(const T & t) const { return _CSet::contains(t); }
|
inline bool contains(const T & t) const { return _CSet::contains(t); }
|
||||||
|
|
||||||
//! \~english Tests if element `t` exists in the set.
|
//! Returns if element "t" exists in this set
|
||||||
//! \~russian Проверяет наличие элемента `t` в множестве.
|
|
||||||
bool operator[](const T & t) const { return _CSet::contains(t); }
|
bool operator[](const T & t) const { return _CSet::contains(t); }
|
||||||
|
|
||||||
//! \~english Removes element `t` from the set.
|
//! Returns if element "t" exists in this set
|
||||||
//! \~russian Удаляет элемент `t` из множества.
|
|
||||||
PISet<T> & remove(const T & t) {
|
PISet<T> & remove(const T & t) {
|
||||||
_CSet::remove(t);
|
_CSet::remove(t);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the union of this set with set `v`.
|
//! Unite set with "v"
|
||||||
//! \~russian Возвращает объединение этого множества с множеством `v`.
|
|
||||||
PISet<T> & unite(const PISet<T> & v) {
|
PISet<T> & unite(const PISet<T> & v) {
|
||||||
for (const auto & i: v)
|
for (const auto & i: v)
|
||||||
_CSet::insert(i, 0);
|
_CSet::insert(i, 0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the difference of this set and set `v`.
|
//! Subtract set with "v"
|
||||||
//! \~russian Возвращает разность этого множества и множества `v`.
|
|
||||||
PISet<T> & subtract(const PISet<T> & v) {
|
PISet<T> & subtract(const PISet<T> & v) {
|
||||||
for (const auto & i: v)
|
for (const auto & i: v)
|
||||||
_CSet::remove(i);
|
_CSet::remove(i);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the intersection of this set with set `v`.
|
//! Intersect set with "v"
|
||||||
//! \~russian Возвращает пересечение этого множества с множеством `v`.
|
|
||||||
PISet<T> & intersect(const PISet<T> & v) {
|
PISet<T> & intersect(const PISet<T> & v) {
|
||||||
_CSet::removeWhere([&v](const T & k, uchar) { return !v.contains(k); });
|
_CSet::removeWhere([&v](const T & k, uchar) { return !v.contains(k); });
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the union of this set with set `v`.
|
//! Unite set with "v"
|
||||||
//! \~russian Возвращает объединение этого множества с множеством `v`.
|
|
||||||
PISet<T> & operator+=(const PISet<T> & v) { return unite(v); }
|
PISet<T> & operator+=(const PISet<T> & v) { return unite(v); }
|
||||||
|
|
||||||
//! \~english Returns the union of this set with set `v`.
|
//! Unite set with "v"
|
||||||
//! \~russian Возвращает объединение этого множества с множеством `v`.
|
|
||||||
PISet<T> & operator|=(const PISet<T> & v) { return unite(v); }
|
PISet<T> & operator|=(const PISet<T> & v) { return unite(v); }
|
||||||
|
|
||||||
//! \~english Returns the difference of this set and set `v`.
|
//! Subtract set with "v"
|
||||||
//! \~russian Возвращает разность этого множества и множества `v`.
|
|
||||||
PISet<T> & operator-=(const PISet<T> & v) { return subtract(v); }
|
PISet<T> & operator-=(const PISet<T> & v) { return subtract(v); }
|
||||||
|
|
||||||
//! \~english Returns the intersection of this set with set `v`.
|
//! Intersect set with "v"
|
||||||
//! \~russian Возвращает пересечение этого множества с множеством `v`.
|
|
||||||
PISet<T> & operator&=(const PISet<T> & v) { return intersect(v); }
|
PISet<T> & operator&=(const PISet<T> & v) { return intersect(v); }
|
||||||
|
|
||||||
//! \~english Converts the set to a vector.
|
//! Returns content of set as PIVector
|
||||||
//! \~russian Преобразует множество в вектор.
|
|
||||||
PIVector<T> toVector() const {
|
PIVector<T> toVector() const {
|
||||||
PIVector<T> ret;
|
PIVector<T> ret;
|
||||||
for (const auto & i: *this)
|
for (const auto & i: *this)
|
||||||
@@ -286,8 +238,7 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Converts the set to a deque.
|
//! Returns content of set as PIDeque
|
||||||
//! \~russian Преобразует множество в deque.
|
|
||||||
PIDeque<T> toDeque() const {
|
PIDeque<T> toDeque() const {
|
||||||
PIDeque<T> ret;
|
PIDeque<T> ret;
|
||||||
for (const auto & i: *this)
|
for (const auto & i: *this)
|
||||||
@@ -297,8 +248,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Returns the union of two sets.
|
//! \relatesalso PISet \brief Returns unite of two sets
|
||||||
//! \~russian Возвращает объединение двух множеств.
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
PISet<T> operator+(const PISet<T> & v0, const PISet<T> & v1) {
|
PISet<T> operator+(const PISet<T> & v0, const PISet<T> & v1) {
|
||||||
PISet<T> ret(v0);
|
PISet<T> ret(v0);
|
||||||
@@ -306,8 +256,7 @@ PISet<T> operator+(const PISet<T> & v0, const PISet<T> & v1) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the difference of two sets.
|
//! \relatesalso PISet \brief Returns subtraction of two sets
|
||||||
//! \~russian Возвращает разность двух множеств.
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
PISet<T> operator-(const PISet<T> & v0, const PISet<T> & v1) {
|
PISet<T> operator-(const PISet<T> & v0, const PISet<T> & v1) {
|
||||||
PISet<T> ret(v0);
|
PISet<T> ret(v0);
|
||||||
@@ -315,8 +264,7 @@ PISet<T> operator-(const PISet<T> & v0, const PISet<T> & v1) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the union of two sets.
|
//! \relatesalso PISet \brief Returns unite of two sets
|
||||||
//! \~russian Возвращает объединение двух множеств.
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
PISet<T> operator|(const PISet<T> & v0, const PISet<T> & v1) {
|
PISet<T> operator|(const PISet<T> & v0, const PISet<T> & v1) {
|
||||||
PISet<T> ret(v0);
|
PISet<T> ret(v0);
|
||||||
@@ -324,8 +272,7 @@ PISet<T> operator|(const PISet<T> & v0, const PISet<T> & v1) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the intersection of two sets.
|
//! \relatesalso PISet \brief Returns intersetion of two sets
|
||||||
//! \~russian Возвращает пересечение двух множеств.
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
PISet<T> operator&(const PISet<T> & v0, const PISet<T> & v1) {
|
PISet<T> operator&(const PISet<T> & v0, const PISet<T> & v1) {
|
||||||
PISet<T> ret(v0);
|
PISet<T> ret(v0);
|
||||||
@@ -334,9 +281,6 @@ PISet<T> operator&(const PISet<T> & v0, const PISet<T> & v1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \relatesalso PICout
|
|
||||||
//! \~english Output operator to \a PICout
|
|
||||||
//! \~russian Оператор вывода в \a PICout
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline PICout operator<<(PICout s, const PISet<Type> & v) {
|
inline PICout operator<<(PICout s, const PISet<Type> & v) {
|
||||||
s.space();
|
s.space();
|
||||||
@@ -353,6 +297,4 @@ inline PICout operator<<(PICout s, const PISet<Type> & v) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \}
|
|
||||||
|
|
||||||
#endif // PISET_H
|
#endif // PISET_H
|
||||||
|
|||||||
@@ -835,8 +835,8 @@ public:
|
|||||||
//! piCout << v.contains({1,4}); // true
|
//! piCout << v.contains({1,4}); // true
|
||||||
//! piCout << v.contains({1,5}); // false
|
//! piCout << v.contains({1,5}); // false
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a every(), \a any(), \a entries(), \a forEach()
|
//! \~\sa \a every(), \a any(), \a entries(), \a forEach(), \a contains()
|
||||||
inline bool contains(const PIVector<T> & v, ssize_t start = 0) const {
|
inline bool containsAll(const PIVector<T> & v, ssize_t start = 0) const {
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = piv_size + start;
|
start = piv_size + start;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
@@ -854,6 +854,24 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Tests if any element of `v` exists in the array.
|
||||||
|
//! \~russian Проверяет наличие хотя бы одного из элементов `v` в массиве.
|
||||||
|
//! \~\sa \a containsAll(), \a contains()
|
||||||
|
inline bool containsAny(const PIVector<T> & v, ssize_t start = 0) const {
|
||||||
|
if (start < 0) {
|
||||||
|
start = piv_size + start;
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
}
|
||||||
|
for (const T & e: v) {
|
||||||
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
|
if (e == piv_data[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//! \~english Count elements equal `e` in the array.
|
//! \~english Count elements equal `e` in the array.
|
||||||
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
|
//! \~russian Подсчитывает количество элементов, совпадающих с элементом `e` в массиве.
|
||||||
//! \~\details
|
//! \~\details
|
||||||
@@ -1303,14 +1321,16 @@ public:
|
|||||||
//! piCout << v; // {1, 3, 7, 5}
|
//! piCout << v; // {1, 3, 7, 5}
|
||||||
//! \endcode
|
//! \endcode
|
||||||
//! \~\sa \a append(), \a prepend(), \a remove()
|
//! \~\sa \a append(), \a prepend(), \a remove()
|
||||||
inline PIVector<T> & insert(size_t index, const T & e = T()) {
|
inline PIVector<T> & insert(size_t index, const T & e = T(), size_t count = 1) {
|
||||||
alloc(piv_size + 1);
|
alloc(piv_size + count);
|
||||||
if (index < piv_size - 1) {
|
if (index < piv_size - count) {
|
||||||
const size_t os = piv_size - index - 1;
|
const size_t os = piv_size - index - count;
|
||||||
memmove(reinterpret_cast<void *>(piv_data + index + 1), reinterpret_cast<const void *>(piv_data + index), os * sizeof(T));
|
memmove(reinterpret_cast<void *>(piv_data + index + count), reinterpret_cast<const void *>(piv_data + index), os * sizeof(T));
|
||||||
|
}
|
||||||
|
PIINTROSPECTION_CONTAINER_USED(T, count)
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
elementNew(piv_data + index + i, e);
|
||||||
}
|
}
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
|
||||||
elementNew(piv_data + index, e);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1349,8 +1369,8 @@ public:
|
|||||||
alloc(piv_size + v.piv_size);
|
alloc(piv_size + v.piv_size);
|
||||||
if (os > 0) {
|
if (os > 0) {
|
||||||
memmove(reinterpret_cast<void *>(piv_data + index + v.piv_size),
|
memmove(reinterpret_cast<void *>(piv_data + index + v.piv_size),
|
||||||
reinterpret_cast<const void *>(piv_data + index),
|
reinterpret_cast<const void *>(piv_data + index),
|
||||||
os * sizeof(T));
|
os * sizeof(T));
|
||||||
}
|
}
|
||||||
newT(piv_data + index, v.piv_data, v.piv_size);
|
newT(piv_data + index, v.piv_data, v.piv_size);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -1372,8 +1392,8 @@ public:
|
|||||||
alloc(piv_size + init_list.size());
|
alloc(piv_size + init_list.size());
|
||||||
if (os > 0) {
|
if (os > 0) {
|
||||||
memmove(reinterpret_cast<void *>(piv_data + index + init_list.size()),
|
memmove(reinterpret_cast<void *>(piv_data + index + init_list.size()),
|
||||||
reinterpret_cast<const void *>(piv_data + index),
|
reinterpret_cast<const void *>(piv_data + index),
|
||||||
os * sizeof(T));
|
os * sizeof(T));
|
||||||
}
|
}
|
||||||
newT(piv_data + index, init_list.begin(), init_list.size());
|
newT(piv_data + index, init_list.begin(), init_list.size());
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
//! \addtogroup Containers
|
/*! \file pivector2d.h
|
||||||
//! \{
|
* \brief 2D wrapper around PIVector
|
||||||
//! \file pivector2d.h
|
*
|
||||||
//! \brief
|
* This file declares PIVector2D
|
||||||
//! \~english Declares \a PIVector2D
|
*/
|
||||||
//! \~russian Объявление \a PIVector2D
|
|
||||||
//! \~\authors
|
|
||||||
//! \~english
|
|
||||||
//! Andrey Bychkov work.a.b@yandex.ru;
|
|
||||||
//! \~russian
|
|
||||||
//! Андрей Бычков work.a.b@yandex.ru;
|
|
||||||
//! \~\}
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
2D wrapper around PIVector
|
2D wrapper around PIVector
|
||||||
@@ -32,7 +25,6 @@
|
|||||||
#ifndef PIVECTOR2D_H
|
#ifndef PIVECTOR2D_H
|
||||||
#define PIVECTOR2D_H
|
#define PIVECTOR2D_H
|
||||||
|
|
||||||
#include "pipair.h"
|
|
||||||
#include "pivector.h"
|
#include "pivector.h"
|
||||||
|
|
||||||
//! \addtogroup Containers
|
//! \addtogroup Containers
|
||||||
@@ -50,7 +42,7 @@
|
|||||||
//! (use \a resize(), \a addRow(), \a removeRow(), \a removeColumn() instead), but you can modify the values of existing elements.
|
//! (use \a resize(), \a addRow(), \a removeRow(), \a removeColumn() instead), but you can modify the values of existing elements.
|
||||||
//! \~russian
|
//! \~russian
|
||||||
//! Этот класс используется для хранения двумерного массива элементов любого типа в виде единого непрерывного блока памяти (обычного
|
//! Этот класс используется для хранения двумерного массива элементов любого типа в виде единого непрерывного блока памяти (обычного
|
||||||
//! PIVector). Доступ к элементам осуществляется с помощью операторов `[][]`, где первый индекс — это строка, а второй — столбец. Со
|
//! \a PIVector). Доступ к элементам осуществляется с помощью операторов `[][]`, где первый индекс — это строка, а второй — столбец. Со
|
||||||
//! строками можно работать как с объектами \a PIVector, что позволяет изменять отдельные элементы или присваивать целые строки. Нельзя
|
//! строками можно работать как с объектами \a PIVector, что позволяет изменять отдельные элементы или присваивать целые строки. Нельзя
|
||||||
//! напрямую добавлять или удалять элементы, чтобы изменить размеры массива после создания (используйте \a resize(), \a addRow(), \a
|
//! напрямую добавлять или удалять элементы, чтобы изменить размеры массива после создания (используйте \a resize(), \a addRow(), \a
|
||||||
//! removeRow(), \a removeColumn() для этого), но можно изменять значения существующих элементов.
|
//! removeRow(), \a removeColumn() для этого), но можно изменять значения существующих элементов.
|
||||||
@@ -59,21 +51,51 @@
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class PIVector2D {
|
class PIVector2D {
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs an empty 2D array.
|
//! \brief
|
||||||
//! \~russian Создает пустой двумерный массив.
|
//! \~english Index structure for 2D array elements (row, column).
|
||||||
|
//! \~russian Структура индекса для элементов двумерного массива (строка, столбец).
|
||||||
|
struct Index {
|
||||||
|
//! \~english Row index in the 2D array.
|
||||||
|
//! \~russian Индекс строки в двумерном массиве.
|
||||||
|
ssize_t row = -1;
|
||||||
|
//! \~english Column index in the 2D array.
|
||||||
|
//! \~russian Индекс столбца в двумерном массиве.
|
||||||
|
ssize_t col = -1;
|
||||||
|
|
||||||
|
//! \~english Default constructor. Initializes row and col to -1 (invalid index).
|
||||||
|
//! \~russian Конструктор по умолчанию. Инициализирует row и col значениями -1 (некорректный индекс).
|
||||||
|
inline Index() = default;
|
||||||
|
//! \~english Constructs an Index with the given row and column values.
|
||||||
|
//! \~russian Создаёт Index с заданными значениями строки и столбца.
|
||||||
|
inline Index(ssize_t r, ssize_t c): row(r), col(c) {}
|
||||||
|
|
||||||
|
//! \~english Checks if the index is valid (both row and column are non-negative).
|
||||||
|
//! \~russian Проверяет, является ли индекс корректным (строка и столбец неотрицательны).
|
||||||
|
//! \~\sa isNotValid()
|
||||||
|
inline bool isValid() const { return row >= 0 && col >= 0; }
|
||||||
|
|
||||||
|
//! \~english Checks if the index is invalid (either row or column is negative).
|
||||||
|
//! \~russian Проверяет, является ли индекс некорректным (строка или столбец отрицательны).
|
||||||
|
//! \~\sa isValid()
|
||||||
|
inline bool isNotValid() const { return !isValid(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \~english Constructs an empty 2D array. No memory is allocated.
|
||||||
|
//! \~russian Создаёт пустой двумерный массив. Память не выделяется.
|
||||||
|
//! \details
|
||||||
|
//! \~english After this constructor, \a rows() and \a cols() return 0, and \a isEmpty() returns true.
|
||||||
|
//! \~russian После этого конструктора \a rows() и \a cols() возвращают 0, а \a isEmpty() возвращает true.
|
||||||
|
//! \~\sa PIVector::PIVector()
|
||||||
inline PIVector2D() { rows_ = cols_ = 0; }
|
inline PIVector2D() { rows_ = cols_ = 0; }
|
||||||
|
|
||||||
//! \~english Constructs a 2D array with the given dimensions, filled with copies of `f`.
|
//! \~english Constructs a 2D array with the given dimensions, filled with copies of `f`.
|
||||||
//! \~russian Создает двумерный массив заданного размера, заполненный копиями `f`.
|
//! \~russian Создаёт двумерный массив заданного размера, заполненный копиями `f`.
|
||||||
//! \param rows Number of rows.
|
//! \details
|
||||||
//! \param cols Number of columns.
|
//! \~english The underlying storage is a single contiguous block of memory of size `rows * cols`.
|
||||||
//! \param f Value to fill the array with.
|
//! All elements are initialized with the value `f`.
|
||||||
//! \~english \param rows Количество строк.
|
//! \~russian Внутреннее хранилище представляет собой единый непрерывный блок памяти размером `rows * cols`.
|
||||||
//! \~russian \param rows Количество строк.
|
//! Все элементы инициализируются значением `f`.
|
||||||
//! \~english \param cols Количество столбцов.
|
//! \~\sa PIVector::PIVector(size_t, const T&)
|
||||||
//! \~russian \param cols Количество столбцов.
|
|
||||||
//! \~english \param f Значение для заполнения массива.
|
|
||||||
//! \~russian \param f Значение для заполнения массива.
|
|
||||||
inline PIVector2D(size_t rows, size_t cols, const T & f = T()) {
|
inline PIVector2D(size_t rows, size_t cols, const T & f = T()) {
|
||||||
rows_ = rows;
|
rows_ = rows;
|
||||||
cols_ = cols;
|
cols_ = cols;
|
||||||
@@ -81,22 +103,35 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Constructs a 2D array from an existing 1D vector, reshaping it.
|
//! \~english Constructs a 2D array from an existing 1D vector, reshaping it.
|
||||||
//! \~russian Создает двумерный массив из существующего одномерного вектора, изменяя его форму.
|
//! \~russian Создаёт двумерный массив из существующего одномерного вектора, изменяя его форму.
|
||||||
//! \param rows Number of rows.
|
//! \details
|
||||||
//! \param cols Number of columns.
|
//! \~english The constructor copies the data from `v` into the internal flat vector.
|
||||||
//! \param v The source 1D vector. Its size must be at least `rows * cols`.
|
//! If `v` is larger than `rows * cols`, the excess elements are ignored (the vector is truncated).
|
||||||
|
//! If `v` is smaller, other values filled whith default cunstructor T()
|
||||||
|
//! \~russian Конструктор копирует данные из `v` во внутренний плоский вектор.
|
||||||
|
//! Если `v` больше, чем `rows * cols`, лишние элементы игнорируются (вектор обрезается).
|
||||||
|
//! Если `v` меньше, остальные значения будут заполнены из конструктора по умолчанию T()
|
||||||
|
//! \~\sa PIVector::PIVector(const PIVector&), reshape()
|
||||||
inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v): rows_(rows), cols_(cols), mat(v) { mat.resize(rows * cols); }
|
inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v): rows_(rows), cols_(cols), mat(v) { mat.resize(rows * cols); }
|
||||||
|
|
||||||
//! \~english Move constructs a 2D array from an existing 1D vector, reshaping it.
|
//! \~english Move constructs a 2D array from an existing 1D vector, reshaping it.
|
||||||
//! \~russian Конструктор перемещения из существующего одномерного вектора, изменяя его форму.
|
//! \~russian Конструктор перемещения из существующего одномерного вектора, изменяя его форму.
|
||||||
//! \param rows Number of rows.
|
//! \details
|
||||||
//! \param cols Number of columns.
|
//! \~english The data is moved from `v` into the internal flat vector, avoiding a copy.
|
||||||
//! \param v The source 1D vector (rvalue reference). Its size must be at least `rows * cols`.
|
//! After construction, `v` is left in a valid but unspecified state.
|
||||||
|
//! \~russian Данные перемещаются из `v` во внутренний плоский вектор, что позволяет избежать копирования.
|
||||||
|
//! После завершения конструктора `v` остаётся в корректном, но неопределённом состоянии.
|
||||||
|
//! \~\sa PIVector::PIVector(PIVector&&)
|
||||||
inline PIVector2D(size_t rows, size_t cols, PIVector<T> && v): rows_(rows), cols_(cols), mat(std::move(v)) { mat.resize(rows * cols); }
|
inline PIVector2D(size_t rows, size_t cols, PIVector<T> && v): rows_(rows), cols_(cols), mat(std::move(v)) { mat.resize(rows * cols); }
|
||||||
|
|
||||||
//! \~english Constructs a 2D array from a vector of vectors (jagged array). Assumes all inner vectors have the same size.
|
//! \~english Constructs a 2D array from a vector of vectors (jagged array). Assumes all inner vectors have the same size.
|
||||||
//! \~russian Создает двумерный массив из вектора векторов (рваного массива). Предполагается, что все внутренние векторы имеют
|
//! \~russian Создаёт двумерный массив из вектора векторов (рваного массива). Предполагается, что все внутренние векторы имеют
|
||||||
//! одинаковый размер. \param v The source vector of vectors.
|
//! одинаковый размер.
|
||||||
|
//! \details
|
||||||
|
//! \~english If the input is empty, the constructed array is also empty. Otherwise, the number of columns is taken from the size of the
|
||||||
|
//! first inner vector. All inner vectors are concatenated in the internal flat storage.
|
||||||
|
//! \~russian Если входной массив пуст, создаётся пустой двумерный массив. В противном случае количество столбцов берётся из размера
|
||||||
|
//! первого внутреннего вектора. Все внутренние векторы конкатенируются во внутреннем плоском хранилище. \sa PIVector::append()
|
||||||
inline PIVector2D(const PIVector<PIVector<T>> & v) {
|
inline PIVector2D(const PIVector<PIVector<T>> & v) {
|
||||||
rows_ = v.size();
|
rows_ = v.size();
|
||||||
if (rows_) {
|
if (rows_) {
|
||||||
@@ -110,240 +145,97 @@ public:
|
|||||||
if (mat.isEmpty()) rows_ = cols_ = 0;
|
if (mat.isEmpty()) rows_ = cols_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Number of rows.
|
//! \~english Returns the number of rows in the 2D array.
|
||||||
//! \~russian Количество строк.
|
//! \~russian Возвращает количество строк в двумерном массиве.
|
||||||
|
//! \return Number of rows.
|
||||||
|
//! \details
|
||||||
|
//! \~english The result is always non-negative. If the array is empty, returns 0.
|
||||||
|
//! \~russian Результат всегда неотрицательный. Если массив пуст, возвращает 0.
|
||||||
|
//! \~\sa cols(), size(), PIVector::size()
|
||||||
inline size_t rows() const { return rows_; }
|
inline size_t rows() const { return rows_; }
|
||||||
|
|
||||||
//! \~english Number of columns.
|
//! \~english Returns the number of columns in the 2D array.
|
||||||
//! \~russian Количество столбцов.
|
//! \~russian Возвращает количество столбцов в двумерном массиве.
|
||||||
|
//! \return Number of columns.
|
||||||
|
//! \details
|
||||||
|
//! \~english The result is always non-negative. If the array is empty, returns 0.
|
||||||
|
//! \~russian Результат всегда неотрицательный. Если массив пуст, возвращает 0.
|
||||||
|
//! \~\sa rows(), size(), PIVector::size()
|
||||||
inline size_t cols() const { return cols_; }
|
inline size_t cols() const { return cols_; }
|
||||||
|
|
||||||
//! \~english Total number of elements (`rows * cols`).
|
//! \~english Returns the total number of elements (`rows * cols`).
|
||||||
//! \~russian Общее количество элементов (`строки * столбцы`).
|
//! \~russian Возвращает общее количество элементов (`строки * столбцы`).
|
||||||
|
//! \return Total number of elements.
|
||||||
|
//! \details
|
||||||
|
//! \~english This is equivalent to the size of the underlying flat vector.
|
||||||
|
//! \~russian Это эквивалентно размеру внутреннего плоского вектора.
|
||||||
|
//! \~\sa rows(), cols(), PIVector::size()
|
||||||
inline size_t size() const { return mat.size(); }
|
inline size_t size() const { return mat.size(); }
|
||||||
|
|
||||||
//! \~english Total number of elements as signed value.
|
//! \~english Returns the total number of elements as a signed value.
|
||||||
//! \~russian Общее количество элементов в виде знакового числа.
|
//! \~russian Возвращает общее количество элементов в виде знакового числа.
|
||||||
|
//! \return Signed size.
|
||||||
|
//! \~\sa size(), PIVector::size_s()
|
||||||
inline ssize_t size_s() const { return mat.size_s(); }
|
inline ssize_t size_s() const { return mat.size_s(); }
|
||||||
|
|
||||||
//! \~english Total number of elements.
|
//! \~english Returns the total number of elements (same as \a size()).
|
||||||
//! \~russian Общее количество элементов.
|
//! \~russian Возвращает общее количество элементов (то же, что и \a size()).
|
||||||
|
//! \return Total number of elements.
|
||||||
|
//! \~\sa size(), PIVector::length()
|
||||||
inline size_t length() const { return mat.length(); }
|
inline size_t length() const { return mat.length(); }
|
||||||
|
|
||||||
//! \~english Number of elements that the underlying container has currently allocated space for.
|
//! \~english Returns the number of elements that the underlying container has currently allocated space for.
|
||||||
//! \~russian Количество элементов, для которого сейчас выделена память во внутреннем контейнере.
|
//! \~russian Возвращает количество элементов, для которого сейчас выделена память во внутреннем контейнере.
|
||||||
|
//! \return Capacity of the flat vector.
|
||||||
|
//! \details
|
||||||
|
//! \~english This value may be larger than \a size(). It indicates how many elements can be added before a reallocation is needed.
|
||||||
|
//! \~russian Это значение может быть больше, чем \a size(). Оно показывает, сколько элементов можно добавить до того, как потребуется
|
||||||
|
//! перераспределение памяти. \sa reserve(), PIVector::capacity()
|
||||||
inline size_t capacity() const { return mat.capacity(); }
|
inline size_t capacity() const { return mat.capacity(); }
|
||||||
|
|
||||||
//! \~english Checks if the array has no elements.
|
//! \~english Checks if the array has no elements.
|
||||||
//! \~russian Проверяет, пуст ли массив.
|
//! \~russian Проверяет, пуст ли массив.
|
||||||
|
//! \return \c true if the array is empty, \c false otherwise.
|
||||||
|
//! \details
|
||||||
|
//! \~english An empty array has both rows and columns equal to 0.
|
||||||
|
//! \~russian Пустой массив имеет и строки, и столбцы равные 0.
|
||||||
|
//! \~\sa isNotEmpty(), PIVector::isEmpty()
|
||||||
inline bool isEmpty() const { return mat.isEmpty(); }
|
inline bool isEmpty() const { return mat.isEmpty(); }
|
||||||
|
|
||||||
//! \~english Checks if the array has elements.
|
//! \~english Checks if the array has at least one element.
|
||||||
//! \~russian Проверяет, не пуст ли массив.
|
//! \~russian Проверяет, не пуст ли массив.
|
||||||
|
//! \return \c true if the array is not empty, \c false otherwise.
|
||||||
|
//! \~\sa isEmpty(), PIVector::isNotEmpty()
|
||||||
inline bool isNotEmpty() const { return mat.isNotEmpty(); }
|
inline bool isNotEmpty() const { return mat.isNotEmpty(); }
|
||||||
|
|
||||||
|
class RowConst;
|
||||||
|
class ColConst;
|
||||||
|
class Row;
|
||||||
|
class Col;
|
||||||
|
|
||||||
//! \class Row
|
|
||||||
//! \brief
|
|
||||||
//! \~english Proxy class representing a single row in a \a PIVector2D for modification.
|
|
||||||
//! \~russian Прокси-класс, представляющий одну строку в \a PIVector2D для модификации.
|
|
||||||
class Row {
|
|
||||||
friend class PIVector2D<T>;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline Row(PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
|
||||||
st_ = p->cols_ * row;
|
|
||||||
sz_ = p->cols_;
|
|
||||||
}
|
|
||||||
PIVector<T> * p_;
|
|
||||||
size_t st_, sz_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
//! \~english Size of the row (number of columns).
|
|
||||||
//! \~russian Размер строки (количество столбцов).
|
|
||||||
inline size_t size() const { return sz_; }
|
|
||||||
|
|
||||||
//! \~english Accesses the element at the given column index within the row.
|
|
||||||
//! \~russian Доступ к элементу по заданному индексу столбца в строке.
|
|
||||||
inline T & operator[](size_t index) { return (*p_)[st_ + index]; }
|
|
||||||
|
|
||||||
//! \~english Const access to the element at the given column index within the row.
|
|
||||||
//! \~russian Константный доступ к элементу по заданному индексу столбца в строке.
|
|
||||||
inline const T & operator[](size_t index) const { return (*p_)[st_ + index]; }
|
|
||||||
|
|
||||||
//! \~english Returns a pointer to the row data starting at an optional offset.
|
|
||||||
//! \~russian Возвращает указатель на данные строки, начиная с опционального смещения.
|
|
||||||
inline T * data(size_t index = 0) { return p_->data(st_ + index); }
|
|
||||||
|
|
||||||
//! \~english Returns a const pointer to the row data starting at an optional offset.
|
|
||||||
//! \~russian Возвращает константный указатель на данные строки, начиная с опционального смещения.
|
|
||||||
inline const T * data(size_t index = 0) const { return p_->data(st_ + index); }
|
|
||||||
|
|
||||||
//! \~english Assigns the contents of another Row to this row.
|
|
||||||
//! \~russian Присваивает этой строке содержимое другой строки.
|
|
||||||
inline Row & operator=(const Row & other) {
|
|
||||||
if (p_ == other.p_ && st_ == other.st_) return *this;
|
|
||||||
const size_t sz = piMin<size_t>(sz_, other.sz_);
|
|
||||||
p_->_copyRaw(p_->data(st_), other.data(), sz);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Assigns the contents of a \a PIVector to this row.
|
|
||||||
//! \~russian Присваивает этой строке содержимое \a PIVector.
|
|
||||||
inline Row & operator=(const PIVector<T> & other) {
|
|
||||||
const size_t sz = piMin<size_t>(sz_, other.size());
|
|
||||||
p_->_copyRaw(p_->data(st_), other.data(), sz);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Converts the row to a \a PIVector.
|
|
||||||
//! \~russian Преобразует строку в \a PIVector.
|
|
||||||
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
|
|
||||||
|
|
||||||
// --- Поиск в строке ---
|
|
||||||
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
|
|
||||||
if (start < 0) start = 0;
|
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
|
||||||
if ((*p_)[st_ + i] == e) return (ssize_t)i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
|
||||||
if ((*p_)[st_ + i] == e) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
|
||||||
if (start < 0) start = 0;
|
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
|
||||||
if (test((*p_)[st_ + i])) return (ssize_t)i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
|
||||||
if (test((*p_)[st_ + i])) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! \class Col
|
|
||||||
//! \brief
|
|
||||||
//! \~english Proxy class representing a single column in a \a PIVector2D for modification.
|
|
||||||
//! \~russian Прокси-класс, представляющий один столбец в \a PIVector2D для модификации.
|
|
||||||
class Col {
|
|
||||||
friend class PIVector2D<T>;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline Col(PIVector2D<T> * p, size_t col): p_(&(p->mat)) {
|
|
||||||
step_ = p->cols_;
|
|
||||||
col_ = col;
|
|
||||||
sz_ = p->rows_;
|
|
||||||
}
|
|
||||||
PIVector<T> * p_;
|
|
||||||
size_t step_, col_, sz_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
//! \~english Size of the column (number of rows).
|
|
||||||
//! \~russian Размер столбца (количество строк).
|
|
||||||
inline size_t size() const { return sz_; }
|
|
||||||
|
|
||||||
//! \~english Accesses the element at the given row index within the column.
|
|
||||||
//! \~russian Доступ к элементу по заданному индексу строки в столбце.
|
|
||||||
inline T & operator[](size_t index) { return (*p_)[index * step_ + col_]; }
|
|
||||||
|
|
||||||
//! \~english Const access to the element at the given row index within the column.
|
|
||||||
//! \~russian Константный доступ к элементу по заданному индексу строки в столбце.
|
|
||||||
inline const T & operator[](size_t index) const { return (*p_)[index * step_ + col_]; }
|
|
||||||
|
|
||||||
//! \~english Returns a pointer to the column data starting at an optional row offset.
|
|
||||||
//! \~russian Возвращает указатель на данные столбца, начиная с опционального смещения по строкам.
|
|
||||||
inline T * data(size_t index = 0) { return p_->data(index * step_ + col_); }
|
|
||||||
|
|
||||||
//! \~english Returns a const pointer to the column data starting at an optional row offset.
|
|
||||||
//! \~russian Возвращает константный указатель на данные столбца, начиная с опционального смещения по строкам.
|
|
||||||
inline const T * data(size_t index = 0) const { return p_->data(index * step_ + col_); }
|
|
||||||
|
|
||||||
//! \~english Assigns the contents of another Col to this column.
|
|
||||||
//! \~russian Присваивает этому столбцу содержимое другого столбца.
|
|
||||||
inline Col & operator=(const Col & other) {
|
|
||||||
if (p_ == other.p_ && col_ == other.col_) return *this;
|
|
||||||
const size_t sz = piMin<size_t>(sz_, other.sz_);
|
|
||||||
for (size_t i = 0; i < sz; ++i)
|
|
||||||
(*p_)[i * step_ + col_] = other[i];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Assigns the contents of a \a PIVector to this column.
|
|
||||||
//! \~russian Присваивает этому столбцу содержимое \a PIVector.
|
|
||||||
inline Col & operator=(const PIVector<T> & other) {
|
|
||||||
const size_t sz = piMin<size_t>(sz_, other.size());
|
|
||||||
for (size_t i = 0; i < sz; ++i)
|
|
||||||
(*p_)[i * step_ + col_] = other[i];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Converts the column to a \a PIVector.
|
|
||||||
//! \~russian Преобразует столбец в \a PIVector.
|
|
||||||
inline PIVector<T> toVector() const {
|
|
||||||
PIVector<T> ret;
|
|
||||||
ret.reserve(sz_);
|
|
||||||
for (size_t i = 0; i < sz_; i++)
|
|
||||||
ret << (*p_)[i * step_ + col_];
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Поиск в столбце ---
|
|
||||||
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
|
|
||||||
if (start < 0) start = 0;
|
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
|
||||||
if ((*p_)[i * step_ + col_] == e) return (ssize_t)i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
|
||||||
if ((*p_)[i * step_ + col_] == e) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
|
||||||
if (start < 0) start = 0;
|
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
|
||||||
if (test((*p_)[i * step_ + col_])) return (ssize_t)i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
|
||||||
if (test((*p_)[i * step_ + col_])) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! \class RowConst
|
//! \class RowConst
|
||||||
//! \brief
|
//! \brief
|
||||||
//! \~english Proxy class representing a single read-only row in a \a PIVector2D.
|
//! \~english Proxy class representing a single read-only row in a \a PIVector2D.
|
||||||
//! \~russian Прокси-класс, представляющий одну строку в \a PIVector2D только для чтения.
|
//! \~russian Прокси-класс, представляющий одну строку в \a PIVector2D только для чтения.
|
||||||
|
//! \details
|
||||||
|
//! \~english Returned by const \a operator[] or \a row(). Provides const access to row elements.
|
||||||
|
//! \~russian Возвращается константными версиями \a operator[] или \a row(). Предоставляет константный доступ к элементам строки.
|
||||||
|
//! \~\sa Row, ColConst
|
||||||
class RowConst {
|
class RowConst {
|
||||||
friend class PIVector2D<T>;
|
friend class PIVector2D<T>;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
inline RowConst(const PIVector2D<T> * p, size_t row): p_(&(p->mat)) {
|
inline RowConst(const PIVector2D<T> * p, size_t row): p_(&(p->mat)), st_(p->cols_ * row), sz_(p->cols_) {}
|
||||||
st_ = p->cols_ * row;
|
|
||||||
sz_ = p->cols_;
|
|
||||||
}
|
|
||||||
const PIVector<T> * p_;
|
const PIVector<T> * p_;
|
||||||
size_t st_, sz_;
|
const size_t st_, sz_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
//! \~english Copy constructor from modifiable Row to read-only RowConst.
|
||||||
|
//! \~russian Конструктор копирования из модифицируемого класса Row в константный RowConst.
|
||||||
|
//! \~\sa Row
|
||||||
|
inline RowConst(const PIVector2D<T>::Row & r): p_(r.p_), st_(r.st_), sz_(r.sz_) {}
|
||||||
|
|
||||||
//! \~english Size of the row (number of columns).
|
//! \~english Size of the row (number of columns).
|
||||||
//! \~russian Размер строки (количество столбцов).
|
//! \~russian Размер строки (количество столбцов).
|
||||||
inline size_t size() const { return sz_; }
|
inline size_t size() const { return sz_; }
|
||||||
@@ -360,7 +252,12 @@ public:
|
|||||||
//! \~russian Преобразует строку в \a PIVector.
|
//! \~russian Преобразует строку в \a PIVector.
|
||||||
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
|
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
|
||||||
|
|
||||||
// --- Поиск в строке (только чтение) ---
|
//! \~english Returns the first index of element `e` in the row, starting from `start`.
|
||||||
|
//! \~russian Возвращает первый индекс элемента `e` в строке, начиная с позиции `start`.
|
||||||
|
//! \details
|
||||||
|
//! \~english See \a PIVector::indexOf() for details on negative start handling.
|
||||||
|
//! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf().
|
||||||
|
//! \~\sa PIVector::indexOf()
|
||||||
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
|
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
@@ -368,6 +265,11 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Returns the last index of element `e` in the row, searching backwards from `start`.
|
||||||
|
//! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`.
|
||||||
|
//! \return Index if found, -1 otherwise.
|
||||||
|
//! \~\sa PIVector::lastIndexOf()
|
||||||
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
for (ssize_t i = from; i >= 0; --i) {
|
||||||
@@ -375,6 +277,10 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Returns the first index where the predicate `test` returns true, starting from `start`.
|
||||||
|
//! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`.
|
||||||
|
//! \~\sa PIVector::indexWhere()
|
||||||
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
@@ -382,6 +288,11 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`.
|
||||||
|
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true,
|
||||||
|
//! выполняя поиск в обратном направлении от `start`.
|
||||||
|
//! \~\sa PIVector::lastIndexWhere()
|
||||||
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
for (ssize_t i = from; i >= 0; --i) {
|
||||||
@@ -389,25 +300,92 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Applies a function to each element of the row (read-only).
|
||||||
|
//! \~russian Применяет функцию к каждому элементу строки (только чтение).
|
||||||
|
//! \details
|
||||||
|
//! \~english The function can't modify the elements.
|
||||||
|
//! \~russian Функция не может изменять элементы.
|
||||||
|
//! \~\sa forEach (modifiable)
|
||||||
|
inline void forEach(std::function<void(const T &)> func) const {
|
||||||
|
for (size_t i = 0; i < sz_; ++i) {
|
||||||
|
func((*p_)[st_ + i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Checks if the row contains the element `e`.
|
||||||
|
//! \~russian Проверяет, содержит ли строка элемент `e`.
|
||||||
|
//! \~\sa PIVector::contains()
|
||||||
|
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
|
||||||
|
|
||||||
|
//! \~english Counts occurrences of `e` in the row.
|
||||||
|
//! \~russian Подсчитывает количество вхождений `e` в строке.
|
||||||
|
//! \~\sa PIVector::entries()
|
||||||
|
inline int entries(const T & e, ssize_t start = 0) const {
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
|
if ((*p_)[st_ + i] == e) ++count;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Counts elements in the row that pass the `test`.
|
||||||
|
//! \~russian Подсчитывает элементы в строке, проходящие `test`.
|
||||||
|
//! \~\sa PIVector::entries(std::function)
|
||||||
|
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
|
if (test((*p_)[st_ + i])) ++count;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Tests if any element in the row passes the `test`.
|
||||||
|
//! \~russian Проверяет, проходит ли какой-либо элемент в строке `test`.
|
||||||
|
//! \~\sa PIVector::any()
|
||||||
|
inline bool any(std::function<bool(const T & e)> test) const {
|
||||||
|
for (size_t i = 0; i < sz_; ++i) {
|
||||||
|
if (test((*p_)[st_ + i])) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Tests if all elements in the row pass the `test`.
|
||||||
|
//! \~russian Проверяет, проходят ли все элементы в строке `test`.
|
||||||
|
//! \~\sa PIVector::every()
|
||||||
|
inline bool every(std::function<bool(const T & e)> test) const {
|
||||||
|
for (size_t i = 0; i < sz_; ++i) {
|
||||||
|
if (!test((*p_)[st_ + i])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \class ColConst
|
//! \class ColConst
|
||||||
//! \brief
|
//! \brief
|
||||||
//! \~english Proxy class representing a single read-only column in a \a PIVector2D.
|
//! \~english Proxy class representing a single read-only column in a \a PIVector2D.
|
||||||
//! \~russian Прокси-класс, представляющий один столбец в \a PIVector2D только для чтения.
|
//! \~russian Прокси-класс, представляющий один столбец в \a PIVector2D только для чтения.
|
||||||
|
//! \details
|
||||||
|
//! \~english Returned by const \a col(). Provides const access to column elements.
|
||||||
|
//! \~russian Возвращается константной версией \a col(). Предоставляет константный доступ к элементам столбца.
|
||||||
|
//! \~\sa Col, RowConst
|
||||||
class ColConst {
|
class ColConst {
|
||||||
friend class PIVector2D<T>;
|
friend class PIVector2D<T>;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
inline ColConst(const PIVector2D<T> * p, size_t col): p_(&(p->mat)) {
|
inline ColConst(const PIVector2D<T> * p, size_t col): p_(&(p->mat)), step_(p->cols_), col_(col), sz_(p->rows_) {}
|
||||||
step_ = p->cols_;
|
|
||||||
col_ = col;
|
|
||||||
sz_ = p->rows_;
|
|
||||||
}
|
|
||||||
const PIVector<T> * p_;
|
const PIVector<T> * p_;
|
||||||
size_t step_, col_, sz_;
|
const size_t step_, col_, sz_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
//! \~english Copy constructor from modifiable Col to read-only ColConst.
|
||||||
|
//! \~russian Конструктор копирования из модифицируемого класса Col в константный ColConst.
|
||||||
|
//! \~\sa Col
|
||||||
|
inline ColConst(const PIVector2D<T>::Col & c): p_(c.p_), step_(c.step_), col_(c.col_), sz_(c.sz_) {}
|
||||||
|
|
||||||
//! \~english Size of the column (number of rows).
|
//! \~english Size of the column (number of rows).
|
||||||
//! \~russian Размер столбца (количество строк).
|
//! \~russian Размер столбца (количество строк).
|
||||||
inline size_t size() const { return sz_; }
|
inline size_t size() const { return sz_; }
|
||||||
@@ -430,7 +408,12 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Поиск в столбце (только чтение) ---
|
//! \~english Returns the first index of element `e` in the row, starting from `start`.
|
||||||
|
//! \~russian Возвращает первый индекс элемента `e` в строке, начиная с позиции `start`.
|
||||||
|
//! \details
|
||||||
|
//! \~english See \a PIVector::indexOf() for details on negative start handling.
|
||||||
|
//! \~russian Подробнее об обработке отрицательного `start` см. \a PIVector::indexOf().
|
||||||
|
//! \~\sa PIVector::indexOf()
|
||||||
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
|
inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
@@ -438,6 +421,10 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Returns the last index of element `e` in the row, searching backwards from `start`.
|
||||||
|
//! \~russian Возвращает последний индекс элемента `e` в строке, выполняя поиск в обратном направлении от `start`.
|
||||||
|
//! \~\sa PIVector::lastIndexOf()
|
||||||
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
for (ssize_t i = from; i >= 0; --i) {
|
||||||
@@ -445,6 +432,10 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Returns the first index where the predicate `test` returns true, starting from `start`.
|
||||||
|
//! \~russian Возвращает первый индекс, для которого предикат `test` возвращает true, начиная с `start`.
|
||||||
|
//! \~\sa PIVector::indexWhere()
|
||||||
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
for (size_t i = (size_t)start; i < sz_; ++i) {
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
@@ -452,6 +443,11 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Returns the last index where the predicate `test` returns true, searching backwards from `start`.
|
||||||
|
//! \~russian Возвращает последний индекс, для которого предикат `test` возвращает true,
|
||||||
|
//! выполняя поиск в обратном направлении от `start`.
|
||||||
|
//! \~\sa PIVector::lastIndexWhere()
|
||||||
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
||||||
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
|
||||||
for (ssize_t i = from; i >= 0; --i) {
|
for (ssize_t i = from; i >= 0; --i) {
|
||||||
@@ -459,22 +455,277 @@ public:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Applies a function to each element of the column (read-only).
|
||||||
|
//! \~russian Применяет функцию к каждому элементу столбца (только чтение).
|
||||||
|
//! \details
|
||||||
|
//! \~english The function can't modify the elements.
|
||||||
|
//! \~russian Функция не может изменять элементы.
|
||||||
|
//! \~\sa forEach (modifiable)
|
||||||
|
inline void forEach(std::function<void(const T &)> func) const {
|
||||||
|
for (size_t i = 0; i < sz_; ++i) {
|
||||||
|
func((*p_)[i * step_ + col_]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Checks if the column contains the element `e`.
|
||||||
|
//! \~russian Проверяет, содержит ли столбец элемент `e`.
|
||||||
|
//! \~\sa PIVector::contains()
|
||||||
|
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
|
||||||
|
|
||||||
|
//! \~english Counts occurrences of `e` in the column.
|
||||||
|
//! \~russian Подсчитывает количество вхождений `e` в столбце.
|
||||||
|
//! \~\sa PIVector::entries()
|
||||||
|
inline int entries(const T & e, ssize_t start = 0) const {
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
|
if ((*p_)[i * step_ + col_] == e) ++count;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Counts elements in the column that pass the `test`.
|
||||||
|
//! \~russian Подсчитывает элементы в столбце, проходящие `test`.
|
||||||
|
//! \~\sa PIVector::entries(std::function)
|
||||||
|
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (size_t i = (size_t)start; i < sz_; ++i) {
|
||||||
|
if (test((*p_)[i * step_ + col_])) ++count;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Tests if any element in the column passes the `test`.
|
||||||
|
//! \~russian Проверяет, проходит ли какой-либо элемент в столбце `test`.
|
||||||
|
//! \~\sa PIVector::any()
|
||||||
|
inline bool any(std::function<bool(const T & e)> test) const {
|
||||||
|
for (size_t i = 0; i < sz_; ++i) {
|
||||||
|
if (test((*p_)[i * step_ + col_])) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Tests if all elements in the column pass the `test`.
|
||||||
|
//! \~russian Проверяет, проходят ли все элементы в столбце `test`.
|
||||||
|
//! \~\sa PIVector::every()
|
||||||
|
inline bool every(std::function<bool(const T & e)> test) const {
|
||||||
|
for (size_t i = 0; i < sz_; ++i) {
|
||||||
|
if (!test((*p_)[i * step_ + col_])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! \class Row
|
||||||
|
//! \brief
|
||||||
|
//! \~english Proxy class representing a single row in a \a PIVector2D for modification.
|
||||||
|
//! \~russian Прокси-класс, представляющий одну строку в \a PIVector2D для модификации.
|
||||||
|
//! \details
|
||||||
|
//! \~english Objects of this class are returned by non-const \a operator[] or \a row().
|
||||||
|
//! They provide array-like access to the elements of a specific row and allow operations such as assignment from another row or a \a
|
||||||
|
//! PIVector, searching, filling, and iteration.
|
||||||
|
//! \~russian Объекты этого класса возвращаются неконстантными операторами \a operator[] или методом \a row().
|
||||||
|
//! Они предоставляют доступ к элементам конкретной строки, подобный массиву, и позволяют выполнять такие операции, как присваивание из
|
||||||
|
//! другой строки или \a PIVector, поиск, заполнение и итерацию. \sa Col, RowConst
|
||||||
|
class Row: public RowConst {
|
||||||
|
friend class PIVector2D<T>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline Row(PIVector2D<T> * p, size_t row): RowConst(p, row), p_(&(p->mat)) {}
|
||||||
|
PIVector<T> * p_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using RowConst::operator[];
|
||||||
|
using RowConst::data;
|
||||||
|
using RowConst::size;
|
||||||
|
|
||||||
|
//! \~english Accesses the element at the given column index within the row.
|
||||||
|
//! \~russian Доступ к элементу по заданному индексу столбца в строке.
|
||||||
|
//! \details
|
||||||
|
//! \~english No bounds checking is performed; use with caution.
|
||||||
|
//! \~russian Проверка границ не выполняется; используйте с осторожностью.
|
||||||
|
//! \~\sa PIVector::operator[]
|
||||||
|
inline T & operator[](size_t index) { return (*p_)[this->st_ + index]; }
|
||||||
|
|
||||||
|
//! \~english Returns a pointer to the row data starting at an optional offset.
|
||||||
|
//! \~russian Возвращает указатель на данные строки, начиная с опционального смещения.
|
||||||
|
//! \details
|
||||||
|
//! \~english The pointer can be used for direct memory operations. It remains valid as long as the underlying 2D array is not
|
||||||
|
//! reallocated.
|
||||||
|
//! \~russian Указатель можно использовать для прямых операций с памятью. Он остаётся действительным, пока не произойдёт
|
||||||
|
//! перераспределение памяти внутреннего двумерного массива. \sa PIVector::data()
|
||||||
|
inline T * data(size_t index = 0) { return p_->data(this->st_ + index); }
|
||||||
|
|
||||||
|
//! \~english Assigns the contents of another Row to this row.
|
||||||
|
//! \~russian Присваивает этой строке содержимое другой строки.
|
||||||
|
//! \details
|
||||||
|
//! \~english Only the minimum of the two row sizes is copied; if this row is shorter, excess elements in `other` are ignored.
|
||||||
|
//! \~russian Копируется только минимум из размеров двух строк; если эта строка короче, лишние элементы из `other` игнорируются.
|
||||||
|
//! \~\sa PIVector::operator=
|
||||||
|
inline Row & operator=(const Row & other) {
|
||||||
|
if (p_ == other.p_ && this->st_ == other.st_) return *this;
|
||||||
|
const size_t sz = piMin<size_t>(this->sz_, other.sz_);
|
||||||
|
p_->_copyRaw(p_->data(this->st_), other.data(), sz);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Assigns the contents of a \a PIVector to this row.
|
||||||
|
//! \~russian Присваивает этой строке содержимое \a PIVector.
|
||||||
|
//! \details
|
||||||
|
//! \~english Only the minimum of the row size and vector size is copied.
|
||||||
|
//! \~russian Копируется только минимум из размера строки и размера вектора.
|
||||||
|
//! \~\sa PIVector::operator=
|
||||||
|
inline Row & operator=(const PIVector<T> & other) {
|
||||||
|
const size_t sz = piMin<size_t>(this->sz_, other.size());
|
||||||
|
p_->_copyRaw(p_->data(this->st_), other.data(), sz);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Applies a function to each element of the row (modifiable).
|
||||||
|
//! \~russian Применяет функцию к каждому элементу строки (с возможностью изменения).
|
||||||
|
//! \param func Function that takes a reference to T.
|
||||||
|
//! \details
|
||||||
|
//! \~english The function can modify the elements.
|
||||||
|
//! \~russian Функция может изменять элементы.
|
||||||
|
//! \~\sa PIVector::forEach()
|
||||||
|
inline void forEach(std::function<void(T &)> func) {
|
||||||
|
for (size_t i = 0; i < this->sz_; ++i) {
|
||||||
|
func((*p_)[this->st_ + i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Fills the row with copies of `value`.
|
||||||
|
//! \~russian Заполняет строку копиями `value`.
|
||||||
|
//! \~\sa PIVector::fill()
|
||||||
|
inline void fill(const T & value) {
|
||||||
|
for (size_t i = 0; i < this->sz_; ++i) {
|
||||||
|
(*p_)[this->st_ + i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! \class Col
|
||||||
|
//! \brief
|
||||||
|
//! \~english Proxy class representing a single column in a \a PIVector2D for modification.
|
||||||
|
//! \~russian Прокси-класс, представляющий один столбец в \a PIVector2D для модификации.
|
||||||
|
//! \details
|
||||||
|
//! \~english Objects of this class are returned by non-const \a col(). They provide column-wise access and operations similar to \a
|
||||||
|
//! Row.
|
||||||
|
//! \~russian Объекты этого класса возвращаются неконстантным методом \a col(). Они предоставляют доступ к столбцам и операции,
|
||||||
|
//! аналогичные \a Row. \sa Row, ColConst
|
||||||
|
class Col: public ColConst {
|
||||||
|
friend class PIVector2D<T>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline Col(PIVector2D<T> * p, size_t col): ColConst(p, col), p_(&(p->mat)) {}
|
||||||
|
PIVector<T> * p_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using ColConst::operator[];
|
||||||
|
using ColConst::data;
|
||||||
|
using ColConst::size;
|
||||||
|
|
||||||
|
//! \~english Accesses the element at the given row index within the column.
|
||||||
|
//! \~russian Доступ к элементу по заданному индексу строки в столбце.
|
||||||
|
//! \return Reference to the element.
|
||||||
|
inline T & operator[](size_t index) { return (*p_)[index * this->step_ + this->col_]; }
|
||||||
|
|
||||||
|
//! \~english Returns a pointer to the column data starting at an optional row offset.
|
||||||
|
//! \~russian Возвращает указатель на данные столбца, начиная с опционального смещения по строкам.
|
||||||
|
//! \details
|
||||||
|
//! \~english Note that column elements are not stored contiguously in memory, so this pointer cannot be used to iterate over the
|
||||||
|
//! whole column.
|
||||||
|
//! \~russian Обратите внимание, что элементы столбца не хранятся в памяти непрерывно, поэтому этот указатель нельзя использовать
|
||||||
|
//! для итерации по всему столбцу.
|
||||||
|
inline T * data(size_t index = 0) { return p_->data(index * this->step_ + this->col_); }
|
||||||
|
|
||||||
|
//! \~english Assigns the contents of another Col to this column.
|
||||||
|
//! \~russian Присваивает этому столбцу содержимое другого столбца.
|
||||||
|
inline Col & operator=(const Col & other) {
|
||||||
|
if (p_ == other.p_ && this->col_ == other.col_) return *this;
|
||||||
|
const size_t sz = piMin<size_t>(this->sz_, other.sz_);
|
||||||
|
for (size_t i = 0; i < sz; ++i)
|
||||||
|
(*p_)[i * this->step_ + this->col_] = other[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Assigns the contents of a \a PIVector to this column.
|
||||||
|
//! \~russian Присваивает этому столбцу содержимое \a PIVector.
|
||||||
|
inline Col & operator=(const PIVector<T> & other) {
|
||||||
|
const size_t sz = piMin<size_t>(this->sz_, other.size());
|
||||||
|
for (size_t i = 0; i < sz; ++i)
|
||||||
|
(*p_)[i * this->step_ + this->col_] = other[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Applies a function to each element of the column (modifiable).
|
||||||
|
//! \~russian Применяет функцию к каждому элементу столбца (с возможностью изменения).
|
||||||
|
//! \details
|
||||||
|
//! \~english The function can modify the elements.
|
||||||
|
//! \~russian Функция может изменять элементы.
|
||||||
|
//! \~\sa PIVector::forEach()
|
||||||
|
inline void forEach(std::function<void(T &)> func) {
|
||||||
|
for (size_t i = 0; i < this->sz_; ++i) {
|
||||||
|
func((*p_)[i * this->step_ + this->col_]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Fills the column with copies of `value`.
|
||||||
|
//! \~russian Заполняет столбец копиями `value`.
|
||||||
|
//! \~\sa PIVector::fill()
|
||||||
|
inline void fill(const T & value) {
|
||||||
|
for (size_t i = 0; i < this->sz_; ++i) {
|
||||||
|
(*p_)[i * this->step_ + this->col_] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Returns a reference to the element at the given row and column.
|
//! \~english Returns a reference to the element at the given row and column.
|
||||||
//! \~russian Возвращает ссылку на элемент по заданной строке и столбцу.
|
//! \~russian Возвращает ссылку на элемент по заданной строке и столбцу.
|
||||||
|
//! \details
|
||||||
|
//! \~english No bounds checking is performed.
|
||||||
|
//! \~russian Проверка границ не выполняется.
|
||||||
|
//! \~\sa at() (const version), PIVector::operator[]
|
||||||
inline T & element(size_t row, size_t col) { return mat[row * cols_ + col]; }
|
inline T & element(size_t row, size_t col) { return mat[row * cols_ + col]; }
|
||||||
|
|
||||||
//! \~english Returns a const reference to the element at the given row and column.
|
//! \~english Returns a const reference to the element at the given row and column.
|
||||||
//! \~russian Возвращает константную ссылку на элемент по заданной строке и столбцу.
|
//! \~russian Возвращает константную ссылку на элемент по заданной строке и столбцу.
|
||||||
inline const T & element(size_t row, size_t col) const { return mat[row * cols_ + col]; }
|
inline const T & element(size_t row, size_t col) const { return mat[row * cols_ + col]; }
|
||||||
|
|
||||||
//! \~english Returns a const reference to the element at the given row and column (bounds-checked only in debug).
|
//! \~english Returns a const reference to the element at the given row and column
|
||||||
//! \~russian Возвращает константную ссылку на элемент по заданной строке и столбцу (проверка границ только в отладочном режиме).
|
//! \~russian Возвращает константную ссылку на элемент по заданной строке и столбцу
|
||||||
|
//! \details
|
||||||
|
//! \~english No bounds checking is performed.
|
||||||
|
//! \~russian Проверка границ не выполняется.
|
||||||
inline const T & at(size_t row, size_t col) const { return mat[row * cols_ + col]; }
|
inline const T & at(size_t row, size_t col) const { return mat[row * cols_ + col]; }
|
||||||
|
|
||||||
|
//! \~english Returns a reference to the element at the given Index.
|
||||||
|
//! \~russian Возвращает ссылку на элемент по заданному Index.
|
||||||
|
inline T & operator[](const Index & idx) { return element(idx.row, idx.col); }
|
||||||
|
|
||||||
|
//! \~english Returns a const reference to the element at the given Index.
|
||||||
|
//! \~russian Возвращает константную ссылку на элемент по заданному Index.
|
||||||
|
inline const T & operator[](const Index & idx) const { return element(idx.row, idx.col); }
|
||||||
|
|
||||||
|
//! \~english Returns a reference to the element at the given Index.
|
||||||
|
//! \~russian Возвращает ссылку на элемент по заданному Index.
|
||||||
|
inline T & element(const Index & idx) { return element(idx.row, idx.col); }
|
||||||
|
|
||||||
|
//! \~english Returns a const reference to the element at the given Index.
|
||||||
|
//! \~russian Возвращает константную ссылку на элемент по заданному Index.
|
||||||
|
inline const T & element(const Index & idx) const { return element(idx.row, idx.col); }
|
||||||
|
|
||||||
|
//! \~english Returns a const reference to the element at the given Index (bounds-checked only in debug).
|
||||||
|
//! \~russian Возвращает константную ссылку на элемент по заданному Index (проверка границ только в отладочном режиме).
|
||||||
|
inline const T & at(const Index & idx) const { return at(idx.row, idx.col); }
|
||||||
|
|
||||||
//! \~english Returns a proxy object for the row at the given index for modification.
|
//! \~english Returns a proxy object for the row at the given index for modification.
|
||||||
//! \~russian Возвращает прокси-объект для строки по заданному индексу для модификации.
|
//! \~russian Возвращает прокси-объект для строки по заданному индексу для модификации.
|
||||||
|
//! \~\sa row(), Col
|
||||||
inline Row operator[](size_t index) { return Row(this, index); }
|
inline Row operator[](size_t index) { return Row(this, index); }
|
||||||
|
|
||||||
//! \~english Returns a proxy object for the row at the given index for read-only access.
|
//! \~english Returns a proxy object for the row at the given index for read-only access.
|
||||||
@@ -483,6 +734,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Returns a pointer to the underlying flat data starting at an optional offset.
|
//! \~english Returns a pointer to the underlying flat data starting at an optional offset.
|
||||||
//! \~russian Возвращает указатель на внутренние плоские данные, начиная с опционального смещения.
|
//! \~russian Возвращает указатель на внутренние плоские данные, начиная с опционального смещения.
|
||||||
|
//! \~\sa PIVector::data()
|
||||||
inline T * data(size_t index = 0) { return mat.data(index); }
|
inline T * data(size_t index = 0) { return mat.data(index); }
|
||||||
|
|
||||||
//! \~english Returns a const pointer to the underlying flat data starting at an optional offset.
|
//! \~english Returns a const pointer to the underlying flat data starting at an optional offset.
|
||||||
@@ -492,6 +744,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Returns a proxy object for the row at the given index for modification.
|
//! \~english Returns a proxy object for the row at the given index for modification.
|
||||||
//! \~russian Возвращает прокси-объект для строки по заданному индексу для модификации.
|
//! \~russian Возвращает прокси-объект для строки по заданному индексу для модификации.
|
||||||
|
//! \~\sa operator[]
|
||||||
inline Row row(size_t index) { return Row(this, index); }
|
inline Row row(size_t index) { return Row(this, index); }
|
||||||
|
|
||||||
//! \~english Returns a proxy object for the row at the given index for read-only access.
|
//! \~english Returns a proxy object for the row at the given index for read-only access.
|
||||||
@@ -500,21 +753,13 @@ public:
|
|||||||
|
|
||||||
//! \~english Returns a proxy object for the column at the given index for modification.
|
//! \~english Returns a proxy object for the column at the given index for modification.
|
||||||
//! \~russian Возвращает прокси-объект для столбца по заданному индексу для модификации.
|
//! \~russian Возвращает прокси-объект для столбца по заданному индексу для модификации.
|
||||||
|
//! \~\sa col() const
|
||||||
inline Col col(size_t index) { return Col(this, index); }
|
inline Col col(size_t index) { return Col(this, index); }
|
||||||
|
|
||||||
//! \~english Returns a proxy object for the column at the given index for read-only access.
|
//! \~english Returns a proxy object for the column at the given index for read-only access.
|
||||||
//! \~russian Возвращает прокси-объект для столбца по заданному индексу только для чтения.
|
//! \~russian Возвращает прокси-объект для столбца по заданному индексу только для чтения.
|
||||||
inline ColConst col(size_t index) const { return ColConst(this, index); }
|
inline ColConst col(size_t index) const { return ColConst(this, index); }
|
||||||
|
|
||||||
|
|
||||||
//! \~english Replaces a row with the contents of another Row object.
|
|
||||||
//! \~russian Заменяет строку содержимым другого объекта Row.
|
|
||||||
inline PIVector2D<T> & setRow(size_t row, const Row & other) {
|
|
||||||
const size_t sz = piMin<size_t>(cols_, other.sz_);
|
|
||||||
mat._copyRaw(mat.data(cols_ * row), other.data(), sz);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Replaces a row with the contents of a read-only RowConst object.
|
//! \~english Replaces a row with the contents of a read-only RowConst object.
|
||||||
//! \~russian Заменяет строку содержимым объекта RowConst только для чтения.
|
//! \~russian Заменяет строку содержимым объекта RowConst только для чтения.
|
||||||
inline PIVector2D<T> & setRow(size_t row, const RowConst & other) {
|
inline PIVector2D<T> & setRow(size_t row, const RowConst & other) {
|
||||||
@@ -533,25 +778,18 @@ public:
|
|||||||
|
|
||||||
//! \~english Appends a new row to the bottom of the array from another Row object.
|
//! \~english Appends a new row to the bottom of the array from another Row object.
|
||||||
//! \~russian Добавляет новую строку в конец массива из другого объекта Row.
|
//! \~russian Добавляет новую строку в конец массива из другого объекта Row.
|
||||||
inline PIVector2D<T> & addRow(const Row & other) {
|
//! \details
|
||||||
if (cols_ == 0) cols_ = other.sz_;
|
//! \~english If the array was empty, its column count is set to the size of the source row.
|
||||||
const size_t sz = piMin<size_t>(cols_, other.sz_);
|
//! Otherwise, only `min(cols(), other.size())` elements are copied; the rest of the new row is default-initialized.
|
||||||
const size_t ps = mat.size();
|
//! \~russian Если массив был пуст, количество столбцов устанавливается равным размеру исходной строки.
|
||||||
mat.resize(mat.size() + cols_);
|
//! В противном случае копируется только `min(cols(), other.size())` элементов; остальные элементы новой строки инициализируются по
|
||||||
mat._copyRaw(mat.data(ps), other.data(), sz);
|
//! умолчанию.
|
||||||
rows_++;
|
//! \~\sa PIVector::push_back()
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Appends a new row to the bottom of the array from a read-only RowConst object.
|
|
||||||
//! \~russian Добавляет новую строку в конец массива из объекта RowConst только для чтения.
|
|
||||||
inline PIVector2D<T> & addRow(const RowConst & other) {
|
inline PIVector2D<T> & addRow(const RowConst & other) {
|
||||||
if (cols_ == 0) cols_ = other.sz_;
|
if (cols_ == 0) cols_ = other.sz_;
|
||||||
const size_t sz = piMin<size_t>(cols_, other.sz_);
|
mat.append(other.toVector());
|
||||||
const size_t ps = mat.size();
|
|
||||||
mat.resize(mat.size() + cols_);
|
|
||||||
mat._copyRaw(mat.data(ps), other.data(), sz);
|
|
||||||
rows_++;
|
rows_++;
|
||||||
|
mat.resize(rows_ * cols_);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,37 +797,191 @@ public:
|
|||||||
//! \~russian Добавляет новую строку в конец массива из \a PIVector.
|
//! \~russian Добавляет новую строку в конец массива из \a PIVector.
|
||||||
inline PIVector2D<T> & addRow(const PIVector<T> & other) {
|
inline PIVector2D<T> & addRow(const PIVector<T> & other) {
|
||||||
if (cols_ == 0) cols_ = other.size();
|
if (cols_ == 0) cols_ = other.size();
|
||||||
const size_t sz = piMin<size_t>(cols_, other.size());
|
mat.append(other);
|
||||||
const size_t ps = mat.size();
|
|
||||||
mat.resize(mat.size() + cols_);
|
|
||||||
mat._copyRaw(mat.data(ps), other.data(), sz);
|
|
||||||
rows_++;
|
rows_++;
|
||||||
|
mat.resize(rows_ * cols_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Appends \a count new empty rows to the bottom of the array, filled with value \a f.
|
||||||
|
//! \~russian Добавляет \a count новых пустых строк в конец массива, заполненных значением \a f.
|
||||||
|
//! \details
|
||||||
|
//! \~english If the array was empty (no columns defined), the column count is set to 1.
|
||||||
|
//! The new rows are filled with the default value \a f.
|
||||||
|
//! \~russian Если массив был пуст (количество столбцов не определено), количество столбцов устанавливается равным 1.
|
||||||
|
//! Новые строки заполняются значением по умолчанию \a f.
|
||||||
|
//! \~\sa addRow(), appendColumns()
|
||||||
|
inline PIVector2D<T> & appendRows(size_t count, const T & f = T()) {
|
||||||
|
if (count == 0) return *this;
|
||||||
|
if (cols_ == 0) ++cols_;
|
||||||
|
mat.resize(mat.size() + count * cols_, f);
|
||||||
|
rows_ += count;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Appends \a count new empty columns to the end of each row of the array.
|
||||||
|
//! \~russian Добавляет \a count новых пустых столбцов в конец каждой строки массива.
|
||||||
|
//! \details
|
||||||
|
//! \~english If the array was empty (rows not defined), the array becomes a single row with \a count columns.
|
||||||
|
//! If the array already has rows, new elements are inserted at the end of each existing row.
|
||||||
|
//! \~russian Если массив был пуст (строки не определены), массив становится одной строкой с \a count столбцов.
|
||||||
|
//! Если массив уже содержит строки, новые элементы добавляются в конец каждой существующей строки.
|
||||||
|
//! \~\sa appendRows(), addColumn()
|
||||||
|
inline PIVector2D<T> & appendColumns(size_t count, const T & f = T()) {
|
||||||
|
if (count == 0) return *this;
|
||||||
|
if (rows_ == 0) {
|
||||||
|
mat.resize(count, f);
|
||||||
|
rows_ = 1;
|
||||||
|
cols_ = count;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t newCols = cols_ + count;
|
||||||
|
mat.reserve(rows_ * newCols);
|
||||||
|
for (size_t r = rows_; r > 0; --r) {
|
||||||
|
mat.insert(r * cols_, f, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
cols_ = newCols;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Deletes `count` rows starting from the specified row index.
|
||||||
|
//! \~russian Удаляет `count` строк, начиная с указанного индекса строки.
|
||||||
|
//! \details
|
||||||
|
//! \~english Removes the specified rows from the array and updates the row count. If all elements are deleted (array becomes empty),
|
||||||
|
//! both rows and columns are set to 0.
|
||||||
|
//! \~russian Удаляет указанные строки из массива и обновляет количество строк. Если все элементы удалены (массив становится пустым),
|
||||||
|
//! количество строк и столбцов устанавливается в 0.
|
||||||
|
//! \~\sa deleteColumns()
|
||||||
|
inline PIVector2D<T> & deleteRows(size_t row_start, size_t count) {
|
||||||
|
if (row_start >= rows_ || count == 0) return *this;
|
||||||
|
mat.remove(row_start * cols_, cols_ * count);
|
||||||
|
if (isEmpty()) {
|
||||||
|
cols_ = 0;
|
||||||
|
rows_ = 0;
|
||||||
|
} else {
|
||||||
|
rows_ -= count;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Removes the specified columns from the array and updates the column count.
|
||||||
|
//! \~russian Удаляет указанные столбцы из массива и обновляет количество столбцов.
|
||||||
|
//! \details
|
||||||
|
//! \~english Removes \a count columns starting from \a col_start. If \a col_start is out of range or \a count is 0,
|
||||||
|
//! the function does nothing. If \a count extends beyond the last column, only available columns are deleted.
|
||||||
|
//! \~russian Удаляет \a count столбцов начиная с \a col_start. Если \a col_start выходит за границы или \a count равен 0,
|
||||||
|
//! функция ничего не делает. Если \a count выходит за последний столбец, удаляются только доступные столбцы.
|
||||||
|
//! \~\sa removeColumn(), deleteRows()
|
||||||
|
inline PIVector2D<T> & deleteColumns(size_t col_start, size_t count) {
|
||||||
|
if (col_start >= cols_ || rows_ == 0) return *this;
|
||||||
|
count = piMin(count, cols_ - col_start);
|
||||||
|
if (count == 0) return *this;
|
||||||
|
for (size_t r = 0; r < rows_; ++r) {
|
||||||
|
mat.remove(r * (cols_ - count) + col_start, count);
|
||||||
|
}
|
||||||
|
cols_ -= count;
|
||||||
|
mat.resize(rows_ * cols_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Appends a new column to the right of the array from a \a ColConst.
|
||||||
|
//! \~russian Добавляет новую строку в конец массива из \a ColConst.
|
||||||
|
inline PIVector2D<T> & addColumn(const ColConst & other) {
|
||||||
|
if (other.size() == 0) return *this;
|
||||||
|
if (isEmpty()) {
|
||||||
|
mat.reserve(other.size());
|
||||||
|
for (size_t r = 0; r < other.size(); ++r) {
|
||||||
|
mat.append(other[r]);
|
||||||
|
}
|
||||||
|
rows_ = mat.size();
|
||||||
|
cols_ = 1;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t newCols = cols_ + 1;
|
||||||
|
mat.reserve(rows_ * newCols);
|
||||||
|
for (size_t r = rows_; r > 0; --r) {
|
||||||
|
if (r - 1 < other.size()) {
|
||||||
|
mat.insert(r * cols_, other[r - 1]);
|
||||||
|
} else {
|
||||||
|
mat.insert(r * cols_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cols_ = newCols;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \~english Appends a new column to the right of the array from a \a PIVector.
|
||||||
|
//! \~russian Добавляет новую строку в конец массива из \a PIVector.
|
||||||
|
inline PIVector2D<T> & addColumn(const PIVector<T> & other) {
|
||||||
|
if (other.size() == 0) return *this;
|
||||||
|
if (isEmpty()) {
|
||||||
|
mat.append(other);
|
||||||
|
rows_ = mat.size();
|
||||||
|
cols_ = 1;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t newCols = cols_ + 1;
|
||||||
|
mat.reserve(rows_ * newCols);
|
||||||
|
for (size_t r = rows_; r > 0; --r) {
|
||||||
|
if (r - 1 < other.size()) {
|
||||||
|
mat.insert(r * cols_, other[r - 1]);
|
||||||
|
} else {
|
||||||
|
mat.insert(r * cols_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cols_ = newCols;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Resizes the 2D array to new dimensions.
|
//! \~english Resizes the 2D array to new dimensions.
|
||||||
//! \~russian Изменяет размер двумерного массива.
|
//! \~russian Изменяет размер двумерного массива.
|
||||||
//! \details
|
//! \details
|
||||||
//! \~english If the new dimensions are larger, new elements are filled with `f`.
|
//! \~english If the new dimensions are larger, new elements are appended and filled with copies of `f`.
|
||||||
//! If they are smaller, the array is truncated.
|
//! If they are smaller, the array is truncated (excess elements are destroyed). The underlying memory may be reallocated.
|
||||||
//! \~russian Если новые размеры больше, новые элементы заполняются `f`.
|
//! \~russian Если новые размеры больше текущих, новые элементы добавляются в конец и заполняются копиями `f`.
|
||||||
//! Если они меньше, массив обрезается.
|
//! Если новые размеры меньше, массив усекается (лишние элементы уничтожаются). Внутренняя память может быть перераспределена.
|
||||||
|
//! \code
|
||||||
|
//! PIVector2D<int> mat(2, 3, 0); // 2x3 matrix filled with 0
|
||||||
|
//! mat.resize(3, 4, 1); // becomes 3x4, new elements filled with 1
|
||||||
|
//! \endcode
|
||||||
|
//! \~\sa PIVector::resize()
|
||||||
inline PIVector2D<T> & resize(size_t rows, size_t cols, const T & f = T()) {
|
inline PIVector2D<T> & resize(size_t rows, size_t cols, const T & f = T()) {
|
||||||
if (rows == rows_ && cols == cols_) return *this;
|
if (rows == rows_ && cols == cols_) return *this;
|
||||||
PIVector2D<T> tmp(rows, cols, f);
|
if (rows_ == 0 || cols_ == 0) {
|
||||||
size_t copyRows = piMin(rows_, rows);
|
mat.resize(rows * cols, f);
|
||||||
size_t copyCols = piMin(cols_, cols);
|
rows_ = rows;
|
||||||
for (size_t r = 0; r < copyRows; ++r) {
|
cols_ = cols;
|
||||||
for (size_t c = 0; c < copyCols; ++c) {
|
return *this;
|
||||||
tmp.element(r, c) = element(r, c);
|
}
|
||||||
}
|
if (rows != rows_ && cols == cols_) {
|
||||||
|
mat.resize(rows * cols_, f);
|
||||||
|
rows_ = rows;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (cols > cols_) {
|
||||||
|
appendColumns(cols - cols_, f);
|
||||||
|
}
|
||||||
|
if (rows > rows_) {
|
||||||
|
appendRows(rows - rows_, f);
|
||||||
|
}
|
||||||
|
if (cols < cols_) {
|
||||||
|
deleteColumns(cols, cols_ - cols);
|
||||||
|
}
|
||||||
|
if (rows < rows_) {
|
||||||
|
deleteRows(rows, rows_ - rows);
|
||||||
}
|
}
|
||||||
swap(tmp);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Equality operator.
|
//! \~english Equality operator.
|
||||||
//! \~russian Оператор равенства.
|
//! \~russian Оператор равенства.
|
||||||
|
//! \~\sa PIVector::operator==
|
||||||
inline bool operator==(const PIVector2D<T> & t) const {
|
inline bool operator==(const PIVector2D<T> & t) const {
|
||||||
if (cols_ != t.cols_ || rows_ != t.rows_) return false;
|
if (cols_ != t.cols_ || rows_ != t.rows_) return false;
|
||||||
return mat == t.mat;
|
return mat == t.mat;
|
||||||
@@ -601,6 +993,10 @@ public:
|
|||||||
|
|
||||||
//! \~english Converts the 2D array to a vector of vectors (PIVector<PIVector<T>>).
|
//! \~english Converts the 2D array to a vector of vectors (PIVector<PIVector<T>>).
|
||||||
//! \~russian Преобразует двумерный массив в вектор векторов (PIVector<PIVector<T>>).
|
//! \~russian Преобразует двумерный массив в вектор векторов (PIVector<PIVector<T>>).
|
||||||
|
//! \details
|
||||||
|
//! \~english Each row vector is a copy of the corresponding row.
|
||||||
|
//! \~russian Каждый вектор-строка является копией соответствующей строки.
|
||||||
|
//! \~\sa fromVectors(), PIVector::PIVector(const T*, size_t)
|
||||||
inline PIVector<PIVector<T>> toVectors() const {
|
inline PIVector<PIVector<T>> toVectors() const {
|
||||||
PIVector<PIVector<T>> ret;
|
PIVector<PIVector<T>> ret;
|
||||||
ret.reserve(rows_);
|
ret.reserve(rows_);
|
||||||
@@ -623,6 +1019,10 @@ public:
|
|||||||
|
|
||||||
//! \~english Swaps this 2D array with another.
|
//! \~english Swaps this 2D array with another.
|
||||||
//! \~russian Меняет местами этот двумерный массив с другим.
|
//! \~russian Меняет местами этот двумерный массив с другим.
|
||||||
|
//! \details
|
||||||
|
//! \~english Swaps the flat vectors and the dimension members. Very fast, no memory allocation.
|
||||||
|
//! \~russian Обменивает внутренние плоские векторы и члены, хранящие размеры. Очень быстро, без выделения памяти.
|
||||||
|
//! \~\sa PIVector::swap()
|
||||||
inline void swap(PIVector2D<T> & other) {
|
inline void swap(PIVector2D<T> & other) {
|
||||||
mat.swap(other.mat);
|
mat.swap(other.mat);
|
||||||
piSwap<size_t>(rows_, other.rows_);
|
piSwap<size_t>(rows_, other.rows_);
|
||||||
@@ -640,6 +1040,10 @@ public:
|
|||||||
|
|
||||||
//! \~english Clears the array, removing all elements and setting dimensions to 0.
|
//! \~english Clears the array, removing all elements and setting dimensions to 0.
|
||||||
//! \~russian Очищает массив, удаляя все элементы и устанавливая размеры в 0.
|
//! \~russian Очищает массив, удаляя все элементы и устанавливая размеры в 0.
|
||||||
|
//! \details
|
||||||
|
//! \~english The capacity of the underlying flat vector may remain unchanged.
|
||||||
|
//! \~russian Ёмкость внутреннего плоского вектора может остаться неизменной.
|
||||||
|
//! \~\sa PIVector::clear()
|
||||||
inline void clear() {
|
inline void clear() {
|
||||||
rows_ = cols_ = 0;
|
rows_ = cols_ = 0;
|
||||||
mat.clear();
|
mat.clear();
|
||||||
@@ -648,64 +1052,70 @@ public:
|
|||||||
|
|
||||||
//! \~english Checks if the underlying flat vector contains the element `e`.
|
//! \~english Checks if the underlying flat vector contains the element `e`.
|
||||||
//! \~russian Проверяет, содержит ли внутренний плоский вектор элемент `e`.
|
//! \~russian Проверяет, содержит ли внутренний плоский вектор элемент `e`.
|
||||||
inline bool contains(const T & e, ssize_t start = 0) const { return mat.contains(e, start); }
|
//! \~\sa PIVector::contains()
|
||||||
|
inline bool contains(const T & e) const { return mat.contains(e); }
|
||||||
//! \~english Checks if the underlying flat vector contains all elements of `v`.
|
|
||||||
//! \~russian Проверяет, содержит ли внутренний плоский вектор все элементы `v`.
|
|
||||||
inline bool contains(const PIVector<T> & v, ssize_t start = 0) const { return mat.contains(v, start); }
|
|
||||||
|
|
||||||
//! \~english Counts occurrences of `e` in the underlying flat vector.
|
//! \~english Counts occurrences of `e` in the underlying flat vector.
|
||||||
//! \~russian Подсчитывает количество вхождений `e` во внутреннем плоском векторе.
|
//! \~russian Подсчитывает количество вхождений `e` во внутреннем плоском векторе.
|
||||||
inline int entries(const T & e, ssize_t start = 0) const { return mat.entries(e, start); }
|
//! \~\sa PIVector::entries()
|
||||||
|
inline int entries(const T & e) const { return mat.entries(e); }
|
||||||
|
|
||||||
//! \~english Counts elements in the flat vector that pass the `test`.
|
//! \~english Counts elements in the flat vector that pass the `test`.
|
||||||
//! \~russian Подсчитывает элементы в плоском векторе, проходящие `test`.
|
//! \~russian Подсчитывает элементы в плоском векторе, проходящие `test`.
|
||||||
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const { return mat.entries(test, start); }
|
//! \~\sa PIVector::entries(std::function)
|
||||||
|
inline int entries(std::function<bool(const T & e)> test) const { return mat.entries(test); }
|
||||||
|
|
||||||
|
|
||||||
//! \~english Returns the first index (row, col) of `e` in the 2D array.
|
//! \~english Returns the first index (row, col) of `e` in the 2D array.
|
||||||
//! \~russian Возвращает первый индекс (строка, столбец) элемента `e` в двумерном массиве.
|
//! \~russian Возвращает первый индекс (строка, столбец) элемента `e` в двумерном массиве.
|
||||||
inline PIPair<ssize_t, ssize_t> indexOf(const T & e, ssize_t start = 0) const {
|
//! \~\sa PIVector::indexOf()
|
||||||
ssize_t flat = mat.indexOf(e, start);
|
inline Index indexOf(const T & e) const {
|
||||||
if (flat < 0 || cols_ == 0) return PIPair<ssize_t, ssize_t>(-1, -1);
|
ssize_t flat = mat.indexOf(e);
|
||||||
return PIPair<ssize_t, ssize_t>(flat / cols_, flat % cols_);
|
if (flat < 0 || cols_ == 0) return Index{-1, -1};
|
||||||
|
return Index{flat / static_cast<ssize_t>(cols_), flat % static_cast<ssize_t>(cols_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the first index (row, col) in the 2D array that passes the `test`.
|
//! \~english Returns the first index (row, col) in the 2D array that passes the `test`.
|
||||||
//! \~russian Возвращает первый индекс (строка, столбец) в двумерном массиве, проходящий `test`.
|
//! \~russian Возвращает первый индекс (строка, столбец) в двумерном массиве, проходящий `test`.
|
||||||
inline PIPair<ssize_t, ssize_t> indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
//! \~\sa PIVector::indexWhere()
|
||||||
|
inline Index indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
|
||||||
ssize_t flat = mat.indexWhere(test, start);
|
ssize_t flat = mat.indexWhere(test, start);
|
||||||
if (flat < 0 || cols_ == 0) return PIPair<ssize_t, ssize_t>(-1, -1);
|
if (flat < 0 || cols_ == 0) return Index{-1, -1};
|
||||||
return PIPair<ssize_t, ssize_t>(flat / cols_, flat % cols_);
|
return Index{flat / static_cast<ssize_t>(cols_), flat % static_cast<ssize_t>(cols_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the last index (row, col) of `e` in the 2D array.
|
//! \~english Returns the last index (row, col) of `e` in the 2D array.
|
||||||
//! \~russian Возвращает последний индекс (строка, столбец) элемента `e` в двумерном массиве.
|
//! \~russian Возвращает последний индекс (строка, столбец) элемента `e` в двумерном массиве.
|
||||||
inline PIPair<ssize_t, ssize_t> lastIndexOf(const T & e, ssize_t start = -1) const {
|
//! \~\sa PIVector::lastIndexOf()
|
||||||
|
inline Index lastIndexOf(const T & e, ssize_t start = -1) const {
|
||||||
ssize_t flat = mat.lastIndexOf(e, start);
|
ssize_t flat = mat.lastIndexOf(e, start);
|
||||||
if (flat < 0 || cols_ == 0) return PIPair<ssize_t, ssize_t>(-1, -1);
|
if (flat < 0 || cols_ == 0) return Index{-1, -1};
|
||||||
return PIPair<ssize_t, ssize_t>(flat / cols_, flat % cols_);
|
return Index{flat / static_cast<ssize_t>(cols_), flat % static_cast<ssize_t>(cols_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns the last index (row, col) in the 2D array that passes the `test`.
|
//! \~english Returns the last index (row, col) in the 2D array that passes the `test`.
|
||||||
//! \~russian Возвращает последний индекс (строка, столбец) в двумерном массиве, проходящий `test`.
|
//! \~russian Возвращает последний индекс (строка, столбец) в двумерном массиве, проходящий `test`.
|
||||||
inline PIPair<ssize_t, ssize_t> lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
//! \~\sa PIVector::lastIndexWhere()
|
||||||
|
inline Index lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
||||||
ssize_t flat = mat.lastIndexWhere(test, start);
|
ssize_t flat = mat.lastIndexWhere(test, start);
|
||||||
if (flat < 0 || cols_ == 0) return PIPair<ssize_t, ssize_t>(-1, -1);
|
if (flat < 0 || cols_ == 0) return Index{-1, -1};
|
||||||
return PIPair<ssize_t, ssize_t>(flat / cols_, flat % cols_);
|
return Index{flat / static_cast<ssize_t>(cols_), flat % static_cast<ssize_t>(cols_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \~english Tests if any element in the flat vector passes the `test`.
|
//! \~english Tests if any element in the flat vector passes the `test`.
|
||||||
//! \~russian Проверяет, проходит ли какой-либо элемент в плоском векторе `test`.
|
//! \~russian Проверяет, проходит ли какой-либо элемент в плоском векторе `test`.
|
||||||
|
//! \~\sa PIVector::any()
|
||||||
inline bool any(std::function<bool(const T & e)> test) const { return mat.any(test); }
|
inline bool any(std::function<bool(const T & e)> test) const { return mat.any(test); }
|
||||||
|
|
||||||
//! \~english Tests if all elements in the flat vector pass the `test`.
|
//! \~english Tests if all elements in the flat vector pass the `test`.
|
||||||
//! \~russian Проверяет, проходят ли все элементы в плоском векторе `test`.
|
//! \~russian Проверяет, проходят ли все элементы в плоском векторе `test`.
|
||||||
|
//! \~\sa PIVector::every()
|
||||||
inline bool every(std::function<bool(const T & e)> test) const { return mat.every(test); }
|
inline bool every(std::function<bool(const T & e)> test) const { return mat.every(test); }
|
||||||
|
|
||||||
//! \~english Fills the entire 2D array with copies of `e`.
|
//! \~english Fills the entire 2D array with copies of `e`.
|
||||||
//! \~russian Заполняет весь двумерный массив копиями `e`.
|
//! \~russian Заполняет весь двумерный массив копиями `e`.
|
||||||
|
//! \~\sa PIVector::fill()
|
||||||
inline PIVector2D<T> & fill(const T & e = T()) {
|
inline PIVector2D<T> & fill(const T & e = T()) {
|
||||||
mat.fill(e);
|
mat.fill(e);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -713,6 +1123,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Fills the entire 2D array using a generator function `f` based on flat index.
|
//! \~english Fills the entire 2D array using a generator function `f` based on flat index.
|
||||||
//! \~russian Заполняет весь двумерный массив, используя функцию-генератор `f` на основе плоского индекса.
|
//! \~russian Заполняет весь двумерный массив, используя функцию-генератор `f` на основе плоского индекса.
|
||||||
|
//! \~\sa PIVector::fill(std::function)
|
||||||
inline PIVector2D<T> & fill(std::function<T(size_t i)> f) {
|
inline PIVector2D<T> & fill(std::function<T(size_t i)> f) {
|
||||||
mat.fill(f);
|
mat.fill(f);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -724,6 +1135,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Assigns new size and fills with value.
|
//! \~english Assigns new size and fills with value.
|
||||||
//! \~russian Задаёт новый размер и заполняет значением.
|
//! \~russian Задаёт новый размер и заполняет значением.
|
||||||
|
//! \~\sa PIVector::assign(size_t, const T&)
|
||||||
inline PIVector2D<T> & assign(size_t rows, size_t cols, const T & f = T()) {
|
inline PIVector2D<T> & assign(size_t rows, size_t cols, const T & f = T()) {
|
||||||
mat.assign(rows * cols, f);
|
mat.assign(rows * cols, f);
|
||||||
rows_ = rows;
|
rows_ = rows;
|
||||||
@@ -732,9 +1144,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: исправить - при транспонировании количество строк становится количеством столбцов и наоборот
|
|
||||||
//! \~english Returns a transposed 2D array (rows become columns and vice versa).
|
//! \~english Returns a transposed 2D array (rows become columns and vice versa).
|
||||||
//! \~russian Возвращает транспонированный двумерный массив (строки становятся столбцами и наоборот).
|
//! \~russian Возвращает транспонированный двумерный массив (строки становятся столбцами и наоборот).
|
||||||
|
//! \details
|
||||||
|
//! \~english The element at (r, c) in the original becomes at (c, r) in the result.
|
||||||
|
//! \~russian Элемент (r, c) исходного массива становится элементом (c, r) в результате.
|
||||||
|
//! \code
|
||||||
|
//! PIVector2D<int> mat(2, 3, ...);
|
||||||
|
//! auto t = mat.transposed(); // now 3x2
|
||||||
|
//! \endcode
|
||||||
inline PIVector2D<T> transposed() const {
|
inline PIVector2D<T> transposed() const {
|
||||||
if (isEmpty()) return PIVector2D<T>();
|
if (isEmpty()) return PIVector2D<T>();
|
||||||
PIVector2D<T> result(cols_, rows_);
|
PIVector2D<T> result(cols_, rows_);
|
||||||
@@ -748,6 +1166,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Reverses the order of rows in place.
|
//! \~english Reverses the order of rows in place.
|
||||||
//! \~russian Изменяет порядок строк на обратный на месте.
|
//! \~russian Изменяет порядок строк на обратный на месте.
|
||||||
|
//! \~\sa reverseColumns(), PIVector::reverse()
|
||||||
inline PIVector2D<T> & reverseRows() {
|
inline PIVector2D<T> & reverseRows() {
|
||||||
const size_t half = rows_ / 2;
|
const size_t half = rows_ / 2;
|
||||||
for (size_t i = 0; i < half; ++i) {
|
for (size_t i = 0; i < half; ++i) {
|
||||||
@@ -762,6 +1181,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Reverses the order of columns in each row in place.
|
//! \~english Reverses the order of columns in each row in place.
|
||||||
//! \~russian Изменяет порядок столбцов в каждой строке на обратный на месте.
|
//! \~russian Изменяет порядок столбцов в каждой строке на обратный на месте.
|
||||||
|
//! \~\sa reverseRows(), PIVector::reverse()
|
||||||
inline PIVector2D<T> & reverseColumns() {
|
inline PIVector2D<T> & reverseColumns() {
|
||||||
for (size_t r = 0; r < rows_; ++r) {
|
for (size_t r = 0; r < rows_; ++r) {
|
||||||
Row currentRow = row(r);
|
Row currentRow = row(r);
|
||||||
@@ -775,10 +1195,14 @@ public:
|
|||||||
|
|
||||||
//! \~english Returns a sub-2D array (a range of rows and columns).
|
//! \~english Returns a sub-2D array (a range of rows and columns).
|
||||||
//! \~russian Возвращает подмассив (диапазон строк и столбцов).
|
//! \~russian Возвращает подмассив (диапазон строк и столбцов).
|
||||||
|
//! \details
|
||||||
|
//! \~english If the range exceeds the array boundaries, it is clipped. If rowCount or colCount is 0, an empty array is returned.
|
||||||
|
//! \~russian Если диапазон выходит за границы массива, он обрезается. Если rowCount или colCount равны 0, возвращается пустой массив.
|
||||||
|
//! \~\sa PIVector::getRange()
|
||||||
inline PIVector2D<T> getRange(size_t rowStart, size_t rowCount, size_t colStart, size_t colCount) const {
|
inline PIVector2D<T> getRange(size_t rowStart, size_t rowCount, size_t colStart, size_t colCount) const {
|
||||||
if (rowStart >= rows_ || colStart >= cols_ || rowCount == 0 || colCount == 0) return PIVector2D<T>();
|
if (rowStart >= rows_ || colStart >= cols_ || rowCount == 0 || colCount == 0) return PIVector2D<T>();
|
||||||
size_t actualRowCount = piMin(rowCount, rows_ - rowStart);
|
const size_t actualRowCount = piMin<size_t>(rowCount, rows_ - rowStart);
|
||||||
size_t actualColCount = piMin(colCount, cols_ - colStart);
|
const size_t actualColCount = piMin<size_t>(colCount, cols_ - colStart);
|
||||||
|
|
||||||
PIVector2D<T> result(actualRowCount, actualColCount);
|
PIVector2D<T> result(actualRowCount, actualColCount);
|
||||||
for (size_t r = 0; r < actualRowCount; ++r) {
|
for (size_t r = 0; r < actualRowCount; ++r) {
|
||||||
@@ -791,6 +1215,10 @@ public:
|
|||||||
|
|
||||||
//! \~english Applies a function to each element and returns a new 2D array of a different type.
|
//! \~english Applies a function to each element and returns a new 2D array of a different type.
|
||||||
//! \~russian Применяет функцию к каждому элементу и возвращает новый двумерный массив другого типа.
|
//! \~russian Применяет функцию к каждому элементу и возвращает новый двумерный массив другого типа.
|
||||||
|
//! \details
|
||||||
|
//! \~english The original array is not modified.
|
||||||
|
//! \~russian Исходный массив не изменяется.
|
||||||
|
//! \~\sa PIVector::map()
|
||||||
template<typename ST>
|
template<typename ST>
|
||||||
inline PIVector2D<ST> map(std::function<ST(const T & e)> f) const {
|
inline PIVector2D<ST> map(std::function<ST(const T & e)> f) const {
|
||||||
return PIVector2D<ST>(rows_, cols_, mat.template map<ST>(f));
|
return PIVector2D<ST>(rows_, cols_, mat.template map<ST>(f));
|
||||||
@@ -798,6 +1226,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Applies a function (with row and col indices) to each element and returns a new 2D array.
|
//! \~english Applies a function (with row and col indices) to each element and returns a new 2D array.
|
||||||
//! \~russian Применяет функцию (с индексами строки и столбца) к каждому элементу и возвращает новый двумерный массив.
|
//! \~russian Применяет функцию (с индексами строки и столбца) к каждому элементу и возвращает новый двумерный массив.
|
||||||
|
//! \~\sa PIVector::mapIndexed()
|
||||||
template<typename ST>
|
template<typename ST>
|
||||||
inline PIVector2D<ST> mapIndexed(std::function<ST(size_t row, size_t col, const T & e)> f) const {
|
inline PIVector2D<ST> mapIndexed(std::function<ST(size_t row, size_t col, const T & e)> f) const {
|
||||||
PIVector<ST> mappedMat;
|
PIVector<ST> mappedMat;
|
||||||
@@ -810,20 +1239,22 @@ public:
|
|||||||
return PIVector2D<ST>(rows_, cols_, std::move(mappedMat));
|
return PIVector2D<ST>(rows_, cols_, std::move(mappedMat));
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Итерация по строкам и столбцам ---
|
|
||||||
//! \~english Applies a function to each row (modifiable).
|
//! \~english Applies a function to each row (modifiable).
|
||||||
//! \~russian Применяет функцию к каждой строке (с возможностью изменения).
|
//! \~russian Применяет функцию к каждой строке (с возможностью изменения).
|
||||||
|
//! \~\sa forEachRow() const, PIVector::forEach()
|
||||||
inline PIVector2D<T> & forEachRow(std::function<void(Row)> f) {
|
inline PIVector2D<T> & forEachRow(std::function<void(Row)> f) {
|
||||||
for (size_t r = 0; r < rows_; ++r)
|
for (size_t r = 0; r < rows_; ++r)
|
||||||
f(row(r));
|
f(row(r));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Applies a function to each row (read-only).
|
//! \~english Applies a function to each row (read-only).
|
||||||
//! \~russian Применяет функцию к каждой строке (только чтение).
|
//! \~russian Применяет функцию к каждой строке (только чтение).
|
||||||
inline void forEachRow(std::function<void(RowConst)> f) const {
|
inline void forEachRow(std::function<void(RowConst)> f) const {
|
||||||
for (size_t r = 0; r < rows_; ++r)
|
for (size_t r = 0; r < rows_; ++r)
|
||||||
f(row(r));
|
f(row(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Applies a function to each column (modifiable).
|
//! \~english Applies a function to each column (modifiable).
|
||||||
//! \~russian Применяет функцию к каждому столбцу (с возможностью изменения).
|
//! \~russian Применяет функцию к каждому столбцу (с возможностью изменения).
|
||||||
inline PIVector2D<T> & forEachColumn(std::function<void(Col)> f) {
|
inline PIVector2D<T> & forEachColumn(std::function<void(Col)> f) {
|
||||||
@@ -831,8 +1262,10 @@ public:
|
|||||||
f(col(c));
|
f(col(c));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Applies a function to each column (read-only).
|
//! \~english Applies a function to each column (read-only).
|
||||||
//! \~russian Применяет функцию к каждому столбцу (только чтение).
|
//! \~russian Применяет функцию к каждому столбцу (только чтение).
|
||||||
|
//! \param f Function taking a \a ColConst.
|
||||||
inline void forEachColumn(std::function<void(ColConst)> f) const {
|
inline void forEachColumn(std::function<void(ColConst)> f) const {
|
||||||
for (size_t c = 0; c < cols_; ++c)
|
for (size_t c = 0; c < cols_; ++c)
|
||||||
f(col(c));
|
f(col(c));
|
||||||
@@ -840,6 +1273,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Accumulates a value across all elements.
|
//! \~english Accumulates a value across all elements.
|
||||||
//! \~russian Аккумулирует значение по всем элементам.
|
//! \~russian Аккумулирует значение по всем элементам.
|
||||||
|
//! \~\sa PIVector::reduce()
|
||||||
template<typename ST>
|
template<typename ST>
|
||||||
inline ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
inline ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||||
return mat.template reduce<ST>(f, initial);
|
return mat.template reduce<ST>(f, initial);
|
||||||
@@ -847,6 +1281,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Accumulates a value across all elements with indices.
|
//! \~english Accumulates a value across all elements with indices.
|
||||||
//! \~russian Аккумулирует значение по всем элементам с индексами.
|
//! \~russian Аккумулирует значение по всем элементам с индексами.
|
||||||
|
//! \~\sa PIVector::reduceIndexed()
|
||||||
template<typename ST>
|
template<typename ST>
|
||||||
inline ST reduceIndexed(std::function<ST(size_t row, size_t col, const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
inline ST reduceIndexed(std::function<ST(size_t row, size_t col, const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||||
ST ret(initial);
|
ST ret(initial);
|
||||||
@@ -860,52 +1295,45 @@ public:
|
|||||||
|
|
||||||
//! \~english Removes a row from the 2D array.
|
//! \~english Removes a row from the 2D array.
|
||||||
//! \~russian Удаляет строку из двумерного массива.
|
//! \~russian Удаляет строку из двумерного массива.
|
||||||
inline PIVector2D<T> & removeRow(size_t row) {
|
//! \details
|
||||||
if (row >= rows_) return *this;
|
//! \~english If the last row is removed and the array becomes empty, \a cols() is set to 0.
|
||||||
size_t startIdx = row * cols_;
|
//! \~russian Если удаляется последняя строка и массив становится пустым, \a cols() устанавливается в 0.
|
||||||
mat.remove(startIdx, cols_);
|
//! \~\sa removeColumn(), PIVector::remove()
|
||||||
rows_--;
|
inline PIVector2D<T> & removeRow(size_t row) { return deleteRows(row, 1); }
|
||||||
if (rows_ == 0) cols_ = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Removes a column from the 2D array.
|
//! \~english Removes a column from the 2D array.
|
||||||
//! \~russian Удаляет столбец из двумерного массива.
|
//! \~russian Удаляет столбец из двумерного массива.
|
||||||
inline PIVector2D<T> & removeColumn(size_t col) {
|
//! \details
|
||||||
if (col >= cols_ || rows_ == 0) return *this;
|
//! \~english This operation is more expensive than removing a row because elements must be moved.
|
||||||
PIVector2D<T> result(rows_, cols_ - 1);
|
//! \~russian Эта операция дороже, чем удаление строки, поскольку требуется перемещение элементов.
|
||||||
for (size_t r = 0; r < rows_; ++r) {
|
//! \~\sa removeRow(), PIVector::remove()
|
||||||
for (size_t c = 0, nc = 0; c < cols_; ++c) {
|
inline PIVector2D<T> & removeColumn(size_t col) { return deleteColumns(col, 1); }
|
||||||
if (c == col) continue;
|
|
||||||
result.element(r, nc++) = element(r, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
swap(result);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Removes all rows that satisfy a condition.
|
//! \~english Removes all rows that satisfy a condition.
|
||||||
//! \~russian Удаляет все строки, удовлетворяющие условию.
|
//! \~russian Удаляет все строки, удовлетворяющие условию.
|
||||||
|
//! \details
|
||||||
|
//! \~english Rows are removed from the bottom to avoid index shifting issues.
|
||||||
|
//! \~russian Строки удаляются снизу вверх, чтобы избежать проблем со смещением индексов.
|
||||||
|
//! \~\sa removeColumnsWhere(), PIVector::removeWhere()
|
||||||
inline PIVector2D<T> & removeRowsWhere(std::function<bool(const RowConst &)> test) {
|
inline PIVector2D<T> & removeRowsWhere(std::function<bool(const RowConst &)> test) {
|
||||||
ssize_t r = rows_ - 1;
|
ssize_t r = rows_;
|
||||||
while (r >= 0) {
|
while (--r >= 0) {
|
||||||
if (test(RowConst(this, r))) {
|
if (test(RowConst(this, r))) {
|
||||||
removeRow(r);
|
removeRow(r);
|
||||||
}
|
}
|
||||||
--r;
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Removes all columns that satisfy a condition.
|
//! \~english Removes all columns that satisfy a condition.
|
||||||
//! \~russian Удаляет все столбцы, удовлетворяющие условию.
|
//! \~russian Удаляет все столбцы, удовлетворяющие условию.
|
||||||
|
//! \~\sa removeRowsWhere()
|
||||||
inline PIVector2D<T> & removeColumnsWhere(std::function<bool(const ColConst &)> test) {
|
inline PIVector2D<T> & removeColumnsWhere(std::function<bool(const ColConst &)> test) {
|
||||||
ssize_t c = cols_ - 1;
|
ssize_t c = cols_;
|
||||||
while (c >= 0) {
|
while (--c >= 0) {
|
||||||
if (test(ColConst(this, c))) {
|
if (test(ColConst(this, c))) {
|
||||||
removeColumn(c);
|
removeColumn(c);
|
||||||
}
|
}
|
||||||
--c;
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -913,6 +1341,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Returns a new 2D array containing only the rows that pass the test.
|
//! \~english Returns a new 2D array containing only the rows that pass the test.
|
||||||
//! \~russian Возвращает новый двумерный массив, содержащий только строки, прошедшие проверку.
|
//! \~russian Возвращает новый двумерный массив, содержащий только строки, прошедшие проверку.
|
||||||
|
//! \~\sa filterColumns(), PIVector::filter()
|
||||||
inline PIVector2D<T> filterRows(std::function<bool(const RowConst &)> test) const {
|
inline PIVector2D<T> filterRows(std::function<bool(const RowConst &)> test) const {
|
||||||
PIVector2D<T> result;
|
PIVector2D<T> result;
|
||||||
for (size_t r = 0; r < rows_; ++r) {
|
for (size_t r = 0; r < rows_; ++r) {
|
||||||
@@ -926,6 +1355,7 @@ public:
|
|||||||
|
|
||||||
//! \~english Returns a new 2D array containing only the columns that pass the test.
|
//! \~english Returns a new 2D array containing only the columns that pass the test.
|
||||||
//! \~russian Возвращает новый двумерный массив, содержащий только столбцы, прошедшие проверку.
|
//! \~russian Возвращает новый двумерный массив, содержащий только столбцы, прошедшие проверку.
|
||||||
|
//! \~\sa filterRows()
|
||||||
inline PIVector2D<T> filterColumns(std::function<bool(const ColConst &)> test) const {
|
inline PIVector2D<T> filterColumns(std::function<bool(const ColConst &)> test) const {
|
||||||
if (isEmpty()) return PIVector2D<T>();
|
if (isEmpty()) return PIVector2D<T>();
|
||||||
PIVector<size_t> goodCols;
|
PIVector<size_t> goodCols;
|
||||||
@@ -934,23 +1364,13 @@ public:
|
|||||||
goodCols << c;
|
goodCols << c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PIVector2D<T> result(rows_, goodCols.size());
|
PIVector2D<T> result;
|
||||||
for (size_t r = 0; r < rows_; ++r) {
|
for (size_t gc = 0; gc < goodCols.size(); ++gc) {
|
||||||
for (size_t gc = 0; gc < goodCols.size(); ++gc) {
|
result.addColumn(col(goodCols[gc]));
|
||||||
result.element(r, gc) = element(r, goodCols[gc]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns a new 2D array (as a single row) containing only the elements that pass the test.
|
|
||||||
//! \~russian Возвращает новый двумерный массив (в виде одной строки), содержащий только элементы, прошедшие проверку.
|
|
||||||
inline PIVector2D<T> filterElements(std::function<bool(const T &)> test) const {
|
|
||||||
PIVector<T> filtered = mat.filter(test);
|
|
||||||
if (filtered.isEmpty()) return PIVector2D<T>();
|
|
||||||
return PIVector2D<T>(1, filtered.size(), filtered);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t rows_, cols_;
|
size_t rows_, cols_;
|
||||||
PIVector<T> mat;
|
PIVector<T> mat;
|
||||||
|
|||||||
@@ -245,9 +245,6 @@ inline constexpr T piAbs(const T & v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Templated function return minimum of two values
|
|
||||||
//! \~russian Шаблонный метод, возвращающий минимум из двух значений
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr T piMin(const T & f, const T & s) {
|
constexpr T piMin(const T & f, const T & s) {
|
||||||
return ((f > s) ? s : f);
|
return ((f > s) ? s : f);
|
||||||
@@ -285,9 +282,6 @@ constexpr T piMin(const T & f, const T & s, const Args &... args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Templated function return maximum of two values
|
|
||||||
//! \~russian Шаблонный метод, возвращающий максимум из двух значений
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr T piMax(const T & f, const T & s) {
|
constexpr T piMax(const T & f, const T & s) {
|
||||||
return ((f < s) ? s : f);
|
return ((f < s) ? s : f);
|
||||||
|
|||||||
@@ -64,16 +64,7 @@ PIP_EXPORT PIString errorString();
|
|||||||
//! \~russian Сброс последней ошибки
|
//! \~russian Сброс последней ошибки
|
||||||
PIP_EXPORT void errorClear();
|
PIP_EXPORT void errorClear();
|
||||||
|
|
||||||
//! \ingroup Core
|
|
||||||
//! \brief
|
|
||||||
//! \~english Initialize random number generator
|
|
||||||
//! \~russian Инициализация генератора случайных чисел
|
|
||||||
PIP_EXPORT void randomize();
|
PIP_EXPORT void randomize();
|
||||||
|
|
||||||
//! \ingroup Core
|
|
||||||
//! \brief
|
|
||||||
//! \~english Returns random integer value
|
|
||||||
//! \~russian Возвращает случайное целое число
|
|
||||||
PIP_EXPORT int randomi();
|
PIP_EXPORT int randomi();
|
||||||
|
|
||||||
//! \ingroup Core
|
//! \ingroup Core
|
||||||
|
|||||||
@@ -45,15 +45,11 @@ public:
|
|||||||
s = size_;
|
s = size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Copy constructor
|
|
||||||
//! \~russian Конструктор копирования
|
|
||||||
PIMemoryBlock(const PIMemoryBlock & o) {
|
PIMemoryBlock(const PIMemoryBlock & o) {
|
||||||
d = o.d;
|
d = o.d;
|
||||||
s = o.s;
|
s = o.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Assignment operator
|
|
||||||
//! \~russian Оператор присваивания
|
|
||||||
PIMemoryBlock & operator=(const PIMemoryBlock & o) {
|
PIMemoryBlock & operator=(const PIMemoryBlock & o) {
|
||||||
d = o.d;
|
d = o.d;
|
||||||
s = o.s;
|
s = o.s;
|
||||||
|
|||||||
@@ -29,53 +29,21 @@
|
|||||||
|
|
||||||
#include "pimathbase.h"
|
#include "pimathbase.h"
|
||||||
|
|
||||||
//! \~english Geographical ellipsoid Earth model
|
|
||||||
//! \~russian Географическая эллипсоидная модель Земли
|
|
||||||
class PIP_EXPORT PIEllipsoidModel {
|
class PIP_EXPORT PIEllipsoidModel {
|
||||||
public:
|
public:
|
||||||
//! \~english Default constructor
|
|
||||||
//! \~russian Конструктор по умолчанию
|
|
||||||
PIEllipsoidModel();
|
PIEllipsoidModel();
|
||||||
|
double eccSquared() const { return eccentricity * eccentricity; } // eccentricity squared
|
||||||
//! \~english Get eccentricity squared
|
|
||||||
//! \~russian Получить квадрат эксцентриситета
|
|
||||||
double eccSquared() const { return eccentricity * eccentricity; }
|
|
||||||
|
|
||||||
//! \~english Get semi-minor axis (b)
|
|
||||||
//! \~russian Получить малую полуось (b)
|
|
||||||
double b() const { return a * sqrt(1 - eccSquared()); }
|
double b() const { return a * sqrt(1 - eccSquared()); }
|
||||||
|
|
||||||
//! \~english WGS84 ellipsoid model
|
|
||||||
//! \~russian Эллипсоид WGS84
|
|
||||||
static PIEllipsoidModel WGS84Ellipsoid();
|
static PIEllipsoidModel WGS84Ellipsoid();
|
||||||
|
|
||||||
//! \~english PZ90 ellipsoid model
|
|
||||||
//! \~russian Эллипсоид ПЗ-90
|
|
||||||
static PIEllipsoidModel PZ90Ellipsoid();
|
static PIEllipsoidModel PZ90Ellipsoid();
|
||||||
|
|
||||||
//! \~english GPS ellipsoid (same as WGS84)
|
|
||||||
//! \~russian Эллипсоид GPS (то же что WGS84)
|
|
||||||
static PIEllipsoidModel GPSEllipsoid();
|
static PIEllipsoidModel GPSEllipsoid();
|
||||||
|
|
||||||
//! \~english Krasovskiy ellipsoid model
|
|
||||||
//! \~russian Эллипсоид Красовского
|
|
||||||
static PIEllipsoidModel KrasovskiyEllipsoid();
|
static PIEllipsoidModel KrasovskiyEllipsoid();
|
||||||
|
|
||||||
//! \~english Major semi-axis (meters)
|
double a; /// Major axis of Earth in meters
|
||||||
//! \~russian Большая полуось (метры)
|
double flattening; /// Flattening (ellipsoid parameter)
|
||||||
double a;
|
double eccentricity; /// Eccentricity (ellipsoid parameter)
|
||||||
|
double angVelocity; /// Angular velocity of Earth in radians/sec
|
||||||
//! \~english Flattening (f = (a-b)/a)
|
|
||||||
//! \~russian Сплюснутость (f = (a-b)/a)
|
|
||||||
double flattening;
|
|
||||||
|
|
||||||
//! \~english First eccentricity
|
|
||||||
//! \~russian Первый эксцентриситет
|
|
||||||
double eccentricity;
|
|
||||||
|
|
||||||
//! \~english Angular velocity (rad/sec)
|
|
||||||
//! \~russian Угловая скорость (рад/сек)
|
|
||||||
double angVelocity;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,338 +29,147 @@
|
|||||||
#include "piellipsoidmodel.h"
|
#include "piellipsoidmodel.h"
|
||||||
#include "pimathvector.h"
|
#include "pimathvector.h"
|
||||||
|
|
||||||
//! \~english Geographical position class
|
|
||||||
//! \~russian Класс географической позиции
|
|
||||||
class PIP_EXPORT PIGeoPosition: public PIMathVectorT3d {
|
class PIP_EXPORT PIGeoPosition: public PIMathVectorT3d {
|
||||||
public:
|
public:
|
||||||
//! \~english Coordinate system types
|
|
||||||
//! \~russian Типы систем координат
|
|
||||||
enum CoordinateSystem {
|
enum CoordinateSystem {
|
||||||
Unknown = 0, //!< Unknown coordinate system
|
Unknown = 0, /// Unknown coordinate system
|
||||||
Geodetic, //!< Geodetic latitude, longitude, and height above ellipsoid
|
Geodetic, /// Geodetic latitude, longitude, and height above ellipsoid
|
||||||
Geocentric, //!< Geocentric (regular spherical coordinates)
|
Geocentric, /// Geocentric (regular spherical coordinates)
|
||||||
Cartesian, //!< Cartesian (Earth-centered, Earth-fixed)
|
Cartesian, /// Cartesian (Earth-centered, Earth-fixed)
|
||||||
Spherical //!< Spherical coordinates (theta,phi,radius)
|
Spherical /// Spherical coordinates (theta,phi,radius)
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english One centimeter tolerance
|
static const double one_cm_tolerance; /// One centimeter tolerance.
|
||||||
//! \~russian Допуск один сантиметр
|
static const double one_mm_tolerance; /// One millimeter tolerance.
|
||||||
static const double one_cm_tolerance;
|
static const double one_um_tolerance; /// One micron tolerance.
|
||||||
|
static double position_tolerance; /// Default tolerance (default 1mm)
|
||||||
//! \~english One millimeter tolerance
|
|
||||||
//! \~russian Допуск один миллиметр
|
|
||||||
static const double one_mm_tolerance;
|
|
||||||
|
|
||||||
//! \~english One micron tolerance
|
|
||||||
//! \~russian Допуск один микрон
|
|
||||||
static const double one_um_tolerance;
|
|
||||||
|
|
||||||
//! \~english Default position tolerance (default 1mm)
|
|
||||||
//! \~russian Допуск позиции по умолчанию (по умолчанию 1мм)
|
|
||||||
static double position_tolerance;
|
|
||||||
|
|
||||||
//! \~english Set position tolerance
|
|
||||||
//! \~russian Установить допуск позиции
|
|
||||||
//! \param tol New tolerance value
|
|
||||||
//! \return Previous tolerance value
|
|
||||||
static double setPositionTolerance(const double tol) {
|
static double setPositionTolerance(const double tol) {
|
||||||
position_tolerance = tol;
|
position_tolerance = tol;
|
||||||
return position_tolerance;
|
return position_tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Get position tolerance
|
|
||||||
//! \~russian Получить допуск позиции
|
|
||||||
static double getPositionTolerance() { return position_tolerance; }
|
static double getPositionTolerance() { return position_tolerance; }
|
||||||
|
|
||||||
//! \~english Default constructor
|
|
||||||
//! \~russian Конструктор по умолчанию
|
|
||||||
PIGeoPosition();
|
PIGeoPosition();
|
||||||
|
|
||||||
//! \~english Constructor with coordinates
|
|
||||||
//! \~russian Конструктор с координатами
|
|
||||||
//! \param a First coordinate
|
|
||||||
//! \param b Second coordinate
|
|
||||||
//! \param c Third coordinate
|
|
||||||
//! \param s Coordinate system
|
|
||||||
//! \param ell Ellipsoid model
|
|
||||||
PIGeoPosition(double a, double b, double c, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
PIGeoPosition(double a, double b, double c, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
//! \~english Constructor from vector
|
|
||||||
//! \~russian Конструктор из вектора
|
|
||||||
//! \param v Vector with coordinates
|
|
||||||
//! \param s Coordinate system
|
|
||||||
//! \param ell Ellipsoid model
|
|
||||||
PIGeoPosition(PIMathVectorT3d v, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
PIGeoPosition(PIMathVectorT3d v, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
|
|
||||||
//! \~english Transform to specified coordinate system
|
|
||||||
//! \~russian Преобразовать в указанную систему координат
|
|
||||||
//! \param sys Target coordinate system
|
|
||||||
//! \return Reference to this position
|
|
||||||
PIGeoPosition & transformTo(CoordinateSystem sys);
|
PIGeoPosition & transformTo(CoordinateSystem sys);
|
||||||
|
|
||||||
//! \~english Convert to geodetic coordinates
|
|
||||||
//! \~russian Преобразовать в геодезические координаты
|
|
||||||
PIGeoPosition & asGeodetic() {
|
PIGeoPosition & asGeodetic() {
|
||||||
transformTo(Geodetic);
|
transformTo(Geodetic);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
} /// Convert to geodetic coordinate
|
||||||
|
|
||||||
//! \~english Convert to geodetic coordinates using specified ellipsoid
|
|
||||||
//! \~russian Преобразовать в геодезические координаты с указанным эллипсоидом
|
|
||||||
//! \param ell Ellipsoid model to use
|
|
||||||
//! \return Reference to this position
|
|
||||||
PIGeoPosition & asGeodetic(const PIEllipsoidModel & ell) {
|
PIGeoPosition & asGeodetic(const PIEllipsoidModel & ell) {
|
||||||
setEllipsoidModel(ell);
|
setEllipsoidModel(ell);
|
||||||
transformTo(Geodetic);
|
transformTo(Geodetic);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
} /// Convert to another ell, then to geodetic coordinates
|
||||||
|
|
||||||
//! \~english Convert to ECEF (cartesian) coordinates
|
|
||||||
//! \~russian Преобразовать в координаты ECEF (декартовы)
|
|
||||||
PIGeoPosition & asECEF() {
|
PIGeoPosition & asECEF() {
|
||||||
transformTo(Cartesian);
|
transformTo(Cartesian);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
} /// Convert to cartesian coordinates
|
||||||
|
|
||||||
//! \~english Get X coordinate (or first coordinate in Cartesian)
|
|
||||||
//! \~russian Получить координату X (или первую координату в Декартовой)
|
|
||||||
double x() const;
|
double x() const;
|
||||||
|
|
||||||
//! \~english Get Y coordinate (or second coordinate in Cartesian)
|
|
||||||
//! \~russian Получить координату Y (или вторую координату в Декартовой)
|
|
||||||
double y() const;
|
double y() const;
|
||||||
|
|
||||||
//! \~english Get Z coordinate (or third coordinate in Cartesian)
|
|
||||||
//! \~russian Получить координату Z (или третью координату в Декартовой)
|
|
||||||
double z() const;
|
double z() const;
|
||||||
|
|
||||||
//! \~english Get geodetic latitude in degrees
|
|
||||||
//! \~russian Получить геодезическую широту в градусах
|
|
||||||
double latitudeGeodetic() const;
|
double latitudeGeodetic() const;
|
||||||
|
|
||||||
//! \~english Get geocentric latitude in degrees
|
|
||||||
//! \~russian Получить геоцентрическую широту в градусах
|
|
||||||
double latitudeGeocentric() const;
|
double latitudeGeocentric() const;
|
||||||
|
|
||||||
//! \~english Get longitude in degrees
|
|
||||||
//! \~russian Получить долготу в градусах
|
|
||||||
double longitude() const;
|
double longitude() const;
|
||||||
|
|
||||||
//! \~english Get theta (angle from Z axis) in degrees
|
|
||||||
//! \~russian Получить тета (угол от оси Z) в градусах
|
|
||||||
double theta() const;
|
double theta() const;
|
||||||
|
|
||||||
//! \~english Get phi (angle in XY plane from X axis) in degrees
|
|
||||||
//! \~russian Получить фи (угол в плоскости XY от оси X) в градусах
|
|
||||||
double phi() const;
|
double phi() const;
|
||||||
|
|
||||||
//! \~english Get radius (distance from Earth center)
|
|
||||||
//! \~russian Получить радиус (расстояние от центра Земли)
|
|
||||||
double radius() const;
|
double radius() const;
|
||||||
|
|
||||||
//! \~english Get height above ellipsoid
|
|
||||||
//! \~russian Получить высоту над эллипсоидом
|
|
||||||
double height() const;
|
double height() const;
|
||||||
|
|
||||||
//! \~english Set ellipsoid model for this position
|
/// Set the ellipsoid values for this PIGeoPosition given a ellipsoid.
|
||||||
//! \~russian Установить модель эллипсоида для этой позиции
|
|
||||||
//! \param ell Ellipsoid model
|
|
||||||
void setEllipsoidModel(const PIEllipsoidModel & ell) { el = ell; }
|
void setEllipsoidModel(const PIEllipsoidModel & ell) { el = ell; }
|
||||||
|
|
||||||
//! \~english Set position from geodetic coordinates
|
/// Set the \a PIGeoPosition given geodetic coordinates in degrees. \a CoordinateSystem is set to \a Geodetic.
|
||||||
//! \~russian Установить позицию из геодезических координат
|
|
||||||
//! \param lat Latitude in degrees
|
|
||||||
//! \param lon Longitude in degrees
|
|
||||||
//! \param ht Height above ellipsoid
|
|
||||||
//! \param ell Ellipsoid model (default WGS84)
|
|
||||||
//! \return Reference to this position
|
|
||||||
PIGeoPosition & setGeodetic(double lat, double lon, double ht, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
PIGeoPosition & setGeodetic(double lat, double lon, double ht, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
//! \~english Set position from geocentric coordinates
|
/// Set the \a PIGeoPosition given geocentric coordinates in degrees. \a CoordinateSystem is set to \a Geocentric
|
||||||
//! \~russian Установить позицию из геоцентрических координат
|
|
||||||
//! \param lat Latitude in degrees
|
|
||||||
//! \param lon Longitude in degrees
|
|
||||||
//! \param rad Radius
|
|
||||||
//! \return Reference to this position
|
|
||||||
PIGeoPosition & setGeocentric(double lat, double lon, double rad);
|
PIGeoPosition & setGeocentric(double lat, double lon, double rad);
|
||||||
|
|
||||||
//! \~english Set position from spherical coordinates
|
/// Set the \a PIGeoPosition given spherical coordinates in degrees. \a CoordinateSystem is set to \a Spherical
|
||||||
//! \~russian Установить позицию из сферических координат
|
|
||||||
//! \param theta Angle from Z axis in degrees
|
|
||||||
//! \param phi Angle in XY plane from X axis in degrees
|
|
||||||
//! \param rad Radius
|
|
||||||
//! \return Reference to this position
|
|
||||||
PIGeoPosition & setSpherical(double theta, double phi, double rad);
|
PIGeoPosition & setSpherical(double theta, double phi, double rad);
|
||||||
|
|
||||||
//! \~english Set position from ECEF coordinates
|
/// Set the \a PIGeoPosition given ECEF coordinates in meeters. \a CoordinateSystem is set to \a Cartesian.
|
||||||
//! \~russian Установить позицию из координат ECEF
|
|
||||||
//! \param x X coordinate in meters
|
|
||||||
//! \param y Y coordinate in meters
|
|
||||||
//! \param z Z coordinate in meters
|
|
||||||
//! \return Reference to this position
|
|
||||||
PIGeoPosition & setECEF(double x, double y, double z);
|
PIGeoPosition & setECEF(double x, double y, double z);
|
||||||
|
|
||||||
//! \~english Convert spherical to Cartesian coordinates
|
/// Fundamental conversion from spherical to cartesian coordinates.
|
||||||
//! \~russian Преобразовать сферические в декартовы координаты
|
|
||||||
//! \param tpr Input spherical (theta, phi, radius)
|
|
||||||
//! \param xyz Output Cartesian (x, y, z)
|
|
||||||
static void convertSphericalToCartesian(const PIMathVectorT3d & tpr, PIMathVectorT3d & xyz);
|
static void convertSphericalToCartesian(const PIMathVectorT3d & tpr, PIMathVectorT3d & xyz);
|
||||||
|
|
||||||
//! \~english Convert Cartesian to spherical coordinates
|
/// Fundamental routine to convert cartesian to spherical coordinates.
|
||||||
//! \~russian Преобразовать декартовы в сферические координаты
|
|
||||||
//! \param xyz Input Cartesian (x, y, z)
|
|
||||||
//! \param tpr Output spherical (theta, phi, radius)
|
|
||||||
static void convertCartesianToSpherical(const PIMathVectorT3d & xyz, PIMathVectorT3d & tpr);
|
static void convertCartesianToSpherical(const PIMathVectorT3d & xyz, PIMathVectorT3d & tpr);
|
||||||
|
|
||||||
//! \~english Convert Cartesian (ECEF) to geodetic coordinates
|
/// Fundamental routine to convert ECEF (cartesian) to geodetic coordinates,
|
||||||
//! \~russian Преобразовать декартовы (ECEF) в геодезические координаты
|
|
||||||
//! \param xyz Input Cartesian (x, y, z)
|
|
||||||
//! \param llh Output geodetic (latitude, longitude, height)
|
|
||||||
//! \param ell Ellipsoid model (default WGS84)
|
|
||||||
static void convertCartesianToGeodetic(const PIMathVectorT3d & xyz,
|
static void convertCartesianToGeodetic(const PIMathVectorT3d & xyz,
|
||||||
PIMathVectorT3d & llh,
|
PIMathVectorT3d & llh,
|
||||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
//! \~english Convert geodetic to Cartesian (ECEF) coordinates
|
/// Fundamental routine to convert geodetic to ECEF (cartesian) coordinates,
|
||||||
//! \~russian Преобразовать геодезические в декартовы (ECEF) координаты
|
|
||||||
//! \param llh Input geodetic (latitude, longitude, height)
|
|
||||||
//! \param xyz Output Cartesian (x, y, z)
|
|
||||||
//! \param ell Ellipsoid model (default WGS84)
|
|
||||||
static void convertGeodeticToCartesian(const PIMathVectorT3d & llh,
|
static void convertGeodeticToCartesian(const PIMathVectorT3d & llh,
|
||||||
PIMathVectorT3d & xyz,
|
PIMathVectorT3d & xyz,
|
||||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
//! \~english Convert Cartesian (ECEF) to geocentric coordinates
|
/// Fundamental routine to convert cartesian (ECEF) to geocentric
|
||||||
//! \~russian Преобразовать декартовы (ECEF) в геоцентрические координаты
|
|
||||||
//! \param xyz Input Cartesian (x, y, z)
|
|
||||||
//! \param llr Output geocentric (latitude, longitude, radius)
|
|
||||||
static void convertCartesianToGeocentric(const PIMathVectorT3d & xyz, PIMathVectorT3d & llr);
|
static void convertCartesianToGeocentric(const PIMathVectorT3d & xyz, PIMathVectorT3d & llr);
|
||||||
|
|
||||||
//! \~english Convert geocentric to Cartesian (ECEF)
|
/// Fundamental routine to convert geocentric to cartesian (ECEF)
|
||||||
//! \~russian Преобразовать геоцентрические в декартовы (ECEF)
|
|
||||||
//! \param llr Input geocentric (latitude, longitude, radius)
|
|
||||||
//! \param xyz Output Cartesian (x, y, z)
|
|
||||||
static void convertGeocentricToCartesian(const PIMathVectorT3d & llr, PIMathVectorT3d & xyz);
|
static void convertGeocentricToCartesian(const PIMathVectorT3d & llr, PIMathVectorT3d & xyz);
|
||||||
|
|
||||||
//! \~english Convert geocentric to geodetic
|
/// Fundamental routine to convert geocentric to geodetic
|
||||||
//! \~russian Преобразовать геоцентрические в геодезические
|
|
||||||
//! \param llr Input geocentric (latitude, longitude, radius)
|
|
||||||
//! \param llh Output geodetic (latitude, longitude, height)
|
|
||||||
//! \param ell Ellipsoid model (default WGS84)
|
|
||||||
static void convertGeocentricToGeodetic(const PIMathVectorT3d & llr,
|
static void convertGeocentricToGeodetic(const PIMathVectorT3d & llr,
|
||||||
PIMathVectorT3d & llh,
|
PIMathVectorT3d & llh,
|
||||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
//! \~english Convert geodetic to geocentric
|
/// Fundamental routine to convert geodetic to geocentric
|
||||||
//! \~russian Преобразовать геодезические в геоцентрические
|
|
||||||
//! \param llh Input geodetic (latitude, longitude, height)
|
|
||||||
//! \param llr Output geocentric (latitude, longitude, radius)
|
|
||||||
//! \param ell Ellipsoid model (default WGS84)
|
|
||||||
static void convertGeodeticToGeocentric(const PIMathVectorT3d & llh,
|
static void convertGeodeticToGeocentric(const PIMathVectorT3d & llh,
|
||||||
PIMathVectorT3d & llr,
|
PIMathVectorT3d & llr,
|
||||||
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
//! \~english Compute radius of ellipsoid at given latitude
|
/// Compute the radius of the ellipsoidal Earth, given the geodetic latitude.
|
||||||
//! \~russian Вычислить радиус эллипсоида на заданной широте
|
|
||||||
//! \param geolat Geodetic latitude in degrees
|
|
||||||
//! \param ell Ellipsoid model (default WGS84)
|
|
||||||
//! \return Radius in meters
|
|
||||||
static double radiusEarth(double geolat, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
static double radiusEarth(double geolat, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
|
|
||||||
//! \~english Compute radius of ellipsoid at current position
|
|
||||||
//! \~russian Вычислить радиус эллипсоида в текущей позиции
|
|
||||||
double radiusEarth() const {
|
double radiusEarth() const {
|
||||||
PIGeoPosition p(*this);
|
PIGeoPosition p(*this);
|
||||||
p.transformTo(PIGeoPosition::Geodetic);
|
p.transformTo(PIGeoPosition::Geodetic);
|
||||||
return PIGeoPosition::radiusEarth((*this)[0], p.el);
|
return PIGeoPosition::radiusEarth((*this)[0], p.el);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Compute range between two positions
|
/// Compute the range in meters between two PIGeoPositions.
|
||||||
//! \~russian Вычислить расстояние между двумя позициями
|
|
||||||
//! \param a First position
|
|
||||||
//! \param b Second position
|
|
||||||
//! \return Range in meters
|
|
||||||
static double range(const PIGeoPosition & a, const PIGeoPosition & b);
|
static double range(const PIGeoPosition & a, const PIGeoPosition & b);
|
||||||
|
|
||||||
//! \~english Compute range from this position to another
|
|
||||||
//! \~russian Вычислить расстояние от этой позиции до другой
|
|
||||||
//! \param p Target position
|
|
||||||
//! \return Range in meters
|
|
||||||
double range(const PIGeoPosition & p) const { return range((*this), p); }
|
double range(const PIGeoPosition & p) const { return range((*this), p); }
|
||||||
|
|
||||||
//! \~english Compute elevation angle to target position
|
/// Computes the elevation of the input (p) position as seen from this PIGeoPosition.
|
||||||
//! \~russian Вычислить угол возвышения до целевой позиции
|
|
||||||
//! \param p Target position
|
|
||||||
//! \return Elevation angle in degrees
|
|
||||||
double elevation(const PIGeoPosition & p) const;
|
double elevation(const PIGeoPosition & p) const;
|
||||||
|
|
||||||
//! \~english Compute geodetic elevation angle to target position
|
/// Computes the elevation of the input (p) position as seen from this PIGeoPosition, using a Geodetic (ellipsoidal) system.
|
||||||
//! \~russian Вычислить геодезический угол возвышения до целевой позиции
|
|
||||||
//! \param p Target position
|
|
||||||
//! \return Elevation angle in degrees
|
|
||||||
double elevationGeodetic(const PIGeoPosition & p) const;
|
double elevationGeodetic(const PIGeoPosition & p) const;
|
||||||
|
|
||||||
//! \~english Compute azimuth angle to target position
|
/// Computes the azimuth of the input (p) position as seen from this PIGeoPosition.
|
||||||
//! \~russian Вычислить азимут до целевой позиции
|
|
||||||
//! \param p Target position
|
|
||||||
//! \return Azimuth angle in degrees
|
|
||||||
double azimuth(const PIGeoPosition & p) const;
|
double azimuth(const PIGeoPosition & p) const;
|
||||||
|
|
||||||
//! \~english Compute geodetic azimuth angle to target position
|
/// Computes the azimuth of the input (p) position as seen from this PIGeoPosition, using a Geodetic (ellipsoidal) system.
|
||||||
//! \~russian Вычислить геодезический азимут до целевой позиции
|
|
||||||
//! \param p Target position
|
|
||||||
//! \return Azimuth angle in degrees
|
|
||||||
double azimuthGeodetic(const PIGeoPosition & p) const;
|
double azimuthGeodetic(const PIGeoPosition & p) const;
|
||||||
|
|
||||||
//! \~english Get radius of curvature of the meridian
|
/// Computes the radius of curvature of the meridian (Rm) corresponding to this PIGeoPosition.
|
||||||
//! \~russian Получить радиус кривизны меридиана
|
|
||||||
//! \return Radius in meters
|
|
||||||
double getCurvMeridian() const;
|
double getCurvMeridian() const;
|
||||||
|
|
||||||
//! \~english Get radius of curvature in the prime vertical
|
/// Computes the radius of curvature in the prime vertical (Rn) corresponding to this PIGeoPosition.
|
||||||
//! \~russian Получить радиус кривизны в вертикале
|
|
||||||
//! \return Radius in meters
|
|
||||||
double getCurvPrimeVertical() const;
|
double getCurvPrimeVertical() const;
|
||||||
|
|
||||||
//! \~english Get as PIMathVectorT3d
|
/// Returns as PIMathVectorT3d
|
||||||
//! \~russian Получить как PIMathVectorT3d
|
|
||||||
//! \return Reference to underlying vector
|
|
||||||
const PIMathVectorT3d & vector() const { return *this; }
|
const PIMathVectorT3d & vector() const { return *this; }
|
||||||
|
|
||||||
//! \~english Assignment from vector
|
|
||||||
//! \~russian Присваивание из вектора
|
|
||||||
PIGeoPosition & operator=(const PIMathVectorT3d & v);
|
PIGeoPosition & operator=(const PIMathVectorT3d & v);
|
||||||
|
|
||||||
//! \~english Subtraction
|
|
||||||
//! \~russian Вычитание
|
|
||||||
PIGeoPosition & operator-=(const PIGeoPosition & right);
|
PIGeoPosition & operator-=(const PIGeoPosition & right);
|
||||||
|
|
||||||
//! \~english Addition
|
|
||||||
//! \~russian Сложение
|
|
||||||
PIGeoPosition & operator+=(const PIGeoPosition & right);
|
PIGeoPosition & operator+=(const PIGeoPosition & right);
|
||||||
|
|
||||||
//! \~english Subtraction
|
|
||||||
//! \~russian Вычитание
|
|
||||||
friend PIGeoPosition operator-(const PIGeoPosition & left, const PIGeoPosition & right);
|
friend PIGeoPosition operator-(const PIGeoPosition & left, const PIGeoPosition & right);
|
||||||
|
|
||||||
//! \~english Addition
|
|
||||||
//! \~russian Сложение
|
|
||||||
friend PIGeoPosition operator+(const PIGeoPosition & left, const PIGeoPosition & right);
|
friend PIGeoPosition operator+(const PIGeoPosition & left, const PIGeoPosition & right);
|
||||||
|
|
||||||
//! \~english Scalar multiplication
|
|
||||||
//! \~russian Умножение на скаляр
|
|
||||||
friend PIGeoPosition operator*(const double & scale, const PIGeoPosition & right);
|
friend PIGeoPosition operator*(const double & scale, const PIGeoPosition & right);
|
||||||
friend PIGeoPosition operator*(const PIGeoPosition & left, const double & scale);
|
friend PIGeoPosition operator*(const PIGeoPosition & left, const double & scale);
|
||||||
friend PIGeoPosition operator*(const int & scale, const PIGeoPosition & right);
|
friend PIGeoPosition operator*(const int & scale, const PIGeoPosition & right);
|
||||||
friend PIGeoPosition operator*(const PIGeoPosition & left, const int & scale);
|
friend PIGeoPosition operator*(const PIGeoPosition & left, const int & scale);
|
||||||
|
|
||||||
//! \~english Equality comparison
|
|
||||||
//! \~russian Сравнение на равенство
|
|
||||||
bool operator==(const PIGeoPosition & right) const;
|
bool operator==(const PIGeoPosition & right) const;
|
||||||
|
|
||||||
//! \~english Inequality comparison
|
|
||||||
//! \~russian Сравнение на неравенство
|
|
||||||
bool operator!=(const PIGeoPosition & right) const { return !(operator==(right)); }
|
bool operator!=(const PIGeoPosition & right) const { return !(operator==(right)); }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,36 +29,16 @@
|
|||||||
#include "piiodevice.h"
|
#include "piiodevice.h"
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup IO
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english CAN device.
|
|
||||||
//! \~russian Устройство CAN.
|
|
||||||
class PIP_EXPORT PICAN: public PIIODevice {
|
class PIP_EXPORT PICAN: public PIIODevice {
|
||||||
PIIODEVICE(PICAN, "can");
|
PIIODEVICE(PICAN, "can");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs %PICAN with empty path and ReadWrite mode
|
|
||||||
//! \~russian Создаёт %PICAN с пустым путём и режимом ReadWrite
|
|
||||||
explicit PICAN(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
explicit PICAN(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PICAN();
|
virtual ~PICAN();
|
||||||
|
|
||||||
//! \~english Set CAN ID for filtering received messages
|
|
||||||
//! \~russian Устанавливает CAN ID для фильтрации принимаемых сообщений
|
|
||||||
void setCANID(int id);
|
void setCANID(int id);
|
||||||
|
|
||||||
//! \~english Returns current CAN ID
|
|
||||||
//! \~russian Возвращает текущий CAN ID
|
|
||||||
int CANID() const;
|
int CANID() const;
|
||||||
|
|
||||||
//! \~english Returns CAN ID of last readed message
|
|
||||||
//! \~russian Возвращает CAN ID последнего прочитанного сообщения
|
|
||||||
int readedCANID() const;
|
int readedCANID() const;
|
||||||
|
|
||||||
//! \~english Interrupt blocking operation
|
|
||||||
//! \~russian Прерывает блокирующую операцию
|
|
||||||
void interrupt() override;
|
void interrupt() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -29,10 +29,6 @@
|
|||||||
#include "pidiagnostics.h"
|
#include "pidiagnostics.h"
|
||||||
#include "piethernet.h"
|
#include "piethernet.h"
|
||||||
|
|
||||||
//! \ingroup IO
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Peering net node.
|
|
||||||
//! \~russian Элемент пиринговой сети.
|
|
||||||
class PIP_EXPORT PIPeer: public PIIODevice {
|
class PIP_EXPORT PIPeer: public PIIODevice {
|
||||||
PIIODEVICE(PIPeer, "peer");
|
PIIODEVICE(PIPeer, "peer");
|
||||||
|
|
||||||
@@ -40,16 +36,9 @@ private:
|
|||||||
class PeerData;
|
class PeerData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs %PIPeer with name "name"
|
|
||||||
//! \~russian Создаёт %PIPeer с именем "name"
|
|
||||||
explicit PIPeer(const PIString & name = PIString());
|
explicit PIPeer(const PIString & name = PIString());
|
||||||
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PIPeer();
|
virtual ~PIPeer();
|
||||||
|
|
||||||
//! \~english Peer information structure
|
|
||||||
//! \~russian Структура информации о пире
|
|
||||||
class PIP_EXPORT PeerInfo {
|
class PIP_EXPORT PeerInfo {
|
||||||
friend class PIPeer;
|
friend class PIPeer;
|
||||||
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
||||||
@@ -98,89 +87,38 @@ public:
|
|||||||
|
|
||||||
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
BINARY_STREAM_FRIEND(PIPeer::PeerInfo);
|
||||||
|
|
||||||
//! \~english Send data to peer with name "to"
|
|
||||||
//! \~russian Отправляет данные пиру с именем "to"
|
|
||||||
bool send(const PIString & to, const PIByteArray & data) { return send(to, data.data(), data.size_s()); }
|
bool send(const PIString & to, const PIByteArray & data) { return send(to, data.data(), data.size_s()); }
|
||||||
|
|
||||||
//! \~english Send string to peer with name "to"
|
|
||||||
//! \~russian Отправляет строку пиру с именем "to"
|
|
||||||
bool send(const PIString & to, const PIString & data) { return send(to, data.data(), data.size_s()); }
|
bool send(const PIString & to, const PIString & data) { return send(to, data.data(), data.size_s()); }
|
||||||
bool send(const PIString & to, const void * data, int size);
|
bool send(const PIString & to, const void * data, int size);
|
||||||
|
|
||||||
//! \~english Send data to peer "to"
|
|
||||||
//! \~russian Отправляет данные пиру "to"
|
|
||||||
bool send(const PeerInfo & to, const PIByteArray & data) { return send(to.name, data.data(), data.size_s()); }
|
bool send(const PeerInfo & to, const PIByteArray & data) { return send(to.name, data.data(), data.size_s()); }
|
||||||
bool send(const PeerInfo & to, const PIString & data) { return send(to.name, data.data(), data.size_s()); }
|
bool send(const PeerInfo & to, const PIString & data) { return send(to.name, data.data(), data.size_s()); }
|
||||||
bool send(const PeerInfo & to, const void * data, int size) { return send(to.name, data, size); }
|
bool send(const PeerInfo & to, const void * data, int size) { return send(to.name, data, size); }
|
||||||
bool send(const PeerInfo * to, const PIByteArray & data);
|
bool send(const PeerInfo * to, const PIByteArray & data);
|
||||||
bool send(const PeerInfo * to, const PIString & data);
|
bool send(const PeerInfo * to, const PIString & data);
|
||||||
bool send(const PeerInfo * to, const void * data, int size);
|
bool send(const PeerInfo * to, const void * data, int size);
|
||||||
|
|
||||||
//! \~english Send data to all peers
|
|
||||||
//! \~russian Отправляет данные всем пирам
|
|
||||||
void sendToAll(const PIByteArray & data);
|
void sendToAll(const PIByteArray & data);
|
||||||
void sendToAll(const PIString & data);
|
void sendToAll(const PIString & data);
|
||||||
void sendToAll(const void * data, int size);
|
void sendToAll(const void * data, int size);
|
||||||
|
|
||||||
//! \~english Returns if receiving multicast packets is enabled
|
|
||||||
//! \~russian Возвращает включён ли приём мультикаст пакетов
|
|
||||||
bool isMulticastReceive() const { return !eths_mcast.isEmpty(); }
|
bool isMulticastReceive() const { return !eths_mcast.isEmpty(); }
|
||||||
|
|
||||||
//! \~english Returns if receiving broadcast packets is enabled
|
|
||||||
//! \~russian Возвращает включён ли приём широковещательных пакетов
|
|
||||||
bool isBroadcastReceive() const { return !eths_bcast.isEmpty(); }
|
bool isBroadcastReceive() const { return !eths_bcast.isEmpty(); }
|
||||||
|
|
||||||
//! \~english Returns diagnostic service
|
|
||||||
//! \~russian Возвращает диагностический сервис
|
|
||||||
PIDiagnostics & diagnosticService() { return diag_s; }
|
PIDiagnostics & diagnosticService() { return diag_s; }
|
||||||
|
|
||||||
//! \~english Returns diagnostic data
|
|
||||||
//! \~russian Возвращает диагностические данные
|
|
||||||
PIDiagnostics & diagnosticData() { return diag_d; }
|
PIDiagnostics & diagnosticData() { return diag_d; }
|
||||||
|
|
||||||
//! \~english Returns all known peers
|
|
||||||
//! \~russian Возвращает всех известных пиров
|
|
||||||
const PIVector<PIPeer::PeerInfo> & allPeers() const { return peers; }
|
const PIVector<PIPeer::PeerInfo> & allPeers() const { return peers; }
|
||||||
|
|
||||||
//! \~english Returns if peer with name "name" exists
|
|
||||||
//! \~russian Возвращает существует ли пир с именем "name"
|
|
||||||
bool isPeerExists(const PIString & name) const { return getPeerByName(name) != 0; }
|
bool isPeerExists(const PIString & name) const { return getPeerByName(name) != 0; }
|
||||||
|
|
||||||
//! \~english Returns peer info by name, or nullptr if not found
|
|
||||||
//! \~russian Возвращает информацию о пире по имени, или nullptr если не найден
|
|
||||||
const PeerInfo * getPeerByName(const PIString & name) const { return peers_map.value(name, 0); }
|
const PeerInfo * getPeerByName(const PIString & name) const { return peers_map.value(name, 0); }
|
||||||
|
|
||||||
//! \~english Returns self info
|
|
||||||
//! \~russian Возвращает информацию о себе
|
|
||||||
const PeerInfo & selfInfo() const { return self_info; }
|
const PeerInfo & selfInfo() const { return self_info; }
|
||||||
const PIMap<PIString, PIVector<PeerInfo *>> & _peerMap() const { return addresses_map; }
|
const PIMap<PIString, PIVector<PeerInfo *>> & _peerMap() const { return addresses_map; }
|
||||||
|
|
||||||
//! \~english Reinitialize peer network
|
|
||||||
//! \~russian Переинициализирует пиринговую сеть
|
|
||||||
void reinit();
|
void reinit();
|
||||||
|
|
||||||
//! \~english Lock peers list
|
|
||||||
//! \~russian Блокирует список пиров
|
|
||||||
void lock() { peers_mutex.lock(); }
|
void lock() { peers_mutex.lock(); }
|
||||||
|
|
||||||
//! \~english Unlock peers list
|
|
||||||
//! \~russian Разблокирует список пиров
|
|
||||||
void unlock() { peers_mutex.unlock(); }
|
void unlock() { peers_mutex.unlock(); }
|
||||||
|
|
||||||
//! \~english Change peer name to "new_name"
|
|
||||||
//! \~russian Изменяет имя пира на "new_name"
|
|
||||||
void changeName(const PIString & new_name);
|
void changeName(const PIString & new_name);
|
||||||
|
|
||||||
//! \~english Returns trusted peer name
|
|
||||||
//! \~russian Возвращает имя доверенного пира
|
|
||||||
const PIString & trustPeerName() const { return trust_peer; }
|
const PIString & trustPeerName() const { return trust_peer; }
|
||||||
|
|
||||||
//! \~english Set trusted peer name
|
|
||||||
//! \~russian Устанавливает имя доверенного пира
|
|
||||||
void setTrustPeerName(const PIString & peer_name) { trust_peer = peer_name; }
|
void setTrustPeerName(const PIString & peer_name) { trust_peer = peer_name; }
|
||||||
|
|
||||||
//! \~english Set TCP server IP address
|
|
||||||
//! \~russian Устанавливает IP адрес TCP сервера
|
|
||||||
void setTcpServerIP(const PIString & ip);
|
void setTcpServerIP(const PIString & ip);
|
||||||
|
|
||||||
ssize_t bytesAvailable() const override;
|
ssize_t bytesAvailable() const override;
|
||||||
|
|||||||
@@ -29,59 +29,35 @@
|
|||||||
#include "piiodevice.h"
|
#include "piiodevice.h"
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup IO
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english SPI device.
|
|
||||||
//! \~russian Устройство SPI.
|
|
||||||
class PIP_EXPORT PISPI: public PIIODevice {
|
class PIP_EXPORT PISPI: public PIIODevice {
|
||||||
PIIODEVICE(PISPI, "spi");
|
PIIODEVICE(PISPI, "spi");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs %PISPI with path "path", speed "speed_hz" and mode "mode"
|
|
||||||
//! \~russian Создаёт %PISPI с путём "path", скоростью "speed_hz" и режимом "mode"
|
|
||||||
explicit PISPI(const PIString & path = PIString(), uint speed_hz = 1000000, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
explicit PISPI(const PIString & path = PIString(), uint speed_hz = 1000000, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
|
||||||
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PISPI();
|
virtual ~PISPI();
|
||||||
|
|
||||||
//! \~english Parameters of PISPI
|
//! \brief Parameters of PISPI
|
||||||
//! \~russian Параметры PISPI
|
|
||||||
enum Parameters {
|
enum Parameters {
|
||||||
ClockInverse /*! \~english SPI clk polarity control \~russian Управление полярностью SPI clk */ = 0x1,
|
ClockInverse /*! SPI clk polarity control*/ = 0x1,
|
||||||
ClockPhaseShift /*! \~english SPI clk phase control \~russian Управление фазой SPI clk */ = 0x2,
|
ClockPhaseShift /*! SPI clk phase control */ = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Set SPI speed in Hz
|
|
||||||
//! \~russian Устанавливает скорость SPI в Гц
|
|
||||||
void setSpeed(uint speed_hz);
|
void setSpeed(uint speed_hz);
|
||||||
|
|
||||||
//! \~english Returns current SPI speed in Hz
|
|
||||||
//! \~russian Возвращает текущую скорость SPI в Гц
|
|
||||||
uint speed() const { return spi_speed; }
|
uint speed() const { return spi_speed; }
|
||||||
|
|
||||||
//! \~english Set number of bits per word, default is 8
|
|
||||||
//! \~russian Устанавливает количество бит на слово, по умолчанию 8
|
|
||||||
void setBits(uchar bits = 8);
|
void setBits(uchar bits = 8);
|
||||||
|
|
||||||
//! \~english Returns number of bits per word
|
|
||||||
//! \~russian Возвращает количество бит на слово
|
|
||||||
uchar bits() const { return spi_bits; }
|
uchar bits() const { return spi_bits; }
|
||||||
|
|
||||||
//! \~english Set parameters to "parameters_"
|
//! Set parameters to "parameters_"
|
||||||
//! \~russian Устанавливает параметры в "parameters_"
|
|
||||||
void setParameters(PIFlags<PISPI::Parameters> parameters_) { spi_mode = (int)parameters_; }
|
void setParameters(PIFlags<PISPI::Parameters> parameters_) { spi_mode = (int)parameters_; }
|
||||||
|
|
||||||
//! \~english Set parameter "parameter" to "on" state
|
//! Set parameter "parameter" to "on" state
|
||||||
//! \~russian Устанавливает параметр "parameter" в состояние "on"
|
|
||||||
void setParameter(PISPI::Parameters parameter, bool on = true);
|
void setParameter(PISPI::Parameters parameter, bool on = true);
|
||||||
|
|
||||||
//! \~english Returns if parameter "parameter" is set
|
//! Returns if parameter "parameter" is set
|
||||||
//! \~russian Возвращает установлен ли параметр "parameter"
|
|
||||||
bool isParameterSet(PISPI::Parameters parameter) const;
|
bool isParameterSet(PISPI::Parameters parameter) const;
|
||||||
|
|
||||||
//! \~english Returns parameters
|
//! Returns parameters
|
||||||
//! \~russian Возвращает параметры
|
|
||||||
PIFlags<PISPI::Parameters> parameters() const { return spi_mode; }
|
PIFlags<PISPI::Parameters> parameters() const { return spi_mode; }
|
||||||
|
|
||||||
ssize_t bytesAvailable() const override;
|
ssize_t bytesAvailable() const override;
|
||||||
|
|||||||
@@ -62,24 +62,13 @@
|
|||||||
|
|
||||||
struct usb_dev_handle;
|
struct usb_dev_handle;
|
||||||
|
|
||||||
//! \ingroup IO
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english USB device.
|
|
||||||
//! \~russian Устройство USB.
|
|
||||||
class PIP_USB_EXPORT PIUSB: public PIIODevice {
|
class PIP_USB_EXPORT PIUSB: public PIIODevice {
|
||||||
PIIODEVICE(PIUSB, "usb");
|
PIIODEVICE(PIUSB, "usb");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs %PIUSB with vendor ID "vid" and product ID "pid"
|
|
||||||
//! \~russian Создаёт %PIUSB с идентификатором поставщика "vid" и идентификатором продукта "pid"
|
|
||||||
explicit PIUSB(ushort vid = 0, ushort pid = 0);
|
explicit PIUSB(ushort vid = 0, ushort pid = 0);
|
||||||
|
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
virtual ~PIUSB();
|
virtual ~PIUSB();
|
||||||
|
|
||||||
//! \~english USB endpoint structure
|
|
||||||
//! \~russian Структура USB endpoint
|
|
||||||
struct PIP_USB_EXPORT Endpoint {
|
struct PIP_USB_EXPORT Endpoint {
|
||||||
Endpoint(uchar a = 0, uchar at = 0, ushort mps = 0) {
|
Endpoint(uchar a = 0, uchar at = 0, ushort mps = 0) {
|
||||||
address = a;
|
address = a;
|
||||||
@@ -122,8 +111,6 @@ public:
|
|||||||
UsageType usage_type = DataEndpoint;
|
UsageType usage_type = DataEndpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english USB interface structure
|
|
||||||
//! \~russian Структура USB интерфейса
|
|
||||||
struct PIP_USB_EXPORT Interface {
|
struct PIP_USB_EXPORT Interface {
|
||||||
uchar index = 0;
|
uchar index = 0;
|
||||||
uchar value_to_select = 0;
|
uchar value_to_select = 0;
|
||||||
@@ -133,8 +120,6 @@ public:
|
|||||||
PIVector<PIUSB::Endpoint> endpoints;
|
PIVector<PIUSB::Endpoint> endpoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english USB configuration structure
|
|
||||||
//! \~russian Структура USB конфигурации
|
|
||||||
struct PIP_USB_EXPORT Configuration {
|
struct PIP_USB_EXPORT Configuration {
|
||||||
uchar index = 0;
|
uchar index = 0;
|
||||||
uchar value_to_select = 0;
|
uchar value_to_select = 0;
|
||||||
@@ -145,8 +130,6 @@ public:
|
|||||||
PIVector<PIUSB::Interface> interfaces;
|
PIVector<PIUSB::Interface> interfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english USB device descriptor structure
|
|
||||||
//! \~russian Структура дескриптора USB устройства
|
|
||||||
struct PIP_USB_EXPORT Descriptor {
|
struct PIP_USB_EXPORT Descriptor {
|
||||||
ushort usb_spec_number = 0;
|
ushort usb_spec_number = 0;
|
||||||
uchar device_class = 0;
|
uchar device_class = 0;
|
||||||
@@ -162,100 +145,36 @@ public:
|
|||||||
PIVector<PIUSB::Configuration> configurations;
|
PIVector<PIUSB::Configuration> configurations;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Returns current device descriptor
|
|
||||||
//! \~russian Возвращает текущий дескриптор устройства
|
|
||||||
const PIUSB::Descriptor & currentDescriptor() const { return desc_; }
|
const PIUSB::Descriptor & currentDescriptor() const { return desc_; }
|
||||||
|
|
||||||
//! \~english Returns current configuration
|
|
||||||
//! \~russian Возвращает текущую конфигурацию
|
|
||||||
const PIUSB::Configuration & currentConfiguration() const { return conf_; }
|
const PIUSB::Configuration & currentConfiguration() const { return conf_; }
|
||||||
|
|
||||||
//! \~english Returns current interface
|
|
||||||
//! \~russian Возвращает текущий интерфейс
|
|
||||||
const PIUSB::Interface & currentInterface() const { return iface_; }
|
const PIUSB::Interface & currentInterface() const { return iface_; }
|
||||||
|
|
||||||
//! \~english Returns vendor ID
|
|
||||||
//! \~russian Возвращает ID поставщика
|
|
||||||
ushort vendorID() const { return vid_; }
|
ushort vendorID() const { return vid_; }
|
||||||
|
|
||||||
//! \~english Returns product ID
|
|
||||||
//! \~russian Возвращает ID продукта
|
|
||||||
ushort productID() const { return pid_; }
|
ushort productID() const { return pid_; }
|
||||||
|
|
||||||
//! \~english Returns device number
|
|
||||||
//! \~russian Возвращает номер устройства
|
|
||||||
int deviceNumber() const { return property("deviceNumber").toInt(); }
|
int deviceNumber() const { return property("deviceNumber").toInt(); }
|
||||||
|
|
||||||
//! \~english Returns read timeout in milliseconds
|
|
||||||
//! \~russian Возвращает таймаут чтения в миллисекундах
|
|
||||||
int timeoutRead() const { return property("timeoutRead").toInt(); }
|
int timeoutRead() const { return property("timeoutRead").toInt(); }
|
||||||
|
|
||||||
//! \~english Returns write timeout in milliseconds
|
|
||||||
//! \~russian Возвращает таймаут записи в миллисекундах
|
|
||||||
int timeoutWrite() const { return property("timeoutWrite").toInt(); }
|
int timeoutWrite() const { return property("timeoutWrite").toInt(); }
|
||||||
|
|
||||||
//! \~english Returns read endpoint
|
|
||||||
//! \~russian Возвращает endpoint для чтения
|
|
||||||
const PIUSB::Endpoint & endpointRead() const { return ep_read; }
|
const PIUSB::Endpoint & endpointRead() const { return ep_read; }
|
||||||
|
|
||||||
//! \~english Returns write endpoint
|
|
||||||
//! \~russian Возвращает endpoint для записи
|
|
||||||
const PIUSB::Endpoint & endpointWrite() const { return ep_write; }
|
const PIUSB::Endpoint & endpointWrite() const { return ep_write; }
|
||||||
|
|
||||||
//! \~english Returns all endpoints
|
|
||||||
//! \~russian Возвращает все endpoints
|
|
||||||
const PIVector<PIUSB::Endpoint> & endpoints() const { return eps; }
|
const PIVector<PIUSB::Endpoint> & endpoints() const { return eps; }
|
||||||
|
|
||||||
//! \~english Returns read endpoints
|
|
||||||
//! \~russian Возвращает endpoints для чтения
|
|
||||||
PIVector<PIUSB::Endpoint> endpointsRead();
|
PIVector<PIUSB::Endpoint> endpointsRead();
|
||||||
|
|
||||||
//! \~english Returns write endpoints
|
|
||||||
//! \~russian Возвращает endpoints для записи
|
|
||||||
PIVector<PIUSB::Endpoint> endpointsWrite();
|
PIVector<PIUSB::Endpoint> endpointsWrite();
|
||||||
|
|
||||||
//! \~english Returns endpoint by address
|
|
||||||
//! \~russian Возвращает endpoint по адресу
|
|
||||||
PIUSB::Endpoint getEndpointByAddress(uchar address);
|
PIUSB::Endpoint getEndpointByAddress(uchar address);
|
||||||
|
|
||||||
//! \~english Set vendor ID to "vid"
|
|
||||||
//! \~russian Устанавливает ID поставщика в "vid"
|
|
||||||
void setVendorID(ushort vid);
|
void setVendorID(ushort vid);
|
||||||
|
|
||||||
//! \~english Set product ID to "pid"
|
|
||||||
//! \~russian Устанавливает ID продукта в "pid"
|
|
||||||
void setProductID(ushort pid);
|
void setProductID(ushort pid);
|
||||||
|
|
||||||
//! \~english Set configuration by value
|
|
||||||
//! \~russian Устанавливает конфигурацию по значению
|
|
||||||
bool setConfiguration(uchar value);
|
bool setConfiguration(uchar value);
|
||||||
|
|
||||||
//! \~english Set interface by value
|
|
||||||
//! \~russian Устанавливает интерфейс по значению
|
|
||||||
bool setInterface(uchar value);
|
bool setInterface(uchar value);
|
||||||
|
|
||||||
//! \~english Set read endpoint
|
|
||||||
//! \~russian Устанавливает endpoint для чтения
|
|
||||||
void setEndpointRead(const PIUSB::Endpoint & ep) { ep_read = ep; }
|
void setEndpointRead(const PIUSB::Endpoint & ep) { ep_read = ep; }
|
||||||
|
|
||||||
//! \~english Set write endpoint
|
|
||||||
//! \~russian Устанавливает endpoint для записи
|
|
||||||
void setEndpointWrite(const PIUSB::Endpoint & ep) { ep_write = ep; }
|
void setEndpointWrite(const PIUSB::Endpoint & ep) { ep_write = ep; }
|
||||||
|
|
||||||
//! \~english Set device number
|
|
||||||
//! \~russian Устанавливает номер устройства
|
|
||||||
void setDeviceNumber(int dn) { setProperty("deviceNumber", dn); }
|
void setDeviceNumber(int dn) { setProperty("deviceNumber", dn); }
|
||||||
|
|
||||||
//! \~english Set read timeout in milliseconds
|
|
||||||
//! \~russian Устанавливает таймаут чтения в миллисекундах
|
|
||||||
void setTimeoutRead(int t) { setProperty("timeoutRead", t); }
|
void setTimeoutRead(int t) { setProperty("timeoutRead", t); }
|
||||||
|
|
||||||
//! \~english Set write timeout in milliseconds
|
|
||||||
//! \~russian Устанавливает таймаут записи в миллисекундах
|
|
||||||
void setTimeoutWrite(int t) { setProperty("timeoutWrite", t); }
|
void setTimeoutWrite(int t) { setProperty("timeoutWrite", t); }
|
||||||
|
|
||||||
//! \~english Control write to device
|
|
||||||
//! \~russian Управляющая запись в устройство
|
|
||||||
int controlWrite(const void * data, int max_size);
|
int controlWrite(const void * data, int max_size);
|
||||||
|
|
||||||
virtual void flush() override;
|
virtual void flush() override;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
//! \file picrc.h
|
/*! \file picrc.h
|
||||||
//! \ingroup Math
|
* \ingroup Math
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english CRC checksum calculation
|
* \~english CRC checksum calculation
|
||||||
//! \~russian Вычисление CRC контрольной суммы
|
* \~russian Вычисление CRC контрольной суммы
|
||||||
|
*/
|
||||||
/*!
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
CRC checksum calculator
|
CRC checksum calculator
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
@@ -28,113 +28,67 @@
|
|||||||
|
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
//! \addtogroup Math
|
|
||||||
//! \{
|
|
||||||
//! \class uint_cl
|
|
||||||
//! \brief
|
|
||||||
//! \~english Fixed-size unsigned integer class for CRC calculations
|
|
||||||
//! \~russian Класс целого числа фиксированного размера для вычисления CRC
|
|
||||||
//! \details
|
|
||||||
//! \~english Provides arbitrary length unsigned integer support for CRC computation
|
|
||||||
//! \~russian Обеспечивает поддержку целых чисел произвольной длины для вычисления CRC
|
|
||||||
//! \}
|
|
||||||
|
|
||||||
template<int L>
|
template<int L>
|
||||||
class PIP_EXPORT uint_cl {
|
class PIP_EXPORT uint_cl {
|
||||||
public:
|
public:
|
||||||
//! \~english Default constructor, initializes to zero
|
|
||||||
//! \~russian Конструктор по умолчанию, инициализирует нулём
|
|
||||||
uint_cl() {
|
uint_cl() {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Copy constructor
|
|
||||||
//! \~russian Конструктор копирования
|
|
||||||
uint_cl(const uint_cl<L> & v) {
|
uint_cl(const uint_cl<L> & v) {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
data_[i] = v.data_[i];
|
data_[i] = v.data_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from unsigned char
|
|
||||||
//! \~russian Конструктор из unsigned char
|
|
||||||
uint_cl(uchar v) {
|
uint_cl(uchar v) {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
data_[i] = (i == 0 ? v : 0);
|
data_[i] = (i == 0 ? v : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from char
|
|
||||||
//! \~russian Конструктор из char
|
|
||||||
uint_cl(char v) {
|
uint_cl(char v) {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
data_[i] = (i == 0 ? v : 0);
|
data_[i] = (i == 0 ? v : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from unsigned short
|
|
||||||
//! \~russian Конструктор из unsigned short
|
|
||||||
uint_cl(ushort v) {
|
uint_cl(ushort v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
for (int i = l; i < L / 8; ++i)
|
for (int i = l; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from short
|
|
||||||
//! \~russian Конструктор из short
|
|
||||||
uint_cl(short v) {
|
uint_cl(short v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
for (int i = l; i < L / 8; ++i)
|
for (int i = l; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from unsigned int
|
|
||||||
//! \~russian Конструктор из unsigned int
|
|
||||||
uint_cl(uint v) {
|
uint_cl(uint v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
for (int i = l; i < L / 8; ++i)
|
for (int i = l; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from int
|
|
||||||
//! \~russian Конструктор из int
|
|
||||||
uint_cl(int v) {
|
uint_cl(int v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
for (int i = l; i < L / 8; ++i)
|
for (int i = l; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from unsigned long
|
|
||||||
//! \~russian Конструктор из unsigned long
|
|
||||||
uint_cl(ulong v) {
|
uint_cl(ulong v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
for (int i = l; i < L / 8; ++i)
|
for (int i = l; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from long
|
|
||||||
//! \~russian Конструктор из long
|
|
||||||
uint_cl(long v) {
|
uint_cl(long v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
for (int i = l; i < L / 8; ++i)
|
for (int i = l; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from unsigned long long
|
|
||||||
//! \~russian Конструктор из unsigned long long
|
|
||||||
uint_cl(ullong v) {
|
uint_cl(ullong v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
for (int i = l; i < L / 8; ++i)
|
for (int i = l; i < L / 8; ++i)
|
||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Construct from long long
|
|
||||||
//! \~russian Конструктор из long long
|
|
||||||
uint_cl(llong v) {
|
uint_cl(llong v) {
|
||||||
int l = piMin<uint>(L / 8, sizeof(v));
|
int l = piMin<uint>(L / 8, sizeof(v));
|
||||||
memcpy(data_, &v, l);
|
memcpy(data_, &v, l);
|
||||||
@@ -142,87 +96,55 @@ public:
|
|||||||
data_[i] = 0;
|
data_[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to bool
|
|
||||||
//! \~russian Преобразование в bool
|
|
||||||
operator bool() {
|
operator bool() {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
if (data_[i] > 0) return true;
|
if (data_[i] > 0) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to char
|
|
||||||
//! \~russian Преобразование в char
|
|
||||||
operator char() { return (char)data_[0]; }
|
operator char() { return (char)data_[0]; }
|
||||||
|
|
||||||
//! \~english Convert to short
|
|
||||||
//! \~russian Преобразование в short
|
|
||||||
operator short() {
|
operator short() {
|
||||||
short t(0);
|
short t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
memcpy(&t, data_, l);
|
memcpy(&t, data_, l);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to int
|
|
||||||
//! \~russian Преобразование в int
|
|
||||||
operator int() {
|
operator int() {
|
||||||
int t(0);
|
int t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
memcpy(&t, data_, l);
|
memcpy(&t, data_, l);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to long
|
|
||||||
//! \~russian Преобразование в long
|
|
||||||
operator long() {
|
operator long() {
|
||||||
long t(0);
|
long t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
memcpy(&t, data_, l);
|
memcpy(&t, data_, l);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to long long
|
|
||||||
//! \~russian Преобразование в long long
|
|
||||||
operator llong() {
|
operator llong() {
|
||||||
llong t(0);
|
llong t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
memcpy(&t, data_, l);
|
memcpy(&t, data_, l);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to unsigned char
|
|
||||||
//! \~russian Преобразование в unsigned char
|
|
||||||
operator uchar() { return data_[0]; }
|
operator uchar() { return data_[0]; }
|
||||||
|
|
||||||
//! \~english Convert to unsigned short
|
|
||||||
//! \~russian Преобразование в unsigned short
|
|
||||||
operator ushort() {
|
operator ushort() {
|
||||||
ushort t(0);
|
ushort t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
memcpy(&t, data_, l);
|
memcpy(&t, data_, l);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to unsigned int
|
|
||||||
//! \~russian Преобразование в unsigned int
|
|
||||||
operator uint() {
|
operator uint() {
|
||||||
uint t(0);
|
uint t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
memcpy(&t, data_, l);
|
memcpy(&t, data_, l);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to unsigned long
|
|
||||||
//! \~russian Преобразование в unsigned long
|
|
||||||
operator ulong() {
|
operator ulong() {
|
||||||
ulong t(0);
|
ulong t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
memcpy(&t, data_, l);
|
memcpy(&t, data_, l);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Convert to unsigned long long
|
|
||||||
//! \~russian Преобразование в unsigned long long
|
|
||||||
operator ullong() {
|
operator ullong() {
|
||||||
ullong t(0);
|
ullong t(0);
|
||||||
int l = piMin<uint>(L / 8, sizeof(t));
|
int l = piMin<uint>(L / 8, sizeof(t));
|
||||||
@@ -230,8 +152,6 @@ public:
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Addition operator
|
|
||||||
//! \~russian Оператор сложения
|
|
||||||
uint_cl<L> operator+(const uint_cl<L> & v) {
|
uint_cl<L> operator+(const uint_cl<L> & v) {
|
||||||
uint_cl<L> t;
|
uint_cl<L> t;
|
||||||
uint cv;
|
uint cv;
|
||||||
@@ -245,15 +165,12 @@ public:
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Bitwise AND operator
|
|
||||||
//! \~russian Побитовый оператор И
|
|
||||||
uint_cl<L> operator&(const uint_cl<L> & v) const {
|
uint_cl<L> operator&(const uint_cl<L> & v) const {
|
||||||
uint_cl<L> t;
|
uint_cl<L> t;
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
t.data_[i] = v.data_[i] & data_[i];
|
t.data_[i] = v.data_[i] & data_[i];
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint_cl<L> operator&(const uchar & v) const { return *this & uint_cl<L>(v); }
|
uint_cl<L> operator&(const uchar & v) const { return *this & uint_cl<L>(v); }
|
||||||
uint_cl<L> operator&(const ushort & v) const { return *this & uint_cl<L>(v); }
|
uint_cl<L> operator&(const ushort & v) const { return *this & uint_cl<L>(v); }
|
||||||
uint_cl<L> operator&(const uint & v) const { return *this & uint_cl<L>(v); }
|
uint_cl<L> operator&(const uint & v) const { return *this & uint_cl<L>(v); }
|
||||||
@@ -265,15 +182,12 @@ public:
|
|||||||
uint_cl<L> operator&(const long & v) const { return *this & uint_cl<L>(v); }
|
uint_cl<L> operator&(const long & v) const { return *this & uint_cl<L>(v); }
|
||||||
uint_cl<L> operator&(const llong & v) const { return *this & uint_cl<L>(v); }
|
uint_cl<L> operator&(const llong & v) const { return *this & uint_cl<L>(v); }
|
||||||
|
|
||||||
//! \~english Bitwise OR operator
|
|
||||||
//! \~russian Побитовый оператор ИЛИ
|
|
||||||
uint_cl<L> operator|(const uint_cl<L> & v) const {
|
uint_cl<L> operator|(const uint_cl<L> & v) const {
|
||||||
uint_cl<L> t;
|
uint_cl<L> t;
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
t.data_[i] = v.data_[i] | data_[i];
|
t.data_[i] = v.data_[i] | data_[i];
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint_cl<L> operator|(const uchar & v) const { return *this | uint_cl<L>(v); }
|
uint_cl<L> operator|(const uchar & v) const { return *this | uint_cl<L>(v); }
|
||||||
uint_cl<L> operator|(const ushort & v) const { return *this | uint_cl<L>(v); }
|
uint_cl<L> operator|(const ushort & v) const { return *this | uint_cl<L>(v); }
|
||||||
uint_cl<L> operator|(const uint & v) const { return *this | uint_cl<L>(v); }
|
uint_cl<L> operator|(const uint & v) const { return *this | uint_cl<L>(v); }
|
||||||
@@ -285,15 +199,12 @@ public:
|
|||||||
uint_cl<L> operator|(const long & v) const { return *this | uint_cl<L>(v); }
|
uint_cl<L> operator|(const long & v) const { return *this | uint_cl<L>(v); }
|
||||||
uint_cl<L> operator|(const llong & v) const { return *this | uint_cl<L>(v); }
|
uint_cl<L> operator|(const llong & v) const { return *this | uint_cl<L>(v); }
|
||||||
|
|
||||||
//! \~english Bitwise XOR operator
|
|
||||||
//! \~russian Побитовый оператор исключающее ИЛИ
|
|
||||||
uint_cl<L> operator^(const uint_cl<L> & v) const {
|
uint_cl<L> operator^(const uint_cl<L> & v) const {
|
||||||
uint_cl<L> t;
|
uint_cl<L> t;
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
t.data_[i] = v.data_[i] ^ data_[i];
|
t.data_[i] = v.data_[i] ^ data_[i];
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint_cl<L> operator^(const uchar & v) const { return *this ^ uint_cl<L>(v); }
|
uint_cl<L> operator^(const uchar & v) const { return *this ^ uint_cl<L>(v); }
|
||||||
uint_cl<L> operator^(const ushort & v) const { return *this ^ uint_cl<L>(v); }
|
uint_cl<L> operator^(const ushort & v) const { return *this ^ uint_cl<L>(v); }
|
||||||
uint_cl<L> operator^(const uint & v) const { return *this ^ uint_cl<L>(v); }
|
uint_cl<L> operator^(const uint & v) const { return *this ^ uint_cl<L>(v); }
|
||||||
@@ -305,8 +216,6 @@ public:
|
|||||||
uint_cl<L> operator^(const long & v) const { return *this ^ uint_cl<L>(v); }
|
uint_cl<L> operator^(const long & v) const { return *this ^ uint_cl<L>(v); }
|
||||||
uint_cl<L> operator^(const llong & v) const { return *this ^ uint_cl<L>(v); }
|
uint_cl<L> operator^(const llong & v) const { return *this ^ uint_cl<L>(v); }
|
||||||
|
|
||||||
//! \~english Less than operator
|
|
||||||
//! \~russian Оператор меньше
|
|
||||||
bool operator<(const uint_cl<L> & v) const {
|
bool operator<(const uint_cl<L> & v) const {
|
||||||
for (int i = 0; i < L / 8; ++i) {
|
for (int i = 0; i < L / 8; ++i) {
|
||||||
if (v.data_[i] > data_[i]) return true;
|
if (v.data_[i] > data_[i]) return true;
|
||||||
@@ -314,9 +223,6 @@ public:
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Less than or equal operator
|
|
||||||
//! \~russian Оператор меньше или равно
|
|
||||||
bool operator<=(const uint_cl<L> & v) const {
|
bool operator<=(const uint_cl<L> & v) const {
|
||||||
for (int i = 0; i < L / 8; ++i) {
|
for (int i = 0; i < L / 8; ++i) {
|
||||||
if (v.data_[i] > data_[i]) return true;
|
if (v.data_[i] > data_[i]) return true;
|
||||||
@@ -324,9 +230,6 @@ public:
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Greater than operator
|
|
||||||
//! \~russian Оператор больше
|
|
||||||
bool operator>(const uint_cl<L> & v) const {
|
bool operator>(const uint_cl<L> & v) const {
|
||||||
for (int i = 0; i < L / 8; ++i) {
|
for (int i = 0; i < L / 8; ++i) {
|
||||||
if (v.data_[i] < data_[i]) return true;
|
if (v.data_[i] < data_[i]) return true;
|
||||||
@@ -334,9 +237,6 @@ public:
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Greater than or equal operator
|
|
||||||
//! \~russian Оператор больше или равно
|
|
||||||
bool operator>=(const uint_cl<L> & v) const {
|
bool operator>=(const uint_cl<L> & v) const {
|
||||||
for (int i = 0; i < L / 8; ++i) {
|
for (int i = 0; i < L / 8; ++i) {
|
||||||
if (v.data_[i] < data_[i]) return true;
|
if (v.data_[i] < data_[i]) return true;
|
||||||
@@ -344,27 +244,18 @@ public:
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Equality operator
|
|
||||||
//! \~russian Оператор равенства
|
|
||||||
bool operator==(const uint_cl<L> & v) const {
|
bool operator==(const uint_cl<L> & v) const {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
if (v.data_[i] != data_[i]) return false;
|
if (v.data_[i] != data_[i]) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Inequality operator
|
|
||||||
//! \~russian Оператор неравенства
|
|
||||||
bool operator!=(const uint_cl<L> & v) const {
|
bool operator!=(const uint_cl<L> & v) const {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
if (v.data_[i] != data_[i]) return true;
|
if (v.data_[i] != data_[i]) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<=(const uint_cl<8> & v1) { return (*(uchar *)data()) <= (*(uchar *)v1.data()); }
|
bool operator<=(const uint_cl<8> & v1) { return (*(uchar *)data()) <= (*(uchar *)v1.data()); }
|
||||||
|
|
||||||
//! \~english Right shift operator
|
|
||||||
//! \~russian Оператор побитового сдвига вправо
|
|
||||||
uint_cl<L> operator>>(const int & c) const {
|
uint_cl<L> operator>>(const int & c) const {
|
||||||
uint_cl<L> t;
|
uint_cl<L> t;
|
||||||
int l = L - c;
|
int l = L - c;
|
||||||
@@ -379,11 +270,7 @@ public:
|
|||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint_cl<L> operator>>(const uint & c) const { return (*this << (int)c); }
|
uint_cl<L> operator>>(const uint & c) const { return (*this << (int)c); }
|
||||||
|
|
||||||
//! \~english Left shift operator
|
|
||||||
//! \~russian Оператор побитового сдвига влево
|
|
||||||
uint_cl<L> operator<<(const int & c) const {
|
uint_cl<L> operator<<(const int & c) const {
|
||||||
uint_cl<L> t;
|
uint_cl<L> t;
|
||||||
int l = L - c;
|
int l = L - c;
|
||||||
@@ -398,28 +285,19 @@ public:
|
|||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint_cl<L> operator<<(const uint & c) const { return (*this >> (int)c); }
|
uint_cl<L> operator<<(const uint & c) const { return (*this >> (int)c); }
|
||||||
|
|
||||||
//! \~english In-place bitwise inversion
|
|
||||||
//! \~russian Побитовая инверсия на месте
|
|
||||||
uint_cl<L> & inverse() const {
|
uint_cl<L> & inverse() const {
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
data_[i] = ~data_[i];
|
data_[i] = ~data_[i];
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns bitwise inverted copy
|
|
||||||
//! \~russian Возвращает копию с побитовой инверсией
|
|
||||||
uint_cl<L> inversed() const {
|
uint_cl<L> inversed() const {
|
||||||
uint_cl<L> t(*this);
|
uint_cl<L> t(*this);
|
||||||
for (int i = 0; i < L / 8; ++i)
|
for (int i = 0; i < L / 8; ++i)
|
||||||
t.data_[i] = ~t.data_[i];
|
t.data_[i] = ~t.data_[i];
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns bit-reversed copy
|
|
||||||
//! \~russian Возвращает копию с переставленными битами
|
|
||||||
uint_cl<L> reversed() const {
|
uint_cl<L> reversed() const {
|
||||||
uint_cl<L> t;
|
uint_cl<L> t;
|
||||||
bool bit;
|
bool bit;
|
||||||
@@ -433,16 +311,8 @@ public:
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Get const pointer to data
|
|
||||||
//! \~russian Получить константный указатель на данные
|
|
||||||
const uchar * data() const { return data_; }
|
const uchar * data() const { return data_; }
|
||||||
|
|
||||||
//! \~english Get pointer to data
|
|
||||||
//! \~russian Получить указатель на данные
|
|
||||||
uchar * data() { return data_; }
|
uchar * data() { return data_; }
|
||||||
|
|
||||||
//! \~english Get data length in bytes
|
|
||||||
//! \~russian Получить длину данных в байтах
|
|
||||||
uint length() const { return L / 8; }
|
uint length() const { return L / 8; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -450,11 +320,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Reverse byte order
|
|
||||||
//! \~russian Реверс порядка байтов
|
|
||||||
//! \details
|
|
||||||
//! \~english Reverses the bit order within a byte
|
|
||||||
//! \~russian Инвертирует порядок битов в байте
|
|
||||||
inline uchar reverseByte(uchar b) {
|
inline uchar reverseByte(uchar b) {
|
||||||
uchar ret = 0;
|
uchar ret = 0;
|
||||||
bool bit;
|
bool bit;
|
||||||
@@ -465,26 +330,9 @@ inline uchar reverseByte(uchar b) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \addtogroup Math
|
|
||||||
//! \{
|
|
||||||
//! \class PICRC
|
|
||||||
//! \brief
|
|
||||||
//! \~english CRC calculator class
|
|
||||||
//! \~russian Класс калькулятора CRC
|
|
||||||
//! \details
|
|
||||||
//! \~english Calculates CRC checksum using configurable polynomial and parameters
|
|
||||||
//! \~russian Вычисляет контрольную сумму CRC с использованием настраиваемого полинома и параметров
|
|
||||||
//! \sa CRC_32, CRC_16, CRC_8
|
|
||||||
//! \}
|
|
||||||
|
|
||||||
template<uint L, typename N = uint_cl<L>>
|
template<uint L, typename N = uint_cl<L>>
|
||||||
class PIP_EXPORT PICRC {
|
class PIP_EXPORT PICRC {
|
||||||
public:
|
public:
|
||||||
//! \~english Default constructor
|
|
||||||
//! \~russian Конструктор по умолчанию
|
|
||||||
//! \note
|
|
||||||
//! \~english Polynomial value defaults to zero
|
|
||||||
//! \~russian Значение полинома по умолчанию ноль
|
|
||||||
PICRC(const N & poly = N()) {
|
PICRC(const N & poly = N()) {
|
||||||
poly_ = poly;
|
poly_ = poly;
|
||||||
reverse_poly = true;
|
reverse_poly = true;
|
||||||
@@ -493,13 +341,6 @@ public:
|
|||||||
reverse_before_xor = reverse_data = false;
|
reverse_before_xor = reverse_data = false;
|
||||||
initTable();
|
initTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Constructor with full parameters
|
|
||||||
//! \~russian Конструктор с полными параметрами
|
|
||||||
//! \param poly polynomial value
|
|
||||||
//! \param reverse_poly_ whether to reverse polynomial bits
|
|
||||||
//! \param initial initial CRC value
|
|
||||||
//! \param out_xor XOR value for output
|
|
||||||
PICRC(const N & poly, bool reverse_poly_, const N & initial, const N & out_xor) {
|
PICRC(const N & poly, bool reverse_poly_, const N & initial, const N & out_xor) {
|
||||||
poly_ = poly;
|
poly_ = poly;
|
||||||
reverse_poly = reverse_poly_;
|
reverse_poly = reverse_poly_;
|
||||||
@@ -509,33 +350,18 @@ public:
|
|||||||
initTable();
|
initTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Set initial CRC value
|
|
||||||
//! \~russian Установить начальное значение CRC
|
|
||||||
void setInitial(const N & v) { init_ = v; }
|
void setInitial(const N & v) { init_ = v; }
|
||||||
|
|
||||||
//! \~english Set output XOR value
|
|
||||||
//! \~russian Установить значение XOR для вывода
|
|
||||||
void setOutXor(const N & v) { out_ = v; }
|
void setOutXor(const N & v) { out_ = v; }
|
||||||
|
|
||||||
//! \~english Set polynomial bit reversal
|
|
||||||
//! \~russian Установить реверс битов полинома
|
|
||||||
void setReversePolynome(bool yes) {
|
void setReversePolynome(bool yes) {
|
||||||
reverse_poly = yes;
|
reverse_poly = yes;
|
||||||
initTable();
|
initTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Set output bit reversal before XOR
|
|
||||||
//! \~russian Установить реверс битов вывода перед XOR
|
|
||||||
void setReverseOutBeforeXOR(bool yes) { reverse_before_xor = yes; }
|
void setReverseOutBeforeXOR(bool yes) { reverse_before_xor = yes; }
|
||||||
|
|
||||||
//! \~english Set data byte reversal
|
|
||||||
//! \~russian Установить реверс байтов данных
|
|
||||||
void setReverseDataBytes(bool yes) { reverse_data = yes; }
|
void setReverseDataBytes(bool yes) { reverse_data = yes; }
|
||||||
|
|
||||||
//! \~english Initialize lookup table
|
|
||||||
//! \~russian Инициализировать таблицу поиска
|
|
||||||
void initTable() {
|
void initTable() {
|
||||||
N tmp, pol = reverse_poly ? reversed(poly_) : poly_;
|
N tmp, pol = reverse_poly ? reversed(poly_) : poly_;
|
||||||
|
// cout << std::hex << "poly " << (uint)N(poly_) << " -> " << (uint)N(pol) << endl;
|
||||||
for (int i = 0; i < 256; ++i) {
|
for (int i = 0; i < 256; ++i) {
|
||||||
tmp = uchar(i);
|
tmp = uchar(i);
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j)
|
||||||
@@ -544,11 +370,10 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Calculate CRC from raw data
|
|
||||||
//! \~russian Вычислить CRC из сырых данных
|
|
||||||
N calculate(const void * data, int size) {
|
N calculate(const void * data, int size) {
|
||||||
N crc = init_;
|
N crc = init_;
|
||||||
uchar *data_ = (uchar *)data, cb;
|
uchar *data_ = (uchar *)data, cb;
|
||||||
|
// cout << "process " << size << endl;
|
||||||
uchar nTemp;
|
uchar nTemp;
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
cb = data_[i];
|
cb = data_[i];
|
||||||
@@ -560,13 +385,7 @@ public:
|
|||||||
if (reverse_before_xor) crc = reversed(crc);
|
if (reverse_before_xor) crc = reversed(crc);
|
||||||
return crc ^ out_;
|
return crc ^ out_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Calculate CRC from PIByteArray
|
|
||||||
//! \~russian Вычислить CRC из PIByteArray
|
|
||||||
N calculate(const PIByteArray & d) { return calculate(d.data(), d.size()); }
|
N calculate(const PIByteArray & d) { return calculate(d.data(), d.size()); }
|
||||||
|
|
||||||
//! \~english Calculate CRC from null-terminated string
|
|
||||||
//! \~russian Вычислить CRC из нуль-терминированной строки
|
|
||||||
N calculate(const char * str) {
|
N calculate(const char * str) {
|
||||||
PIByteArray s(PIString(str).toByteArray());
|
PIByteArray s(PIString(str).toByteArray());
|
||||||
return calculate(s.data(), s.size_s());
|
return calculate(s.data(), s.size_s());
|
||||||
@@ -606,46 +425,22 @@ inline uint PICRC<32, uint>::inversed(const uint & v) {
|
|||||||
return ~v;
|
return ~v;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Standard CRC-32 (Ethernet, ZIP, etc.)
|
|
||||||
//! \~russian Стандартный CRC-32 (Ethernet, ZIP и т.д.)
|
|
||||||
typedef PICRC<32, uint> CRC_32;
|
typedef PICRC<32, uint> CRC_32;
|
||||||
|
|
||||||
//! \~english Standard CRC-24
|
|
||||||
//! \~russian Стандартный CRC-24
|
|
||||||
typedef PICRC<24> CRC_24;
|
typedef PICRC<24> CRC_24;
|
||||||
|
|
||||||
//! \~english Standard CRC-16
|
|
||||||
//! \~russian Стандартный CRC-16
|
|
||||||
typedef PICRC<16, ushort> CRC_16;
|
typedef PICRC<16, ushort> CRC_16;
|
||||||
|
|
||||||
//! \~english Standard CRC-8
|
|
||||||
//! \~russian Стандартный CRC-8
|
|
||||||
typedef PICRC<8, uchar> CRC_8;
|
typedef PICRC<8, uchar> CRC_8;
|
||||||
|
|
||||||
//! \~english Create standard CRC-32 calculator
|
|
||||||
//! \~russian Создать стандартный калькулятор CRC-32
|
|
||||||
inline CRC_32 standardCRC_32() {
|
inline CRC_32 standardCRC_32() {
|
||||||
return CRC_32(0x04C11DB7, true, 0xFFFFFFFF, 0xFFFFFFFF);
|
return CRC_32(0x04C11DB7, true, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Create standard CRC-16 calculator
|
|
||||||
//! \~russian Создать стандартный калькулятор CRC-16
|
|
||||||
inline CRC_16 standardCRC_16() {
|
inline CRC_16 standardCRC_16() {
|
||||||
return CRC_16(0x8005, true, 0x0, 0x0);
|
return CRC_16(0x8005, true, 0x0, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Create standard CRC-16 Modbus calculator
|
|
||||||
//! \~russian Создать стандартный калькулятор CRC-16 Modbus
|
|
||||||
inline CRC_16 standardCRC_16_Modbus() {
|
inline CRC_16 standardCRC_16_Modbus() {
|
||||||
return CRC_16(0x8005, 0xFFFF, 0xFFFF, false);
|
return CRC_16(0x8005, 0xFFFF, 0xFFFF, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Create standard CRC-8 calculator
|
|
||||||
//! \~russian Создать стандартный калькулятор CRC-8
|
|
||||||
inline CRC_8 standardCRC_8() {
|
inline CRC_8 standardCRC_8() {
|
||||||
return CRC_8(0xD5, true, 0x0, 0x0);
|
return CRC_8(0xD5, true, 0x0, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \}
|
|
||||||
|
|
||||||
#endif // CRC_H
|
#endif // CRC_H
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
//! \addtogroup Math
|
/*! \file pifft.h
|
||||||
//! \{
|
* \ingroup Math
|
||||||
//! \file pifft.h
|
* \ingroup FFTW
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Declares \a PIFFT classes
|
* \~english FFT, IFFT and Hilbert transformations
|
||||||
//! \~russian Объявление классов \a PIFFT
|
* \~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
|
PIP - Platform Independent Primitives
|
||||||
Class for FFT, IFFT and Hilbert transformations
|
Class for FFT, IFFT and Hilbert transformations
|
||||||
@@ -67,40 +64,16 @@
|
|||||||
|
|
||||||
# include "pip_fftw_export.h"
|
# include "pip_fftw_export.h"
|
||||||
|
|
||||||
//! \addtogroup Math
|
|
||||||
//! \{
|
|
||||||
//! \class PIFFT_double
|
|
||||||
//! \brief
|
|
||||||
//! \~english Fast Fourier Transform implementation for double precision.
|
|
||||||
//! \~russian Реализация быстрого преобразования Фурье для двойной точности.
|
|
||||||
//! \~\}
|
|
||||||
//! \sa \a PIFFT_float, \a PIFFTW
|
|
||||||
class PIP_EXPORT PIFFT_double {
|
class PIP_EXPORT PIFFT_double {
|
||||||
public:
|
public:
|
||||||
//! \~english Default constructor.
|
|
||||||
//! \~russian Конструктор по умолчанию.
|
|
||||||
PIFFT_double();
|
PIFFT_double();
|
||||||
|
|
||||||
//! \~english Calculate FFT from complex vector.
|
|
||||||
//! \~russian Вычисление БПФ из комплексного вектора.
|
|
||||||
PIVector<complexd> * calcFFT(const PIVector<complexd> & val);
|
PIVector<complexd> * calcFFT(const PIVector<complexd> & val);
|
||||||
//! \~english Calculate FFT from real vector.
|
|
||||||
//! \~russian Вычисление БПФ из вещественного вектора.
|
|
||||||
PIVector<complexd> * calcFFT(const PIVector<double> & val);
|
PIVector<complexd> * calcFFT(const PIVector<double> & val);
|
||||||
//! \~english Calculate inverse FFT.
|
|
||||||
//! \~russian Вычисление обратного БПФ.
|
|
||||||
PIVector<complexd> * calcFFTinverse(const PIVector<complexd> & val);
|
PIVector<complexd> * calcFFTinverse(const PIVector<complexd> & val);
|
||||||
//! \~english Calculate Hilbert transform.
|
|
||||||
//! \~russian Вычисление преобразования Гильберта.
|
|
||||||
PIVector<complexd> * calcHilbert(const PIVector<double> & val);
|
PIVector<complexd> * calcHilbert(const PIVector<double> & val);
|
||||||
//! \~english Get amplitude spectrum.
|
|
||||||
//! \~russian Получить амплитудный спектр.
|
|
||||||
PIVector<double> getAmplitude() const;
|
PIVector<double> getAmplitude() const;
|
||||||
//! \~english Get real part.
|
|
||||||
//! \~russian Получить действительную часть.
|
|
||||||
PIVector<double> getReal() const;
|
PIVector<double> getReal() const;
|
||||||
//! \~english Get imaginary part.
|
|
||||||
//! \~russian Получить мнимую часть.
|
|
||||||
PIVector<double> getImag() const;
|
PIVector<double> getImag() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -145,40 +118,16 @@ private:
|
|||||||
void ftbase_ffttwcalc(PIVector<double> * a, int aoffset, int n1, int n2);
|
void ftbase_ffttwcalc(PIVector<double> * a, int aoffset, int n1, int n2);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \addtogroup Math
|
|
||||||
//! \{
|
|
||||||
//! \class PIFFT_float
|
|
||||||
//! \brief
|
|
||||||
//! \~english Fast Fourier Transform implementation for single precision.
|
|
||||||
//! \~russian Реализация быстрого преобразования Фурье для одинарной точности.
|
|
||||||
//! \~\}
|
|
||||||
//! \sa \a PIFFT_double, \a PIFFTW
|
|
||||||
class PIP_EXPORT PIFFT_float {
|
class PIP_EXPORT PIFFT_float {
|
||||||
public:
|
public:
|
||||||
//! \~english Default constructor.
|
|
||||||
//! \~russian Конструктор по умолчанию.
|
|
||||||
PIFFT_float();
|
PIFFT_float();
|
||||||
|
|
||||||
//! \~english Calculate FFT from complex vector.
|
|
||||||
//! \~russian Вычисление БПФ из комплексного вектора.
|
|
||||||
PIVector<complexf> * calcFFT(const PIVector<complexf> & val);
|
PIVector<complexf> * calcFFT(const PIVector<complexf> & val);
|
||||||
//! \~english Calculate FFT from real vector.
|
|
||||||
//! \~russian Вычисление БПФ из вещественного вектора.
|
|
||||||
PIVector<complexf> * calcFFT(const PIVector<float> & val);
|
PIVector<complexf> * calcFFT(const PIVector<float> & val);
|
||||||
//! \~english Calculate inverse FFT.
|
|
||||||
//! \~russian Вычисление обратного БПФ.
|
|
||||||
PIVector<complexf> * calcFFTinverse(const PIVector<complexf> & val);
|
PIVector<complexf> * calcFFTinverse(const PIVector<complexf> & val);
|
||||||
//! \~english Calculate Hilbert transform.
|
|
||||||
//! \~russian Вычисление преобразования Гильберта.
|
|
||||||
PIVector<complexf> * calcHilbert(const PIVector<float> & val);
|
PIVector<complexf> * calcHilbert(const PIVector<float> & val);
|
||||||
//! \~english Get amplitude spectrum.
|
|
||||||
//! \~russian Получить амплитудный спектр.
|
|
||||||
PIVector<float> getAmplitude() const;
|
PIVector<float> getAmplitude() const;
|
||||||
//! \~english Get real part.
|
|
||||||
//! \~russian Получить действительную часть.
|
|
||||||
PIVector<float> getReal() const;
|
PIVector<float> getReal() const;
|
||||||
//! \~english Get imaginary part.
|
|
||||||
//! \~russian Получить мнимую часть.
|
|
||||||
PIVector<float> getImag() const;
|
PIVector<float> getImag() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -222,7 +171,6 @@ private:
|
|||||||
void ftbase_fftirltrec(PIVector<float> * a, int astart, int astride, PIVector<float> * b, int bstart, int bstride, int m, int n);
|
void ftbase_fftirltrec(PIVector<float> * a, int astart, int astride, PIVector<float> * b, int bstart, int bstride, int m, int n);
|
||||||
void ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int n2);
|
void ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int n2);
|
||||||
};
|
};
|
||||||
//! \~\}
|
|
||||||
|
|
||||||
typedef PIFFT_double PIFFT;
|
typedef PIFFT_double PIFFT;
|
||||||
typedef PIFFT_double PIFFTd;
|
typedef PIFFT_double PIFFTd;
|
||||||
@@ -230,63 +178,40 @@ typedef PIFFT_float PIFFTf;
|
|||||||
|
|
||||||
# ifndef CC_VC
|
# ifndef CC_VC
|
||||||
|
|
||||||
# define _PIFFTW_H(type) \
|
# define _PIFFTW_H(type) \
|
||||||
class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \
|
class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \
|
||||||
public: \
|
public: \
|
||||||
_PIFFTW_P_##type##_(); \
|
_PIFFTW_P_##type##_(); \
|
||||||
~_PIFFTW_P_##type##_(); \
|
~_PIFFTW_P_##type##_(); \
|
||||||
const PIVector<complex<type>> & calcFFT(const PIVector<complex<type>> & in); \
|
const PIVector<complex<type>> & calcFFT(const PIVector<complex<type>> & in); \
|
||||||
const PIVector<complex<type>> & calcFFTR(const PIVector<type> & in); \
|
const PIVector<complex<type>> & calcFFTR(const PIVector<type> & in); \
|
||||||
const PIVector<complex<type>> & calcFFTI(const PIVector<complex<type>> & in); \
|
const PIVector<complex<type>> & calcFFTI(const PIVector<complex<type>> & in); \
|
||||||
void preparePlan(int size, int op); \
|
void preparePlan(int size, int op); \
|
||||||
void * impl; \
|
void * impl; \
|
||||||
};
|
};
|
||||||
_PIFFTW_H(float)
|
_PIFFTW_H(float)
|
||||||
_PIFFTW_H(double)
|
_PIFFTW_H(double)
|
||||||
_PIFFTW_H(ldouble)
|
_PIFFTW_H(ldouble)
|
||||||
|
|
||||||
//! \addtogroup FFTW
|
|
||||||
//! \{
|
|
||||||
//! \class PIFFTW
|
|
||||||
//! \brief
|
|
||||||
//! \~english FFTW wrapper for arbitrary precision types.
|
|
||||||
//! \~russian Обёртка FFTW для типов произвольной точности.
|
|
||||||
//! \~\}
|
|
||||||
//! \note Requires linking against libfftw3
|
|
||||||
//! \sa \a PIFFT_double, \a PIFFT_float
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class PIFFTW {
|
class PIFFTW {
|
||||||
public:
|
public:
|
||||||
//! \~english Default constructor.
|
|
||||||
//! \~russian Конструктор по умолчанию.
|
|
||||||
explicit PIFFTW() {
|
explicit PIFFTW() {
|
||||||
p = 0;
|
p = 0;
|
||||||
newP(p);
|
newP(p);
|
||||||
}
|
}
|
||||||
//! \~english Destructor.
|
|
||||||
//! \~russian Деструктор.
|
|
||||||
~PIFFTW() { deleteP(p); }
|
~PIFFTW() { deleteP(p); }
|
||||||
|
|
||||||
//! \~english Calculate FFT from complex vector.
|
|
||||||
//! \~russian Вычисление БПФ из комплексного вектора.
|
|
||||||
inline const PIVector<complex<T>> & calcFFT(const PIVector<complex<T>> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
inline const PIVector<complex<T>> & calcFFT(const PIVector<complex<T>> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
||||||
//! \~english Calculate FFT from real vector.
|
|
||||||
//! \~russian Вычисление БПФ из вещественного вектора.
|
|
||||||
inline const PIVector<complex<T>> & calcFFT(const PIVector<T> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
inline const PIVector<complex<T>> & calcFFT(const PIVector<T> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
||||||
//! \~english Calculate inverse FFT.
|
|
||||||
//! \~russian Вычисление обратного БПФ.
|
|
||||||
inline const PIVector<complex<T>> & calcFFTinverse(const PIVector<complex<T>> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
inline const PIVector<complex<T>> & calcFFTinverse(const PIVector<complex<T>> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
||||||
|
|
||||||
//! \~english FFT operation type.
|
|
||||||
//! \~russian Тип операции БПФ.
|
|
||||||
enum FFT_Operation {
|
enum FFT_Operation {
|
||||||
foReal,
|
foReal,
|
||||||
foComplex,
|
foComplex,
|
||||||
foInverse
|
foInverse
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Prepare computation plan.
|
|
||||||
//! \~russian Подготовить план вычислений.
|
|
||||||
inline void preparePlan(int size, FFT_Operation op) {}
|
inline void preparePlan(int size, FFT_Operation op) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -297,7 +222,6 @@ private:
|
|||||||
|
|
||||||
void * p;
|
void * p;
|
||||||
};
|
};
|
||||||
//! \~\}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
//! \addtogroup Math
|
/*! \file pigeometry.h
|
||||||
//! \{
|
* \ingroup Math
|
||||||
//! \file pigeometry.h
|
* \brief
|
||||||
//! \brief
|
* \~english Geometry base classes
|
||||||
//! \~english Geometry utilities
|
* \~russian Базовые геометрические классы
|
||||||
//! \~russian Геометрические утилиты
|
* \~\details
|
||||||
//! \~\authors
|
* \~english
|
||||||
//! \~english Ivan Pelipenko peri4ko@yandex.ru; Andrey Bychkov work.a.b@yandex.ru
|
* Add \a PIPoint, \a PILine and \a PIRect classes.
|
||||||
//! \~russian Иван Пелипенко peri4ko@yandex.ru; Андрей Бычков work.a.b@yandex.ru
|
* \~russian
|
||||||
//! \~\}
|
* Содержит классы: \a PIPoint, \a PILine и \a PIRect.
|
||||||
|
* * \~\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
|
PIP - Platform Independent Primitives
|
||||||
Geometry base classes
|
Geometry base classes
|
||||||
|
|||||||
@@ -21,10 +21,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
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/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! \~english OpenCL module
|
|
||||||
//! \~russian Модуль OpenCL
|
|
||||||
//! \defgroup OpenCL OpenCL
|
//! \defgroup OpenCL OpenCL
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english OpenCL support
|
//! \~english OpenCL support
|
||||||
@@ -66,41 +63,17 @@
|
|||||||
|
|
||||||
class PIP_OPENCL_EXPORT PIOpenCL {
|
class PIP_OPENCL_EXPORT PIOpenCL {
|
||||||
public:
|
public:
|
||||||
//! \~english Kernel argument structure
|
|
||||||
//! \~russian Структура аргумента ядра
|
|
||||||
struct KernelArg;
|
struct KernelArg;
|
||||||
|
|
||||||
//! \~english Device structure
|
|
||||||
//! \~russian Структура устройства
|
|
||||||
struct Device;
|
struct Device;
|
||||||
|
|
||||||
//! \~english Platform structure
|
|
||||||
//! \~russian Структура платформы
|
|
||||||
struct Platform;
|
struct Platform;
|
||||||
|
|
||||||
//! \~english OpenCL context class
|
|
||||||
//! \~russian Класс контекста OpenCL
|
|
||||||
class Context;
|
class Context;
|
||||||
|
|
||||||
//! \~english OpenCL buffer class
|
|
||||||
//! \~russian Класс буфера OpenCL
|
|
||||||
class Buffer;
|
class Buffer;
|
||||||
|
|
||||||
//! \~english OpenCL program class
|
|
||||||
//! \~russian Класс программы OpenCL
|
|
||||||
class Program;
|
class Program;
|
||||||
|
|
||||||
//! \~english OpenCL kernel class
|
|
||||||
//! \~russian Класс ядра OpenCL
|
|
||||||
class Kernel;
|
class Kernel;
|
||||||
|
|
||||||
//! \~english List of devices
|
|
||||||
//! \~russian Список устройств
|
|
||||||
typedef PIVector<Device> DeviceList;
|
typedef PIVector<Device> DeviceList;
|
||||||
|
|
||||||
|
|
||||||
//! \~english Address space qualifiers
|
|
||||||
//! \~russian Квалификаторы адресного пространства
|
|
||||||
enum AddressQualifier {
|
enum AddressQualifier {
|
||||||
AddressGlobal,
|
AddressGlobal,
|
||||||
AddressLocal,
|
AddressLocal,
|
||||||
@@ -108,8 +81,6 @@ public:
|
|||||||
AddressPrivate,
|
AddressPrivate,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Access qualifiers
|
|
||||||
//! \~russian Квалификаторы доступа
|
|
||||||
enum AccessQualifier {
|
enum AccessQualifier {
|
||||||
AccessReadOnly,
|
AccessReadOnly,
|
||||||
AccessWriteOnly,
|
AccessWriteOnly,
|
||||||
@@ -117,16 +88,12 @@ public:
|
|||||||
AccessNone,
|
AccessNone,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Buffer direction
|
|
||||||
//! \~russian Направление буфера
|
|
||||||
enum Direction {
|
enum Direction {
|
||||||
Input = 0x01,
|
Input = 0x01,
|
||||||
Output = 0x02,
|
Output = 0x02,
|
||||||
InputOutput = Input | Output,
|
InputOutput = Input | Output,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Type qualifiers
|
|
||||||
//! \~russian Квалификаторы типа
|
|
||||||
enum TypeQualifier {
|
enum TypeQualifier {
|
||||||
TypeConst,
|
TypeConst,
|
||||||
TypeRestrict,
|
TypeRestrict,
|
||||||
@@ -134,8 +101,6 @@ public:
|
|||||||
TypeNone,
|
TypeNone,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Argument types
|
|
||||||
//! \~russian Типы аргументов
|
|
||||||
enum ArgType {
|
enum ArgType {
|
||||||
Char = 1,
|
Char = 1,
|
||||||
UChar,
|
UChar,
|
||||||
@@ -150,51 +115,17 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Kernel argument information
|
|
||||||
//! \~russian Информация об аргументе ядра
|
|
||||||
struct PIP_OPENCL_EXPORT KernelArg {
|
struct PIP_OPENCL_EXPORT KernelArg {
|
||||||
//! \~english Default constructor
|
|
||||||
//! \~russian Конструктор по умолчанию
|
|
||||||
KernelArg();
|
KernelArg();
|
||||||
|
|
||||||
//! \~english Address qualifier
|
|
||||||
//! \~russian Квалификатор адреса
|
|
||||||
AddressQualifier address_qualifier;
|
AddressQualifier address_qualifier;
|
||||||
|
|
||||||
//! \~english Access qualifier
|
|
||||||
//! \~russian Квалификатор доступа
|
|
||||||
AccessQualifier access_qualifier;
|
AccessQualifier access_qualifier;
|
||||||
|
|
||||||
//! \~english Buffer direction
|
|
||||||
//! \~russian Направление буфера
|
|
||||||
Direction direction;
|
Direction direction;
|
||||||
|
|
||||||
//! \~english Type qualifier
|
|
||||||
//! \~russian Квалификатор типа
|
|
||||||
TypeQualifier type_qualifier;
|
TypeQualifier type_qualifier;
|
||||||
|
|
||||||
//! \~english Argument name
|
|
||||||
//! \~russian Имя аргумента
|
|
||||||
PIString arg_name;
|
PIString arg_name;
|
||||||
|
|
||||||
//! \~english Type name
|
|
||||||
//! \~russian Имя типа
|
|
||||||
PIString type_name;
|
PIString type_name;
|
||||||
|
|
||||||
//! \~english Base type name
|
|
||||||
//! \~russian Имя базового типа
|
|
||||||
PIString base_type_name;
|
PIString base_type_name;
|
||||||
|
|
||||||
//! \~english Is pointer
|
|
||||||
//! \~russian Является указателем
|
|
||||||
bool is_pointer;
|
bool is_pointer;
|
||||||
|
|
||||||
//! \~english Argument type
|
|
||||||
//! \~russian Тип аргумента
|
|
||||||
ArgType arg_type;
|
ArgType arg_type;
|
||||||
|
|
||||||
//! \~english Dimensions
|
|
||||||
//! \~russian Размерности
|
|
||||||
int dims;
|
int dims;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -203,180 +134,68 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english OpenCL device information
|
|
||||||
//! \~russian Информация об устройстве OpenCL
|
|
||||||
struct PIP_OPENCL_EXPORT Device {
|
struct PIP_OPENCL_EXPORT Device {
|
||||||
//! \~english Default constructor
|
|
||||||
//! \~russian Конструктор по умолчанию
|
|
||||||
Device() {
|
Device() {
|
||||||
id = platform_id = 0;
|
id = platform_id = 0;
|
||||||
max_compute_units = max_clock_frequency = 0;
|
max_compute_units = max_clock_frequency = 0;
|
||||||
max_memory_size = 0;
|
max_memory_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Check if device is valid
|
|
||||||
//! \~russian Проверить устройство на корректность
|
|
||||||
bool isValid() const { return id != 0; }
|
bool isValid() const { return id != 0; }
|
||||||
|
|
||||||
//! \~english Get display text
|
|
||||||
//! \~russian Получить текст для отображения
|
|
||||||
PIString displayText() const { return name.trimmed() + " (" + device_version.trimmed() + ")"; }
|
PIString displayText() const { return name.trimmed() + " (" + device_version.trimmed() + ")"; }
|
||||||
|
|
||||||
//! \~english Device handle
|
|
||||||
//! \~russian Дескриптор устройства
|
|
||||||
void * id;
|
void * id;
|
||||||
|
|
||||||
//! \~english Platform ID
|
|
||||||
//! \~russian ID платформы
|
|
||||||
void * platform_id;
|
void * platform_id;
|
||||||
|
|
||||||
//! \~english Device name
|
|
||||||
//! \~russian Имя устройства
|
|
||||||
PIString name;
|
PIString name;
|
||||||
|
|
||||||
//! \~english Vendor name
|
|
||||||
//! \~russian Имя производителя
|
|
||||||
PIString vendor;
|
PIString vendor;
|
||||||
|
|
||||||
//! \~english Device version
|
|
||||||
//! \~russian Версия устройства
|
|
||||||
PIString device_version;
|
PIString device_version;
|
||||||
|
|
||||||
//! \~english Driver version
|
|
||||||
//! \~russian Версия драйвера
|
|
||||||
PIString driver_version;
|
PIString driver_version;
|
||||||
|
|
||||||
//! \~english Maximum compute units
|
|
||||||
//! \~russian Максимум вычислительных блоков
|
|
||||||
int max_compute_units;
|
int max_compute_units;
|
||||||
|
|
||||||
//! \~english Maximum clock frequency
|
|
||||||
//! \~russian Максимальная тактовая частота
|
|
||||||
int max_clock_frequency;
|
int max_clock_frequency;
|
||||||
|
|
||||||
//! \~english Maximum memory size
|
|
||||||
//! \~russian Максимальный размер памяти
|
|
||||||
ullong max_memory_size;
|
ullong max_memory_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english OpenCL platform information
|
|
||||||
//! \~russian Информация о платформе OpenCL
|
|
||||||
struct PIP_OPENCL_EXPORT Platform {
|
struct PIP_OPENCL_EXPORT Platform {
|
||||||
//! \~english Default constructor
|
|
||||||
//! \~russian Конструктор по умолчанию
|
|
||||||
Platform() { id = 0; }
|
Platform() { id = 0; }
|
||||||
|
|
||||||
//! \~english Check if platform is valid
|
|
||||||
//! \~russian Проверить платформу на корректность
|
|
||||||
bool isValid() const { return id != 0; }
|
bool isValid() const { return id != 0; }
|
||||||
|
|
||||||
//! \~english Get display text
|
|
||||||
//! \~russian Получить текст для отображения
|
|
||||||
PIString displayText() const { return name.trimmed() + " (" + version.trimmed() + ", " + profile.trimmed() + ")"; }
|
PIString displayText() const { return name.trimmed() + " (" + version.trimmed() + ", " + profile.trimmed() + ")"; }
|
||||||
|
|
||||||
//! \~english Platform handle
|
|
||||||
//! \~russian Дескриптор платформы
|
|
||||||
void * id;
|
void * id;
|
||||||
|
|
||||||
//! \~english Platform name
|
|
||||||
//! \~russian Имя платформы
|
|
||||||
PIString name;
|
PIString name;
|
||||||
|
|
||||||
//! \~english Vendor name
|
|
||||||
//! \~russian Имя производителя
|
|
||||||
PIString vendor;
|
PIString vendor;
|
||||||
|
|
||||||
//! \~english Profile
|
|
||||||
//! \~russian Профиль
|
|
||||||
PIString profile;
|
PIString profile;
|
||||||
|
|
||||||
//! \~english Version
|
|
||||||
//! \~russian Версия
|
|
||||||
PIString version;
|
PIString version;
|
||||||
|
|
||||||
//! \~english Extensions
|
|
||||||
//! \~russian Расширения
|
|
||||||
PIStringList extensions;
|
PIStringList extensions;
|
||||||
|
|
||||||
//! \~english Available devices
|
|
||||||
//! \~russian Доступные устройства
|
|
||||||
PIVector<Device> devices;
|
PIVector<Device> devices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english OpenCL context for managing devices and resources
|
|
||||||
//! \~russian Контекст OpenCL для управления устройствами и ресурсами
|
|
||||||
class PIP_OPENCL_EXPORT Context {
|
class PIP_OPENCL_EXPORT Context {
|
||||||
friend class Buffer;
|
friend class Buffer;
|
||||||
friend class Program;
|
friend class Program;
|
||||||
friend class Kernel;
|
friend class Kernel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
~Context();
|
~Context();
|
||||||
|
|
||||||
//! \~english Get context handle
|
|
||||||
//! \~russian Получить дескриптор контекста
|
|
||||||
void * handle();
|
void * handle();
|
||||||
|
|
||||||
//! \~english Get command queue
|
|
||||||
//! \~russian Получить очередь команд
|
|
||||||
void * queue();
|
void * queue();
|
||||||
|
|
||||||
//! \~english Create context for device list
|
|
||||||
//! \~russian Создать контекст для списка устройств
|
|
||||||
//! \param dl List of devices
|
|
||||||
//! \return New context or nullptr
|
|
||||||
static Context * create(const DeviceList & dl);
|
static Context * create(const DeviceList & dl);
|
||||||
|
|
||||||
//! \~english Create context for single device
|
|
||||||
//! \~russian Создать контекст для одного устройства
|
|
||||||
//! \param d Device
|
|
||||||
//! \return New context or nullptr
|
|
||||||
static Context * create(const Device & d) { return create(DeviceList() << d); }
|
static Context * create(const Device & d) { return create(DeviceList() << d); }
|
||||||
|
|
||||||
//! \~english Create context by platform name
|
|
||||||
//! \~russian Создать контекст по имени платформы
|
|
||||||
//! \param part_name Platform name pattern
|
|
||||||
//! \return New context or nullptr
|
|
||||||
static Context * create(const PIString & part_name);
|
static Context * create(const PIString & part_name);
|
||||||
|
|
||||||
//! \~english Create program from source
|
|
||||||
//! \~russian Создать программу из исходного кода
|
|
||||||
//! \param source OpenCL source code
|
|
||||||
//! \param args Build arguments
|
|
||||||
//! \param error Error message output
|
|
||||||
//! \return New program or nullptr
|
|
||||||
Program * createProgram(const PIString & source, const PIStringList & args = PIStringList(), PIString * error = 0);
|
Program * createProgram(const PIString & source, const PIStringList & args = PIStringList(), PIString * error = 0);
|
||||||
|
|
||||||
//! \~english Create buffer from vector
|
|
||||||
//! \~russian Создать буфер из вектора
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Buffer * createBuffer(PIOpenCL::Direction dir, PIVector<T> & container) {
|
Buffer * createBuffer(PIOpenCL::Direction dir, PIVector<T> & container) {
|
||||||
T def = T();
|
T def = T();
|
||||||
return createBuffer(dir, &container, Buffer::cVector, PIByteArray(&def, sizeof(T)), container.size());
|
return createBuffer(dir, &container, Buffer::cVector, PIByteArray(&def, sizeof(T)), container.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Create buffer from deque
|
|
||||||
//! \~russian Создать буфер из deque
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Buffer * createBuffer(PIOpenCL::Direction dir, PIDeque<T> & container) {
|
Buffer * createBuffer(PIOpenCL::Direction dir, PIDeque<T> & container) {
|
||||||
T def = T();
|
T def = T();
|
||||||
return createBuffer(dir, &container, Buffer::cDeque, PIByteArray(&def, sizeof(T)), container.size());
|
return createBuffer(dir, &container, Buffer::cDeque, PIByteArray(&def, sizeof(T)), container.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Create buffer from 2D vector
|
|
||||||
//! \~russian Создать буфер из 2D вектора
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Buffer * createBuffer(PIOpenCL::Direction dir, PIVector2D<T> & container) {
|
Buffer * createBuffer(PIOpenCL::Direction dir, PIVector2D<T> & container) {
|
||||||
T def = T();
|
T def = T();
|
||||||
return createBuffer(dir, &container, Buffer::cVector2D, PIByteArray(&def, sizeof(T)), container.size());
|
return createBuffer(dir, &container, Buffer::cVector2D, PIByteArray(&def, sizeof(T)), container.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Create buffer for elements
|
|
||||||
//! \~russian Создать буфер для элементов
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Buffer * createBuffer(PIOpenCL::Direction dir, uint elements) {
|
Buffer * createBuffer(PIOpenCL::Direction dir, uint elements) {
|
||||||
T def = T();
|
T def = T();
|
||||||
@@ -397,70 +216,26 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english OpenCL buffer for data storage
|
|
||||||
//! \~russian Буфер OpenCL для хранения данных
|
|
||||||
class PIP_OPENCL_EXPORT Buffer {
|
class PIP_OPENCL_EXPORT Buffer {
|
||||||
friend class Context;
|
friend class Context;
|
||||||
friend class Kernel;
|
friend class Kernel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
~Buffer();
|
~Buffer();
|
||||||
|
|
||||||
//! \~english Get buffer handle
|
|
||||||
//! \~russian Получить дескриптор буфера
|
|
||||||
void * handle();
|
void * handle();
|
||||||
|
|
||||||
//! \~english Resize buffer
|
|
||||||
//! \~russian Изменить размер буфера
|
|
||||||
//! \param new_elements New number of elements
|
|
||||||
//! \return true if successful
|
|
||||||
bool resize(uint new_elements);
|
bool resize(uint new_elements);
|
||||||
|
|
||||||
//! \~english Clear buffer
|
|
||||||
//! \~russian Очистить буфер
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
//! \~english Copy to container
|
|
||||||
//! \~russian Копировать в контейнер
|
|
||||||
void copyToContainer();
|
void copyToContainer();
|
||||||
|
|
||||||
//! \~english Copy to memory
|
|
||||||
//! \~russian Копировать в память
|
|
||||||
void copyTo(void * data);
|
void copyTo(void * data);
|
||||||
|
|
||||||
//! \~english Copy to memory with offset
|
|
||||||
//! \~russian Копировать в память со смещением
|
|
||||||
void copyTo(void * data, int elements_count, int elements_offset = 0);
|
void copyTo(void * data, int elements_count, int elements_offset = 0);
|
||||||
|
|
||||||
//! \~english Copy to another buffer
|
|
||||||
//! \~russian Копировать в другой буфер
|
|
||||||
void copyTo(Buffer * buffer, int elements_count = -1, int elements_from_offset = 0, int elements_to_offset = 0);
|
void copyTo(Buffer * buffer, int elements_count = -1, int elements_from_offset = 0, int elements_to_offset = 0);
|
||||||
|
|
||||||
//! \~english Copy from container
|
|
||||||
//! \~russian Копировать из контейнера
|
|
||||||
void copyFromContainer();
|
void copyFromContainer();
|
||||||
|
|
||||||
//! \~english Copy from memory
|
|
||||||
//! \~russian Копировать из памяти
|
|
||||||
void copyFrom(void * data);
|
void copyFrom(void * data);
|
||||||
|
|
||||||
//! \~english Copy from memory with offset
|
|
||||||
//! \~russian Копировать из памяти со смещением
|
|
||||||
void copyFrom(void * data, int elements_count, int elements_offset = 0);
|
void copyFrom(void * data, int elements_count, int elements_offset = 0);
|
||||||
|
|
||||||
//! \~english Copy from another buffer
|
|
||||||
//! \~russian Копировать из другого буфера
|
|
||||||
void copyFrom(Buffer * buffer, int elements_count = -1, int elements_from_offset = 0, int elements_to_offset = 0);
|
void copyFrom(Buffer * buffer, int elements_count = -1, int elements_from_offset = 0, int elements_to_offset = 0);
|
||||||
|
|
||||||
//! \~english Get elements count
|
|
||||||
//! \~russian Получить количество элементов
|
|
||||||
uint elementsCount() const { return elements; }
|
uint elementsCount() const { return elements; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! \~english Container types
|
|
||||||
//! \~russian Типы контейнеров
|
|
||||||
enum Container {
|
enum Container {
|
||||||
cNone,
|
cNone,
|
||||||
cVector,
|
cVector,
|
||||||
@@ -482,32 +257,16 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english OpenCL program containing kernels
|
|
||||||
//! \~russian Программа OpenCL содержащая ядра
|
|
||||||
class PIP_OPENCL_EXPORT Program {
|
class PIP_OPENCL_EXPORT Program {
|
||||||
friend class Context;
|
friend class Context;
|
||||||
friend class Kernel;
|
friend class Kernel;
|
||||||
friend class Buffer;
|
friend class Buffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
~Program();
|
~Program();
|
||||||
|
|
||||||
//! \~english Get context
|
|
||||||
//! \~russian Получить контекст
|
|
||||||
Context * context() const { return context_; }
|
Context * context() const { return context_; }
|
||||||
|
|
||||||
//! \~english Get source code
|
|
||||||
//! \~russian Получить исходный код
|
|
||||||
const PIString & sourceCode() const { return source_; }
|
const PIString & sourceCode() const { return source_; }
|
||||||
|
|
||||||
//! \~english Get kernel by index
|
|
||||||
//! \~russian Получить ядро по индексу
|
|
||||||
Kernel * kernel(int index = 0) const { return kernels_[index]; }
|
Kernel * kernel(int index = 0) const { return kernels_[index]; }
|
||||||
|
|
||||||
//! \~english Get all kernels
|
|
||||||
//! \~russian Получить все ядра
|
|
||||||
const PIVector<Kernel *> & kernels() const { return kernels_; }
|
const PIVector<Kernel *> & kernels() const { return kernels_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -521,68 +280,28 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english OpenCL kernel for execution
|
|
||||||
//! \~russian Ядро OpenCL для выполнения
|
|
||||||
class PIP_OPENCL_EXPORT Kernel {
|
class PIP_OPENCL_EXPORT Kernel {
|
||||||
friend class Program;
|
friend class Program;
|
||||||
friend class Buffer;
|
friend class Buffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Get parent program
|
|
||||||
//! \~russian Получить родительскую программу
|
|
||||||
Program * program() const { return program_; }
|
Program * program() const { return program_; }
|
||||||
|
|
||||||
//! \~english Execute kernel
|
|
||||||
//! \~russian Выполнить ядро
|
|
||||||
//! \return true if successful
|
|
||||||
bool execute();
|
bool execute();
|
||||||
|
|
||||||
//! \~english Wait for execution to finish
|
|
||||||
//! \~russian Ждать завершения выполнения
|
|
||||||
void waitForFinish();
|
void waitForFinish();
|
||||||
|
|
||||||
//! \~english Set execution range (1D)
|
|
||||||
//! \~russian Установить диапазон выполнения (1D)
|
|
||||||
//! \param size Number of work items
|
|
||||||
void setExecuteRange(int size) { setExecuteRanges(PIVector<int>() << size); }
|
void setExecuteRange(int size) { setExecuteRanges(PIVector<int>() << size); }
|
||||||
|
|
||||||
//! \~english Set execution ranges (ND)
|
|
||||||
//! \~russian Установить диапазоны выполнения (ND)
|
|
||||||
//! \param ranges Array of sizes per dimension
|
|
||||||
void setExecuteRanges(const PIVector<int> & ranges);
|
void setExecuteRanges(const PIVector<int> & ranges);
|
||||||
|
|
||||||
//! \~english Get kernel name
|
|
||||||
//! \~russian Получить имя ядра
|
|
||||||
const PIString & name() const { return name_; }
|
const PIString & name() const { return name_; }
|
||||||
|
|
||||||
//! \~english Get kernel arguments
|
|
||||||
//! \~russian Получить аргументы ядра
|
|
||||||
const PIVector<KernelArg> & args() const { return args_; }
|
const PIVector<KernelArg> & args() const { return args_; }
|
||||||
|
|
||||||
//! \~english Set argument value by index
|
|
||||||
//! \~russian Установить значение аргумента по индексу
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool setArgValue(int index, const T & value) {
|
bool setArgValue(int index, const T & value) {
|
||||||
return setArgValueS(index, PIVariant::fromValue(value));
|
return setArgValueS(index, PIVariant::fromValue(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Set argument value by name
|
|
||||||
//! \~russian Установить значение аргумента по имени
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool setArgValue(const PIString & arg, const T & value) {
|
bool setArgValue(const PIString & arg, const T & value) {
|
||||||
return setArgValue(argIndex(arg), value);
|
return setArgValue(argIndex(arg), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Set variant argument value
|
|
||||||
//! \~russian Установить значение аргумента variant
|
|
||||||
bool setArgValue(const PIString & arg, const PIVariant & value) { return setArgValueS(argIndex(arg), value); }
|
bool setArgValue(const PIString & arg, const PIVariant & value) { return setArgValueS(argIndex(arg), value); }
|
||||||
|
|
||||||
//! \~english Bind buffer to argument
|
|
||||||
//! \~russian Привязать буфер к аргументу
|
|
||||||
bool bindArgValue(int index, Buffer * buffer);
|
bool bindArgValue(int index, Buffer * buffer);
|
||||||
|
|
||||||
//! \~english Bind buffer to argument by name
|
|
||||||
//! \~russian Привязать буфер к аргументу по имени
|
|
||||||
bool bindArgValue(const PIString & arg, Buffer * buffer) { return bindArgValue(argIndex(arg), buffer); }
|
bool bindArgValue(const PIString & arg, Buffer * buffer) { return bindArgValue(argIndex(arg), buffer); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -602,37 +321,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Initialize OpenCL
|
|
||||||
//! \~russian Инициализировать OpenCL
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
//! \~english Get available platforms
|
|
||||||
//! \~russian Получить доступные платформы
|
|
||||||
//! \return Vector of platforms
|
|
||||||
static const PIVector<Platform> & platforms();
|
static const PIVector<Platform> & platforms();
|
||||||
|
|
||||||
//! \~english Get all available devices
|
|
||||||
//! \~russian Получить все доступные устройства
|
|
||||||
//! \return Vector of devices
|
|
||||||
static const PIVector<Device> devices();
|
static const PIVector<Device> devices();
|
||||||
|
|
||||||
//! \~english Get device by ID
|
|
||||||
//! \~russian Получить устройство по ID
|
|
||||||
//! \param id Device handle
|
|
||||||
//! \return Device info
|
|
||||||
static Device deviceByID(void * id);
|
static Device deviceByID(void * id);
|
||||||
|
|
||||||
//! \~english Prepare program source
|
|
||||||
//! \~russian Подготовить исходный код программы
|
|
||||||
//! \param prog Program source
|
|
||||||
//! \return Prepared source
|
|
||||||
static PIString prepareProgram(const PIString & prog);
|
static PIString prepareProgram(const PIString & prog);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static PIString prog_header;
|
static PIString prog_header;
|
||||||
PIOpenCL() { ; }
|
PIOpenCL() { ; }
|
||||||
//! \~english Initialization helper
|
|
||||||
//! \~russian Помощник инициализации
|
|
||||||
class PIP_OPENCL_EXPORT Initializer {
|
class PIP_OPENCL_EXPORT Initializer {
|
||||||
public:
|
public:
|
||||||
Initializer();
|
Initializer();
|
||||||
@@ -644,8 +341,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Output stream operator for KernelArg
|
|
||||||
//! \~russian Оператор вывода в поток для KernelArg
|
|
||||||
PIP_OPENCL_EXPORT PICout operator<<(PICout s, const PIOpenCL::KernelArg & v);
|
PIP_OPENCL_EXPORT PICout operator<<(PICout s, const PIOpenCL::KernelArg & v);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,40 +17,6 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! \~english PIP - Platform Independent Primitives
|
|
||||||
//! \~russian PIP - Кроссплатформенные примитивы
|
|
||||||
//! \mainpage
|
|
||||||
//!
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Main include file for PIP library
|
|
||||||
//! \~russian Главный включаемый файл библиотеки PIP
|
|
||||||
//!
|
|
||||||
//! \~\details
|
|
||||||
//! \~english \section overview Overview
|
|
||||||
//! \~russian \section overview Обзор
|
|
||||||
//!
|
|
||||||
//! \~english
|
|
||||||
//! PIP is a C++ cross-platform library providing platform-independent abstractions for:
|
|
||||||
//! * Core/Types: Strings, variants, containers, datetime, networks
|
|
||||||
//! * Threading: Mutexes, semaphores, thread pools, timers
|
|
||||||
//! * I/O: Files, serial, CAN, GPIO, SPI, Ethernet
|
|
||||||
//! * Math: Vectors, matrices, FFT, quaternions
|
|
||||||
//! * Crypto: MD5, SHA, BLAKE2, SipHash
|
|
||||||
//! * Compression: zlib support
|
|
||||||
//! * HTTP: Client and server support
|
|
||||||
//! * Serialization: JSON, binary, XML
|
|
||||||
//!
|
|
||||||
//! \~russian
|
|
||||||
//! PIP - это кроссплатформенная C++ библиотека, предоставляющая платформонезависимые абстракции для:
|
|
||||||
//! * Ядро/Типы: Строки, варианты, контейнеры, дата/время, сети
|
|
||||||
//! * Потоки: Мьютексы, семафоры, пулы потоков, таймеры
|
|
||||||
//! * Ввод/Вывод: Файлы, последовательные порты, CAN, GPIO, SPI, Ethernet
|
|
||||||
//! * Математика: Векторы, матрицы, FFT, кватернионы
|
|
||||||
//! * Криптография: MD5, SHA, BLAKE2, SipHash
|
|
||||||
//! * Сжатие: Поддержка zlib
|
|
||||||
//! * HTTP: Клиент и сервер
|
|
||||||
//! * Сериализация: JSON, бинарная, XML
|
|
||||||
|
|
||||||
#ifndef PIP_H
|
#ifndef PIP_H
|
||||||
#define PIP_H
|
#define PIP_H
|
||||||
|
|
||||||
|
|||||||
@@ -22,15 +22,12 @@
|
|||||||
You should have received a copy of the GNU Lesser General Public License
|
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/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
//! \~english Resources subsystem
|
|
||||||
//! \~russian Подсистема ресурсов
|
|
||||||
//! \defgroup Resources Resources
|
//! \defgroup Resources Resources
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Resources subsystem
|
//! \~english Resources subsystem
|
||||||
//! \~russian Подсистема ресурсов
|
//! \~russian Подсистема ресурсов
|
||||||
//!
|
//!
|
||||||
//! \~\details
|
//! \~\details
|
||||||
//! \~
|
|
||||||
//! \~english \section cmake_module_Resources Building with CMake
|
//! \~english \section cmake_module_Resources Building with CMake
|
||||||
//! \~russian \section cmake_module_Resources Сборка с использованием CMake
|
//! \~russian \section cmake_module_Resources Сборка с использованием CMake
|
||||||
//!
|
//!
|
||||||
@@ -62,31 +59,18 @@
|
|||||||
|
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
//! \~english Macro for initializing compiled-in resources
|
#define INIT_RESOURCE(name) \
|
||||||
//! \~russian Макрос для инициализации вкомпиленных ресурсов
|
{ \
|
||||||
#define INIT_RESOURCE(name) \
|
extern void _pirc_##name##_init_(); \
|
||||||
{ \
|
_pirc_##name##_init_(); \
|
||||||
extern void _pirc_##name##_init_(); \
|
}
|
||||||
_pirc_##name##_init_(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \~english Class for accessing compiled-in resources
|
|
||||||
//! \~russian Класс для доступа к вкомпиленным ресурсам
|
|
||||||
class PIP_EXPORT PIResources {
|
class PIP_EXPORT PIResources {
|
||||||
public:
|
public:
|
||||||
//! \~english Get resource by section and name
|
//!
|
||||||
//! \~russian Получить ресурс по секции и имени
|
|
||||||
//! \details
|
|
||||||
//! \~english Searches for resource in specified section
|
|
||||||
//! \~russian Ищет ресурс в указанной секции
|
|
||||||
static PIByteArray get(const PIString & section, const PIString & name);
|
static PIByteArray get(const PIString & section, const PIString & name);
|
||||||
|
|
||||||
//! \~english Get resource by name (searches all sections)
|
|
||||||
//! \~russian Получить ресурс по имени (ищет во всех секциях)
|
|
||||||
static PIByteArray get(const PIString & name);
|
static PIByteArray get(const PIString & name);
|
||||||
|
|
||||||
//! \~english Dump all resources to console
|
|
||||||
//! \~russian Вывести все ресурсы в консоль
|
|
||||||
static void dump();
|
static void dump();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -17,13 +17,6 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! \~english Resources storage subsystem
|
|
||||||
//! \~russian Подсистема хранения ресурсов
|
|
||||||
//! \defgroup Resources Resources
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Resources storage subsystem
|
|
||||||
//! \~russian Подсистема хранения ресурсов
|
|
||||||
|
|
||||||
#ifndef PIRESOURCES_P_H
|
#ifndef PIRESOURCES_P_H
|
||||||
#define PIRESOURCES_P_H
|
#define PIRESOURCES_P_H
|
||||||
|
|
||||||
@@ -33,36 +26,17 @@
|
|||||||
|
|
||||||
class PIResources;
|
class PIResources;
|
||||||
|
|
||||||
//! \~english Storage for compiled-in resources
|
|
||||||
//! \~russian Хранилище вкомпиленных ресурсов
|
|
||||||
class PIP_EXPORT PIResourcesStorage {
|
class PIP_EXPORT PIResourcesStorage {
|
||||||
friend class PIResources;
|
friend class PIResources;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Get singleton instance
|
|
||||||
//! \~russian Получить синглтон
|
|
||||||
static PIResourcesStorage * instance();
|
static PIResourcesStorage * instance();
|
||||||
|
|
||||||
//! \~english Section containing resource entries
|
|
||||||
//! \~russian Секция, содержащая записи ресурсов
|
|
||||||
struct PIP_EXPORT Section {
|
struct PIP_EXPORT Section {
|
||||||
//! \~english Constructor
|
|
||||||
//! \~russian Конструктор
|
|
||||||
Section();
|
Section();
|
||||||
//! \~english Destructor
|
|
||||||
//! \~russian Деструктор
|
|
||||||
~Section();
|
~Section();
|
||||||
|
|
||||||
//! \~english Add another section to this one
|
|
||||||
//! \~russian Добавить другую секцию к этой
|
|
||||||
void add(const Section & s);
|
void add(const Section & s);
|
||||||
|
|
||||||
//! \~english Clear all entries
|
|
||||||
//! \~russian Очистить все записи
|
|
||||||
void purge();
|
void purge();
|
||||||
|
|
||||||
//! \~english Map of resource names to data
|
|
||||||
//! \~russian Карта имен ресурсов к данным
|
|
||||||
PIMap<PIString, PIByteArray *> entries;
|
PIMap<PIString, PIByteArray *> entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -82,65 +56,21 @@ public:
|
|||||||
size = si;
|
size = si;
|
||||||
flags = fl;
|
flags = fl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Section name
|
|
||||||
//! \~russian Имя секции
|
|
||||||
PIString section;
|
PIString section;
|
||||||
|
|
||||||
//! \~english Resource name
|
|
||||||
//! \~russian Имя ресурса
|
|
||||||
PIString name;
|
PIString name;
|
||||||
|
|
||||||
//! \~english Alias
|
|
||||||
//! \~russian Псевдоним
|
|
||||||
PIString alias;
|
PIString alias;
|
||||||
|
|
||||||
//! \~english Source file
|
|
||||||
//! \~russian Исходный файл
|
|
||||||
PIString file;
|
PIString file;
|
||||||
|
|
||||||
//! \~english Offset in file
|
|
||||||
//! \~russian Смещение в файле
|
|
||||||
llong offset;
|
llong offset;
|
||||||
|
|
||||||
//! \~english Size
|
|
||||||
//! \~russian Размер
|
|
||||||
llong size;
|
llong size;
|
||||||
|
|
||||||
//! \~english Flags
|
|
||||||
//! \~russian Флаги
|
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Register a section with data
|
|
||||||
//! \~russian Зарегистрировать секцию с данными
|
|
||||||
//! \param section_name Name of the section
|
|
||||||
//! \param data Section data
|
|
||||||
void registerSection(const PIString & section_name, const Section & data);
|
void registerSection(const PIString & section_name, const Section & data);
|
||||||
|
|
||||||
//! \~english Register from raw data
|
|
||||||
//! \~russian Зарегистрировать из сырых данных
|
|
||||||
//! \param rc_data Resource data
|
|
||||||
//! \param rc_desc Resource description
|
|
||||||
//! \param rc_desc_size Description size
|
|
||||||
void registerSection(const uchar * rc_data, const uchar * rc_desc, int rc_desc_size);
|
void registerSection(const uchar * rc_data, const uchar * rc_desc, int rc_desc_size);
|
||||||
|
|
||||||
//! \~english Get section by name
|
|
||||||
//! \~russian Получить секцию по имени
|
|
||||||
//! \param section_name Name of section
|
|
||||||
//! \return Pointer to section or nullptr
|
|
||||||
Section * section(const PIString & section_name) const;
|
Section * section(const PIString & section_name) const;
|
||||||
|
|
||||||
//! \~english Get resource by section and name
|
|
||||||
//! \~russian Получить ресурс по секции и имени
|
|
||||||
PIByteArray get(const PIString & section_name, const PIString & entry_name) const;
|
PIByteArray get(const PIString & section_name, const PIString & entry_name) const;
|
||||||
|
|
||||||
//! \~english Get resource by name (searches all sections)
|
|
||||||
//! \~russian Получить ресурс по имени (ищет во всех секциях)
|
|
||||||
PIByteArray get(const PIString & entry_name) const;
|
PIByteArray get(const PIString & entry_name) const;
|
||||||
|
|
||||||
//! \~english Clear all sections
|
|
||||||
//! \~russian Очистить все секции
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -31,16 +31,12 @@
|
|||||||
|
|
||||||
namespace PIStateMachineHelpers {
|
namespace PIStateMachineHelpers {
|
||||||
|
|
||||||
//! \~english Base class for function wrappers
|
|
||||||
//! \~russian Базовый класс для обёрток функций
|
|
||||||
class FunctionBase {
|
class FunctionBase {
|
||||||
public:
|
public:
|
||||||
virtual ~FunctionBase() {}
|
virtual ~FunctionBase() {}
|
||||||
virtual uint formatHash() = 0;
|
virtual uint formatHash() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Template class for function wrappers
|
|
||||||
//! \~russian Шаблонный класс для обёрток функций
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
class Function: public FunctionBase {
|
class Function: public FunctionBase {
|
||||||
public:
|
public:
|
||||||
@@ -51,8 +47,6 @@ public:
|
|||||||
std::function<bool(Args...)> func;
|
std::function<bool(Args...)> func;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Creates function wrapper from std::function
|
|
||||||
//! \~russian Создает обёртку функции из std::function
|
|
||||||
template<typename Ret, typename... Args>
|
template<typename Ret, typename... Args>
|
||||||
FunctionBase * makeFunction(std::function<Ret(Args...)> func) {
|
FunctionBase * makeFunction(std::function<Ret(Args...)> func) {
|
||||||
auto * ret = new Function<Args...>();
|
auto * ret = new Function<Args...>();
|
||||||
|
|||||||
@@ -31,117 +31,50 @@
|
|||||||
#include "pisystemtime.h"
|
#include "pisystemtime.h"
|
||||||
|
|
||||||
|
|
||||||
//! \~english Base class for state machine states
|
//! \ingroup StateMachine
|
||||||
//! \~russian Базовый класс для состояний машины состояний
|
//! \~\brief
|
||||||
|
//! \~english
|
||||||
|
//! \~russian
|
||||||
class PIP_EXPORT PIStateBase {
|
class PIP_EXPORT PIStateBase {
|
||||||
friend class PIStateMachine;
|
friend class PIStateMachine;
|
||||||
friend class PITransitionBase;
|
friend class PITransitionBase;
|
||||||
friend class PIStateFinal;
|
friend class PIStateFinal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Creates state with name
|
|
||||||
//! \~russian Создает состояние с именем
|
|
||||||
PIStateBase(const PIString & n = {}): name_(n) { ; }
|
PIStateBase(const PIString & n = {}): name_(n) { ; }
|
||||||
virtual ~PIStateBase();
|
virtual ~PIStateBase();
|
||||||
|
|
||||||
//! \~english Called when state is \~russian Вы entered
|
|
||||||
//! зывается при входе в состояние
|
|
||||||
virtual void onEnter() {}
|
virtual void onEnter() {}
|
||||||
|
|
||||||
//! \~english Called when state is exited
|
|
||||||
//! \~russian Вызывается при выходе из состояния
|
|
||||||
virtual void onExit() {}
|
virtual void onExit() {}
|
||||||
|
|
||||||
//! \~english Called when state machine finishes (for final states)
|
|
||||||
//! \~russian Вызывается при завершении машины состояний (для финальных состояний)
|
|
||||||
virtual void onFinish() {}
|
virtual void onFinish() {}
|
||||||
|
|
||||||
//! \~english Returns state machine this state belongs to
|
|
||||||
//! \~russian Возвращает машину состояний, которой принадлежит это состояние
|
|
||||||
PIStateMachine * machine() const { return root; }
|
PIStateMachine * machine() const { return root; }
|
||||||
|
|
||||||
//! \~english Returns parent state
|
|
||||||
//! \~russian Возвращает родительское состояние
|
|
||||||
PIStateBase * parent() const { return parent_state; }
|
PIStateBase * parent() const { return parent_state; }
|
||||||
|
|
||||||
//! \~english Returns active child state
|
|
||||||
//! \~russian Возвращает активное дочернее состояние
|
|
||||||
PIStateBase * activeChild() const { return active_state; }
|
PIStateBase * activeChild() const { return active_state; }
|
||||||
|
|
||||||
//! \~english Returns all active child states
|
|
||||||
//! \~russian Возвращает все активные дочерние состояния
|
|
||||||
PIVector<PIStateBase *> activeChildren() const;
|
PIVector<PIStateBase *> activeChildren() const;
|
||||||
|
|
||||||
//! \~english Returns all active atomic states
|
|
||||||
//! \~russian Возвращает все активные атомарные состояния
|
|
||||||
PIVector<PIStateBase *> activeAtomics() const;
|
PIVector<PIStateBase *> activeAtomics() const;
|
||||||
|
|
||||||
//! \~english Adds child state
|
|
||||||
//! \~russian Добавляет дочернее состояние
|
|
||||||
void addState(PIStateBase * s);
|
void addState(PIStateBase * s);
|
||||||
|
|
||||||
//! \~english Adds multiple child states
|
|
||||||
//! \~russian Добавляет несколько дочерних состояний
|
|
||||||
void addStates(PIVector<PIStateBase *> s);
|
void addStates(PIVector<PIStateBase *> s);
|
||||||
|
|
||||||
//! \~english Sets initial state for compound state
|
|
||||||
//! \~russian Устанавливает начальное состояние для составного состояния
|
|
||||||
void setInitialState(PIStateBase * s);
|
void setInitialState(PIStateBase * s);
|
||||||
|
|
||||||
//! \~english Adds transition to target state on event
|
|
||||||
//! \~russian Добавляет переход к целевому состоянию по событию
|
|
||||||
PITransitionBase * addTransition(PIStateBase * target, int event_id);
|
PITransitionBase * addTransition(PIStateBase * target, int event_id);
|
||||||
|
|
||||||
//! \~english Adds timeout transition to target state
|
|
||||||
//! \~russian Добавляет переход по таймауту к целевому состоянию
|
|
||||||
PITransitionTimeout * addTimeoutTransition(PIStateBase * target, PISystemTime timeout);
|
PITransitionTimeout * addTimeoutTransition(PIStateBase * target, PISystemTime timeout);
|
||||||
|
|
||||||
//! \~english Sets parallel mode for state
|
|
||||||
//! \~russian Устанавливает параллельный режим для состояния
|
|
||||||
void setParallel(bool yes) { is_parallel = yes; }
|
void setParallel(bool yes) { is_parallel = yes; }
|
||||||
|
|
||||||
//! \~english Returns state name
|
|
||||||
//! \~russian Возвращает имя состояния
|
|
||||||
const PIString & getName() const { return name_; }
|
const PIString & getName() const { return name_; }
|
||||||
|
|
||||||
//! \~english Checks if this is root state machine
|
|
||||||
//! \~russian Проверяет является ли это корневой машиной состояний
|
|
||||||
bool isStateMachine() const { return is_root; }
|
bool isStateMachine() const { return is_root; }
|
||||||
|
|
||||||
//! \~english Checks if state is active
|
|
||||||
//! \~russian Проверяет активно ли состояние
|
|
||||||
bool isActive() const { return is_active; }
|
bool isActive() const { return is_active; }
|
||||||
|
|
||||||
//! \~english Checks if state is in parallel mode
|
|
||||||
//! \~russian Проверяет находится ли состояние в параллельном режиме
|
|
||||||
bool isParallel() const { return is_parallel; }
|
bool isParallel() const { return is_parallel; }
|
||||||
|
|
||||||
//! \~english Checks if state is final
|
|
||||||
//! \~russian Проверяет является ли состояние финальным
|
|
||||||
bool isFinal() const { return is_final; }
|
bool isFinal() const { return is_final; }
|
||||||
|
|
||||||
//! \~english Checks if state is atomic (no children)
|
|
||||||
//! \~russian Проверяет является ли состояние атомарным (нет потомков)
|
|
||||||
bool isAtomic() const { return children.isEmpty(); }
|
bool isAtomic() const { return children.isEmpty(); }
|
||||||
|
|
||||||
//! \~english Checks if state is compound (has children)
|
|
||||||
//! \~russian Проверяет является ли состояние составным (есть потомки)
|
|
||||||
bool isCompound() const { return children.isNotEmpty(); }
|
bool isCompound() const { return children.isNotEmpty(); }
|
||||||
|
|
||||||
//! \~english Returns child states
|
|
||||||
//! \~russian Возвращает дочерние состояния
|
|
||||||
const PIVector<PIStateBase *> & getChildren() const { return children; }
|
const PIVector<PIStateBase *> & getChildren() const { return children; }
|
||||||
|
|
||||||
//! \~english Returns transitions from this state
|
|
||||||
//! \~russian Возвращает переходы из этого состояния
|
|
||||||
const PIVector<PITransitionBase *> & getTransitions() const { return transitions; }
|
const PIVector<PITransitionBase *> & getTransitions() const { return transitions; }
|
||||||
|
|
||||||
//! \~english Prints state tree to string
|
|
||||||
//! \~russian Выводит дерево состояний в строку
|
|
||||||
void print(PIString prefix = {});
|
void print(PIString prefix = {});
|
||||||
|
|
||||||
//! \~english Returns all states in machine
|
|
||||||
//! \~russian Возвращает все состояния в машине
|
|
||||||
PIVector<PIStateBase *> gatherStates();
|
PIVector<PIStateBase *> gatherStates();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -167,12 +100,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english State with lambda callbacks
|
|
||||||
//! \~russian Состояние с lambda коллбэками
|
|
||||||
class PIP_EXPORT PIStateLambda: public PIStateBase {
|
class PIP_EXPORT PIStateLambda: public PIStateBase {
|
||||||
public:
|
public:
|
||||||
//! \~english Creates lambda state with callbacks
|
|
||||||
//! \~russian Создает lambda состояние с коллбэками
|
|
||||||
PIStateLambda(std::function<void()> on_enter, std::function<void()> on_exit = nullptr, const PIString & n = {}): PIStateBase(n) {
|
PIStateLambda(std::function<void()> on_enter, std::function<void()> on_exit = nullptr, const PIString & n = {}): PIStateBase(n) {
|
||||||
enter = on_enter;
|
enter = on_enter;
|
||||||
exit = on_exit;
|
exit = on_exit;
|
||||||
@@ -189,12 +118,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Final state of state machine
|
|
||||||
//! \~russian Финальное состояние машины состояний
|
|
||||||
class PIP_EXPORT PIStateFinal: public PIStateBase {
|
class PIP_EXPORT PIStateFinal: public PIStateBase {
|
||||||
public:
|
public:
|
||||||
//! \~english Creates final state with finish callback
|
|
||||||
//! \~russian Создает финальное состояние с коллбэком завершения
|
|
||||||
PIStateFinal(std::function<void()> on_finish = nullptr, const PIString & n = {}): PIStateBase(n) {
|
PIStateFinal(std::function<void()> on_finish = nullptr, const PIString & n = {}): PIStateBase(n) {
|
||||||
is_final = true;
|
is_final = true;
|
||||||
enter = on_finish;
|
enter = on_finish;
|
||||||
|
|||||||
@@ -30,32 +30,22 @@
|
|||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
|
|
||||||
|
|
||||||
//! \~english Base class for state machine transitions
|
//! \ingroup StateMachine
|
||||||
//! \~russian Базовый класс для переходов машины состояний
|
//! \~\brief
|
||||||
|
//! \~english
|
||||||
|
//! \~russian
|
||||||
class PIP_EXPORT PITransitionBase {
|
class PIP_EXPORT PITransitionBase {
|
||||||
friend class PIStateMachine;
|
friend class PIStateMachine;
|
||||||
friend class PIStateBase;
|
friend class PIStateBase;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Creates transition from source to target on event
|
|
||||||
//! \~russian Создает переход от source к target по событию
|
|
||||||
PITransitionBase(PIStateBase * source, PIStateBase * target, int event_id);
|
PITransitionBase(PIStateBase * source, PIStateBase * target, int event_id);
|
||||||
virtual ~PITransitionBase();
|
virtual ~PITransitionBase();
|
||||||
|
|
||||||
//! \~english Returns state machine this transition belongs to
|
|
||||||
//! \~russian Возвращает машину состояний, которой принадлежит этот переход
|
|
||||||
PIStateMachine * machine() const { return root; }
|
PIStateMachine * machine() const { return root; }
|
||||||
|
|
||||||
//! \~english Returns source state
|
|
||||||
//! \~russian Возвращает исходное состояние
|
|
||||||
PIStateBase * source() const { return source_state; }
|
PIStateBase * source() const { return source_state; }
|
||||||
|
|
||||||
//! \~english Returns target state
|
|
||||||
//! \~russian Возвращает целевое состояние
|
|
||||||
PIStateBase * target() const { return target_state; }
|
PIStateBase * target() const { return target_state; }
|
||||||
|
|
||||||
//! \~english Adds guard function to transition
|
|
||||||
//! \~russian Добавляет сторожевую функцию к переходу
|
|
||||||
template<typename R, typename... Args>
|
template<typename R, typename... Args>
|
||||||
PITransitionBase * addGuard(std::function<R(Args...)> f) {
|
PITransitionBase * addGuard(std::function<R(Args...)> f) {
|
||||||
static_assert(std::is_same<R, bool>::value, "guard function should return bool!");
|
static_assert(std::is_same<R, bool>::value, "guard function should return bool!");
|
||||||
@@ -64,15 +54,11 @@ public:
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Adds guard function to transition (callable)
|
|
||||||
//! \~russian Добавляет сторожевую функцию к переходу (callable)
|
|
||||||
template<typename L>
|
template<typename L>
|
||||||
PITransitionBase * addGuard(L f) {
|
PITransitionBase * addGuard(L f) {
|
||||||
return addGuard(toStdFunction(f));
|
return addGuard(toStdFunction(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Tests guard function with arguments
|
|
||||||
//! \~russian Тестирует сторожевую функцию с аргументами
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
bool testGuard(Args... args) {
|
bool testGuard(Args... args) {
|
||||||
if (!guard) return true;
|
if (!guard) return true;
|
||||||
@@ -83,25 +69,13 @@ public:
|
|||||||
return reinterpret_cast<PIStateMachineHelpers::Function<Args...> *>(guard)->func(args...);
|
return reinterpret_cast<PIStateMachineHelpers::Function<Args...> *>(guard)->func(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Adds action to transition
|
|
||||||
//! \~russian Добавляет действие к переходу
|
|
||||||
PITransitionBase * addAction(std::function<void()> a);
|
PITransitionBase * addAction(std::function<void()> a);
|
||||||
|
|
||||||
//! \~english Executes transition action
|
|
||||||
//! \~russian Выполняет действие перехода
|
|
||||||
void makeAction();
|
void makeAction();
|
||||||
|
|
||||||
//! \~english Triggers transition
|
|
||||||
//! \~russian Запускает переход
|
|
||||||
void trigger();
|
void trigger();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \~english Called when transition becomes enabled
|
|
||||||
//! \~russian Вызывается когда переход становится доступным
|
|
||||||
virtual void enabled() {}
|
virtual void enabled() {}
|
||||||
|
|
||||||
//! \~english Called when transition becomes disabled
|
|
||||||
//! \~russian Вызывается когда переход становится недоступным
|
|
||||||
virtual void disabled() {}
|
virtual void disabled() {}
|
||||||
|
|
||||||
int eventID = 0;
|
int eventID = 0;
|
||||||
@@ -112,12 +86,8 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \~english Timeout transition
|
|
||||||
//! \~russian Переход по таймауту
|
|
||||||
class PIP_EXPORT PITransitionTimeout: public PITransitionBase {
|
class PIP_EXPORT PITransitionTimeout: public PITransitionBase {
|
||||||
public:
|
public:
|
||||||
//! \~english Creates timeout transition
|
|
||||||
//! \~russian Создает переход по таймауту
|
|
||||||
PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout);
|
PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout);
|
||||||
~PITransitionTimeout();
|
~PITransitionTimeout();
|
||||||
|
|
||||||
|
|||||||
@@ -342,12 +342,12 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
|||||||
|
|
||||||
PIDir hid_dir("/sys/bus/hid/devices"_a);
|
PIDir hid_dir("/sys/bus/hid/devices"_a);
|
||||||
auto hid_devs = hid_dir.entries();
|
auto hid_devs = hid_dir.entries();
|
||||||
for (auto hd: hid_devs) {
|
for (const auto & hd: hid_devs) {
|
||||||
// piCout << d.path;
|
// piCout << d.path;
|
||||||
if (!isDir(hd)) continue;
|
if (!isDir(hd)) continue;
|
||||||
PIDir dir_input(hd.path + "/input"_a);
|
PIDir dir_input(hd.path + "/input"_a);
|
||||||
auto hid_inputs = dir_input.entries();
|
auto hid_inputs = dir_input.entries();
|
||||||
for (auto hd_i: hid_inputs) {
|
for (const auto & hd_i: hid_inputs) {
|
||||||
if (!isDir(hd_i)) continue;
|
if (!isDir(hd_i)) continue;
|
||||||
// now in /sys/bus/hid/devices/<dev>/input/input<N>
|
// now in /sys/bus/hid/devices/<dev>/input/input<N>
|
||||||
// piCout << hd_i.path;
|
// piCout << hd_i.path;
|
||||||
@@ -364,7 +364,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
|||||||
PIDir dir_e(hd_i.path);
|
PIDir dir_e(hd_i.path);
|
||||||
PIStringList devs;
|
PIStringList devs;
|
||||||
auto dl_e = dir_e.entries();
|
auto dl_e = dir_e.entries();
|
||||||
for (auto d_e: dl_e) {
|
for (const auto & d_e: dl_e) {
|
||||||
if (!d_e.isDir() || d_e.flags[PIFile::FileInfo::Dot] || d_e.flags[PIFile::FileInfo::DotDot]) continue;
|
if (!d_e.isDir() || d_e.flags[PIFile::FileInfo::Dot] || d_e.flags[PIFile::FileInfo::DotDot]) continue;
|
||||||
devs << d_e.name();
|
devs << d_e.name();
|
||||||
}
|
}
|
||||||
@@ -392,7 +392,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
|
|||||||
if (test_f.isClosed()) continue;
|
if (test_f.isClosed()) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ullong ev = readFile(hd_i.path + "/capabilities/ev"_a).toULLong(16);
|
// ullong ev = readFile(hd_i.path + "/capabilities/ev"_a).toULLong(16);
|
||||||
|
|
||||||
auto readAxes = [readFile, checkBit, &hd_i, &dev](const PIString & file, bool is_relative) {
|
auto readAxes = [readFile, checkBit, &hd_i, &dev](const PIString & file, bool is_relative) {
|
||||||
PIVector<PIHIDeviceInfo::AxisInfo> ret;
|
PIVector<PIHIDeviceInfo::AxisInfo> ret;
|
||||||
|
|||||||
@@ -29,98 +29,37 @@
|
|||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
|
|
||||||
|
|
||||||
//! \~english HID device information
|
|
||||||
//! \~russian Информация об HID устройстве
|
|
||||||
struct PIP_EXPORT PIHIDeviceInfo {
|
struct PIP_EXPORT PIHIDeviceInfo {
|
||||||
friend class PIHIDevice;
|
friend class PIHIDevice;
|
||||||
|
|
||||||
//! \~english Base class for value info
|
|
||||||
//! \~russian Базовый класс для информации о значении
|
|
||||||
struct PIP_EXPORT ValueInfoBase {
|
struct PIP_EXPORT ValueInfoBase {
|
||||||
//! \~english Checks if info is valid
|
|
||||||
//! \~russian Проверяет валидна ли информация
|
|
||||||
bool isValid() const { return index >= 0; }
|
bool isValid() const { return index >= 0; }
|
||||||
int index = -1;
|
int index = -1;
|
||||||
int data_index = -1;
|
int data_index = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Axis information
|
|
||||||
//! \~russian Информация об оси
|
|
||||||
struct PIP_EXPORT AxisInfo: public ValueInfoBase {
|
struct PIP_EXPORT AxisInfo: public ValueInfoBase {
|
||||||
int bits = 0;
|
int bits = 0;
|
||||||
int min = 0;
|
int min = 0;
|
||||||
int max = 1;
|
int max = 1;
|
||||||
bool is_relative = false;
|
bool is_relative = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Button information
|
|
||||||
//! \~russian Информация о кнопке
|
|
||||||
struct PIP_EXPORT ButtonInfo: public ValueInfoBase {
|
struct PIP_EXPORT ButtonInfo: public ValueInfoBase {
|
||||||
int code = 0;
|
int code = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Device path
|
|
||||||
//! \~russian Путь к устройству
|
|
||||||
PIString path;
|
PIString path;
|
||||||
|
|
||||||
//! \~english Manufacturer name
|
|
||||||
//! \~russian Имя производителя
|
|
||||||
PIString manufacturer;
|
PIString manufacturer;
|
||||||
|
|
||||||
//! \~english Product name
|
|
||||||
//! \~russian Название продукта
|
|
||||||
PIString product;
|
PIString product;
|
||||||
|
|
||||||
//! \~english Serial number
|
|
||||||
//! \~russian Серийный номер
|
|
||||||
PIString serial;
|
PIString serial;
|
||||||
|
|
||||||
//! \~english Version
|
|
||||||
//! \~russian Версия
|
|
||||||
PIString version;
|
PIString version;
|
||||||
|
|
||||||
//! \~english Vendor ID
|
|
||||||
//! \~russian Идентификатор производителя
|
|
||||||
PIString VID;
|
PIString VID;
|
||||||
|
|
||||||
//! \~english Product ID
|
|
||||||
//! \~russian Идентификатор продукта
|
|
||||||
PIString PID;
|
PIString PID;
|
||||||
|
|
||||||
//! \~english List of axes
|
|
||||||
//! \~russian Список осей
|
|
||||||
PIVector<AxisInfo> axes;
|
PIVector<AxisInfo> axes;
|
||||||
|
|
||||||
//! \~english List of buttons
|
|
||||||
//! \~russian Список кнопок
|
|
||||||
PIVector<ButtonInfo> buttons;
|
PIVector<ButtonInfo> buttons;
|
||||||
|
|
||||||
//! \~english Checks if info is null
|
|
||||||
//! \~russian Проверяет является ли информация пустой
|
|
||||||
bool isNull() const { return path.isEmpty(); }
|
bool isNull() const { return path.isEmpty(); }
|
||||||
|
|
||||||
//! \~english Checks if info is not null
|
|
||||||
//! \~russian Проверяет является ли информация не пустой
|
|
||||||
bool isNotNull() const { return !isNull(); }
|
bool isNotNull() const { return !isNull(); }
|
||||||
|
|
||||||
//! \~english Matches device by string
|
|
||||||
//! \~russian Сопоставляет устройство по строке
|
|
||||||
bool match(const PIString & str) const;
|
bool match(const PIString & str) const;
|
||||||
|
|
||||||
//! \~english Returns axes count
|
|
||||||
//! \~russian Возвращает количество осей
|
|
||||||
int axesCount() const { return axes.size_s(); }
|
int axesCount() const { return axes.size_s(); }
|
||||||
|
|
||||||
//! \~english Returns absolute axes count
|
|
||||||
//! \~russian Возвращает количество абсолютных осей
|
|
||||||
int axesAbsoluteCount() const;
|
int axesAbsoluteCount() const;
|
||||||
|
|
||||||
//! \~english Returns relative axes count
|
|
||||||
//! \~russian Возвращает количество относительных осей
|
|
||||||
int axesRelativeCount() const;
|
int axesRelativeCount() const;
|
||||||
|
|
||||||
//! \~english Returns buttons count
|
|
||||||
//! \~russian Возвращает количество кнопок
|
|
||||||
int buttonsCount() const { return buttons.size_s(); }
|
int buttonsCount() const { return buttons.size_s(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -135,19 +74,13 @@ private:
|
|||||||
PIP_EXPORT PICout operator<<(PICout s, const PIHIDeviceInfo & v);
|
PIP_EXPORT PICout operator<<(PICout s, const PIHIDeviceInfo & v);
|
||||||
|
|
||||||
|
|
||||||
//! \~english HID device
|
|
||||||
//! \~russian HID устройство
|
|
||||||
class PIP_EXPORT PIHIDevice: public PIThread {
|
class PIP_EXPORT PIHIDevice: public PIThread {
|
||||||
PIOBJECT_SUBCLASS(PIHIDevice, PIThread)
|
PIOBJECT_SUBCLASS(PIHIDevice, PIThread)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~PIHIDevice();
|
~PIHIDevice();
|
||||||
|
|
||||||
//! \~english HID event
|
|
||||||
//! \~russian Событие HID
|
|
||||||
struct PIP_EXPORT Event {
|
struct PIP_EXPORT Event {
|
||||||
//! \~english Event type
|
|
||||||
//! \~russian Тип события
|
|
||||||
enum Type {
|
enum Type {
|
||||||
tNone,
|
tNone,
|
||||||
tButton,
|
tButton,
|
||||||
@@ -159,48 +92,19 @@ public:
|
|||||||
float value = 0.;
|
float value = 0.;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Checks if device is opened
|
|
||||||
//! \~russian Проверяет открыто ли устройство
|
|
||||||
bool isOpened() const;
|
bool isOpened() const;
|
||||||
|
|
||||||
//! \~english Opens device by info
|
|
||||||
//! \~russian Открывает устройство по информации
|
|
||||||
bool open(const PIHIDeviceInfo & device);
|
bool open(const PIHIDeviceInfo & device);
|
||||||
|
|
||||||
//! \~english Opens device
|
|
||||||
//! \~russian Открывает устройство
|
|
||||||
bool open();
|
bool open();
|
||||||
|
|
||||||
//! \~english Closes device
|
|
||||||
//! \~russian Закрывает устройство
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
//! \~english Starts reading device
|
|
||||||
//! \~russian Начинает чтение устройства
|
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
//! \~english Stops reading device
|
|
||||||
//! \~russian Останавливает чтение устройства
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
//! \~english Sets dead zone for axes
|
|
||||||
//! \~russian Устанавливает мёртвую зону для осей
|
|
||||||
void setDeadZone(float v) { dead_zone = v; }
|
void setDeadZone(float v) { dead_zone = v; }
|
||||||
|
|
||||||
//! \~english Returns dead zone
|
|
||||||
//! \~russian Возвращает мёртвую зону
|
|
||||||
float deadZone() const { return dead_zone; }
|
float deadZone() const { return dead_zone; }
|
||||||
|
|
||||||
//! \~english Event fired on device event
|
|
||||||
//! \~russian Событие при событии устройства
|
|
||||||
EVENT1(event, PIHIDevice::Event, e);
|
EVENT1(event, PIHIDevice::Event, e);
|
||||||
|
|
||||||
//! \~english Returns all available HID devices
|
|
||||||
//! \~russian Возвращает все доступные HID устройства
|
|
||||||
static PIVector<PIHIDeviceInfo> allDevices(bool try_open = true);
|
static PIVector<PIHIDeviceInfo> allDevices(bool try_open = true);
|
||||||
|
|
||||||
//! \~english Finds device by name
|
|
||||||
//! \~russian Находит устройство по имени
|
|
||||||
static PIHIDeviceInfo findDevice(const PIString & name);
|
static PIHIDeviceInfo findDevice(const PIString & name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -30,54 +30,36 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
//! \~english System signals handler
|
|
||||||
//! \~russian Обработчик системных сигналов
|
|
||||||
class PIP_EXPORT PISignals {
|
class PIP_EXPORT PISignals {
|
||||||
public:
|
public:
|
||||||
//! \~english Signal types
|
|
||||||
//! \~russian Типы сигналов
|
|
||||||
enum Signal {
|
enum Signal {
|
||||||
Interrupt = 0x01, //!< Interrupt from keyboard
|
Interrupt /** Interrupt from keyboard */ = 0x01, // Term Interrupt from keyboard
|
||||||
Illegal = 0x02, //!< Illegal Instruction
|
Illegal /** Illegal Instruction */ = 0x02, // Core Illegal Instruction
|
||||||
Abort = 0x04, //!< Abort signal
|
Abort /** Abort signal */ = 0x04, // Core Abort signal from abort
|
||||||
FPE = 0x08, //!< Floating point exception
|
FPE /** Floating point exception */ = 0x08, // Core Floating point exception
|
||||||
SegFault = 0x10, //!< Invalid memory reference
|
SegFault /** Invalid memory reference */ = 0x10, // Core Invalid memory reference
|
||||||
Termination = 0x20, //!< Termination signal
|
Termination /** Termination signal */ = 0x20, // Term Termination signal
|
||||||
Hangup = 0x40, //!< Hangup detected
|
Hangup = 0x40, // Term Hangup detected on controlling terminal or death of controlling process
|
||||||
Quit = 0x80, //!< Quit from keyboard
|
Quit = 0x80, // Core Quit from keyboard
|
||||||
Kill = 0x100, //!< Kill signal
|
Kill = 0x100, // Term Kill signal
|
||||||
BrokenPipe = 0x200, //!< Broken pipe
|
BrokenPipe = 0x200, // Term Broken pipe: write to pipe with no readers
|
||||||
Timer = 0x400, //!< Timer signal
|
Timer = 0x400, // Term Timer signal from alarm
|
||||||
UserDefined1 = 0x800, //!< User-defined signal 1
|
UserDefined1 = 0x800, // Term User-defined signal 1
|
||||||
UserDefined2 = 0x1000, //!< User-defined signal 2
|
UserDefined2 = 0x1000, // Term User-defined signal 2
|
||||||
ChildStopped = 0x2000, //!< Child stopped or terminated
|
ChildStopped = 0x2000, // Ign Child stopped or terminated
|
||||||
Continue = 0x4000, //!< Continue if stopped
|
Continue = 0x4000, // Cont Continue if stopped
|
||||||
StopProcess = 0x8000, //!< Stop process
|
StopProcess = 0x8000, // Stop Stop process
|
||||||
StopTTY = 0x10000, //!< Stop typed at tty
|
StopTTY = 0x10000, // Stop Stop typed at tty
|
||||||
StopTTYInput = 0x20000, //!< Stop tty input
|
StopTTYInput = 0x20000, // Stop tty input for background process
|
||||||
StopTTYOutput = 0x40000, //!< Stop tty output
|
StopTTYOutput = 0x40000, // Stop tty output for background process
|
||||||
All = 0xFFFFF //!< All signals
|
All = 0xFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Signal handler callback type
|
|
||||||
//! \~russian Тип коллбэка обработчика сигналов
|
|
||||||
//! \note slot is any function with format "void(PISignals::Signal)"
|
|
||||||
typedef std::function<void(PISignals::Signal)> SignalEvent;
|
typedef std::function<void(PISignals::Signal)> SignalEvent;
|
||||||
|
// slot is any function format "void(PISignals::Signal)"
|
||||||
//! \~english Sets signal handler callback
|
|
||||||
//! \~russian Устанавливает коллбэк обработчика сигналов
|
|
||||||
static void setSlot(SignalEvent slot) { ret_func = slot; }
|
static void setSlot(SignalEvent slot) { ret_func = slot; }
|
||||||
|
|
||||||
//! \~english Grabs specified signals
|
|
||||||
//! \~russian Перехватывает указанные сигналы
|
|
||||||
static void grabSignals(PIFlags<PISignals::Signal> signals_);
|
static void grabSignals(PIFlags<PISignals::Signal> signals_);
|
||||||
|
|
||||||
//! \~english Releases specified signals
|
|
||||||
//! \~russian Освобождает указанные сигналы
|
|
||||||
static void releaseSignals(PIFlags<PISignals::Signal> signals_);
|
static void releaseSignals(PIFlags<PISignals::Signal> signals_);
|
||||||
|
|
||||||
//! \~english Raises signal
|
|
||||||
//! \~russian Генерирует сигнал
|
|
||||||
static void raiseSignal(PISignals::Signal signal);
|
static void raiseSignal(PISignals::Signal signal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -35,25 +35,25 @@
|
|||||||
//! \~russian Класс C-строки.
|
//! \~russian Класс C-строки.
|
||||||
class PIP_EXPORT PIConstChars {
|
class PIP_EXPORT PIConstChars {
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs an null string.
|
//! \~english Contructs an null string.
|
||||||
//! \~russian Создает нулевую строку.
|
//! \~russian Создает нулевую строку.
|
||||||
PIConstChars() {}
|
PIConstChars() {}
|
||||||
|
|
||||||
//! \~english Constructs string from C-string "string".
|
//! \~english Contructs string from C-string "string".
|
||||||
//! \~russian Создает строку из C-строки "string".
|
//! \~russian Создает строку из C-строки "string".
|
||||||
PIConstChars(const char * string) {
|
PIConstChars(const char * string) {
|
||||||
str = string;
|
str = string;
|
||||||
len = strlen(string);
|
len = strlen(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Constructs string from "size" characters of buffer "data".
|
//! \~english Contructs string from "size" characters of buffer "data".
|
||||||
//! \~russian Создает строку из "size" символов массива "data".
|
//! \~russian Создает строку из "size" символов массива "data".
|
||||||
PIConstChars(const char * data, size_t size) {
|
PIConstChars(const char * data, size_t size) {
|
||||||
str = data;
|
str = data;
|
||||||
len = size;
|
len = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Constructs a copy of string.
|
//! \~english Contructs a copy of string.
|
||||||
//! \~russian Создает копию строки.
|
//! \~russian Создает копию строки.
|
||||||
PIConstChars(const PIConstChars & o) {
|
PIConstChars(const PIConstChars & o) {
|
||||||
str = o.str;
|
str = o.str;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public:
|
|||||||
typedef const PIChar & const_reference;
|
typedef const PIChar & const_reference;
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
|
|
||||||
//! \~english Constructs an empty string.
|
//! \~english Contructs an empty string.
|
||||||
//! \~russian Создает пустую строку.
|
//! \~russian Создает пустую строку.
|
||||||
PIString() {}
|
PIString() {}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ public:
|
|||||||
PIString & operator+=(llong) = delete;
|
PIString & operator+=(llong) = delete;
|
||||||
PIString & operator+=(ullong) = delete;
|
PIString & operator+=(ullong) = delete;
|
||||||
|
|
||||||
//! \~english Constructs a copy of string.
|
//! \~english Contructs a copy of string.
|
||||||
//! \~russian Создает копию строки.
|
//! \~russian Создает копию строки.
|
||||||
PIString(const PIString & o) {
|
PIString(const PIString & o) {
|
||||||
d = o.d;
|
d = o.d;
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
//! \file piblockingqueue.h
|
/*! \file piblockingqueue.h
|
||||||
//! \ingroup Thread
|
* \ingroup Thread
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Queue with blocking
|
* \~english Queue with blocking
|
||||||
//! \~russian Блокирующая очередь
|
* \~russian Блокирующая очередь
|
||||||
//!
|
*/
|
||||||
//! \details
|
|
||||||
//! \~english Thread-safe queue that supports blocking operations - waits for space when storing and waits for element when retrieving.
|
|
||||||
//! \~russian Потокобезопасная очередь с поддержкой блокирующих операций - ожидает место при добавлении и ожидает элемент при получении.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
|
|
||||||
@@ -36,13 +33,12 @@
|
|||||||
* \brief A Queue that supports operations that wait for the queue to become non-empty when retrieving an element, and
|
* \brief A Queue that supports operations that wait for the queue to become non-empty when retrieving an element, and
|
||||||
* wait for space to become available in the queue when storing an element.
|
* wait for space to become available in the queue when storing an element.
|
||||||
*/
|
*/
|
||||||
//! \~english Thread-safe blocking queue template class
|
|
||||||
//! \~russian Шаблонный класс потокобезопасной блокирующей очереди
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class PIBlockingQueue: private PIQueue<T> {
|
class PIBlockingQueue: private PIQueue<T> {
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs queue with specified capacity
|
/**
|
||||||
//! \~russian Создает очередь с указанной емкостью
|
* \brief Constructor
|
||||||
|
*/
|
||||||
explicit inline PIBlockingQueue(size_t capacity = SIZE_MAX,
|
explicit inline PIBlockingQueue(size_t capacity = SIZE_MAX,
|
||||||
PIConditionVariable * cond_var_add = new PIConditionVariable(),
|
PIConditionVariable * cond_var_add = new PIConditionVariable(),
|
||||||
PIConditionVariable * cond_var_rem = new PIConditionVariable())
|
PIConditionVariable * cond_var_rem = new PIConditionVariable())
|
||||||
@@ -50,8 +46,9 @@ public:
|
|||||||
, cond_var_rem(cond_var_rem)
|
, cond_var_rem(cond_var_rem)
|
||||||
, max_size(capacity) {}
|
, max_size(capacity) {}
|
||||||
|
|
||||||
//! \~english Copy constructor from PIDeque
|
/**
|
||||||
//! \~russian Конструктор копирования из PIDeque
|
* \brief Copy constructor. Initialize queue with copy of other queue elements. Not thread-safe for other queue.
|
||||||
|
*/
|
||||||
explicit inline PIBlockingQueue(const PIDeque<T> & other)
|
explicit inline PIBlockingQueue(const PIDeque<T> & other)
|
||||||
: cond_var_add(new PIConditionVariable())
|
: cond_var_add(new PIConditionVariable())
|
||||||
, cond_var_rem(new PIConditionVariable()) {
|
, cond_var_rem(new PIConditionVariable()) {
|
||||||
@@ -61,8 +58,9 @@ public:
|
|||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Thread-safe copy constructor from another PIBlockingQueue
|
/**
|
||||||
//! \~russian Потокобезопасный конструктор копирования из другой PIBlockingQueue
|
* \brief Thread-safe copy constructor. Initialize queue with copy of other queue elements.
|
||||||
|
*/
|
||||||
inline PIBlockingQueue(PIBlockingQueue<T> & other): cond_var_add(new PIConditionVariable()), cond_var_rem(new PIConditionVariable()) {
|
inline PIBlockingQueue(PIBlockingQueue<T> & other): cond_var_add(new PIConditionVariable()), cond_var_rem(new PIConditionVariable()) {
|
||||||
other.mutex.lock();
|
other.mutex.lock();
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
@@ -77,8 +75,11 @@ public:
|
|||||||
delete cond_var_rem;
|
delete cond_var_rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Inserts element waiting for space to become available
|
/**
|
||||||
//! \~russian Вставляет элемент, ожидая освобождения места
|
* \brief Inserts the specified element into this queue, waiting if necessary for space to become available.
|
||||||
|
*
|
||||||
|
* @param v the element to add
|
||||||
|
*/
|
||||||
PIBlockingQueue<T> & put(const T & v) {
|
PIBlockingQueue<T> & put(const T & v) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
cond_var_rem->wait(mutex, [&]() { return PIDeque<T>::size() < max_size; });
|
cond_var_rem->wait(mutex, [&]() { return PIDeque<T>::size() < max_size; });
|
||||||
@@ -90,8 +91,14 @@ public:
|
|||||||
|
|
||||||
PIBlockingQueue<T> & enqueue(const T & v) { return put(v); }
|
PIBlockingQueue<T> & enqueue(const T & v) { return put(v); }
|
||||||
|
|
||||||
//! \~english Inserts element if possible without exceeding capacity
|
/**
|
||||||
//! \~russian Вставляет элемент если возможно без превышения емкости
|
* \brief Inserts the specified element at the end of this queue if it is possible to do so immediately without
|
||||||
|
* exceeding the queue's capacity, returning true upon success and false if this queue is full.
|
||||||
|
*
|
||||||
|
* @param v the element to add
|
||||||
|
* @param timeout the timeout waiting for inserting if que is full, if timeout is null, then returns immediately
|
||||||
|
* @return true if the element was added to this queue, else false
|
||||||
|
*/
|
||||||
bool offer(const T & v, PISystemTime timeout = {}) {
|
bool offer(const T & v, PISystemTime timeout = {}) {
|
||||||
bool isOk;
|
bool isOk;
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
@@ -122,8 +129,16 @@ public:
|
|||||||
|
|
||||||
T dequeue() { return take(); }
|
T dequeue() { return take(); }
|
||||||
|
|
||||||
//! \~english Retrieves and removes head, waiting until element becomes available
|
/**
|
||||||
//! \~russian Извлекает и удаляет голову очереди, ожидая появления элемента
|
* \brief Retrieves and removes the head of this queue, waiting up to the specified wait time if necessary for an
|
||||||
|
* element to become available.
|
||||||
|
*
|
||||||
|
* @param timeout how long to wait before giving up
|
||||||
|
* @param defaultVal value, which returns if the specified waiting time elapses before an element is available
|
||||||
|
* @param isOk flag, which indicates result of method execution. It will be set to false if timeout, or true if
|
||||||
|
* return value is retrieved value
|
||||||
|
* @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available
|
||||||
|
*/
|
||||||
T poll(PISystemTime timeout = {}, const T & defaultVal = T(), bool * isOk = nullptr) {
|
T poll(PISystemTime timeout = {}, const T & defaultVal = T(), bool * isOk = nullptr) {
|
||||||
T t = defaultVal;
|
T t = defaultVal;
|
||||||
bool isNotEmpty;
|
bool isNotEmpty;
|
||||||
@@ -139,8 +154,12 @@ public:
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns queue capacity
|
/**
|
||||||
//! \~russian Возвращает емкость очереди
|
* \brief Returns the number of elements that this queue can ideally (in the absence of memory or resource
|
||||||
|
* constraints) contains. This is always equal to the initial capacity of this queue less the current size of this queue.
|
||||||
|
*
|
||||||
|
* @return the capacity
|
||||||
|
*/
|
||||||
size_t capacity() {
|
size_t capacity() {
|
||||||
size_t c;
|
size_t c;
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
@@ -149,8 +168,12 @@ public:
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns remaining capacity
|
/**
|
||||||
//! \~russian Возвращает оставшуюся емкость
|
* \brief Returns the number of additional elements that this queue can ideally (in the absence of memory or resource
|
||||||
|
* constraints) accept. This is always equal to the initial capacity of this queue less the current size of this queue.
|
||||||
|
*
|
||||||
|
* @return the remaining capacity
|
||||||
|
*/
|
||||||
size_t remainingCapacity() {
|
size_t remainingCapacity() {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
size_t c = max_size - PIDeque<T>::size();
|
size_t c = max_size - PIDeque<T>::size();
|
||||||
@@ -158,8 +181,9 @@ public:
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns number of elements in queue
|
/**
|
||||||
//! \~russian Возвращает количество элементов в очереди
|
* \brief Returns the number of elements in this collection.
|
||||||
|
*/
|
||||||
size_t size() {
|
size_t size() {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
size_t s = PIDeque<T>::size();
|
size_t s = PIDeque<T>::size();
|
||||||
@@ -167,8 +191,9 @@ public:
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Removes all available elements and adds them to another queue
|
/**
|
||||||
//! \~russian Удаляет все доступные элементы и добавляет их в другую очередь
|
* \brief Removes all available elements from this queue and adds them to other given queue.
|
||||||
|
*/
|
||||||
size_t drainTo(PIDeque<T> & other, size_t maxCount = SIZE_MAX) {
|
size_t drainTo(PIDeque<T> & other, size_t maxCount = SIZE_MAX) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
size_t count = ((maxCount > PIDeque<T>::size()) ? PIDeque<T>::size() : maxCount);
|
size_t count = ((maxCount > PIDeque<T>::size()) ? PIDeque<T>::size() : maxCount);
|
||||||
@@ -178,8 +203,9 @@ public:
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Removes all available elements and adds them to another blocking queue
|
/**
|
||||||
//! \~russian Удаляет все доступные элементы и добавляет их в другую блокирующую очередь
|
* \brief Removes all available elements from this queue and adds them to other given queue.
|
||||||
|
*/
|
||||||
size_t drainTo(PIBlockingQueue<T> & other, size_t maxCount = SIZE_MAX) {
|
size_t drainTo(PIBlockingQueue<T> & other, size_t maxCount = SIZE_MAX) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
other.mutex.lock();
|
other.mutex.lock();
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
//! \file piconditionvar.h
|
/*! \file piconditionvar.h
|
||||||
//! \ingroup Thread
|
* \ingroup Thread
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Conditional variable
|
* \~english Conditional variable
|
||||||
//! \~russian Условная переменная
|
* \~russian Conditional variable
|
||||||
//!
|
*/
|
||||||
//! \details
|
|
||||||
//! \~english Object able to block the calling thread until notified to resume.
|
|
||||||
//! \~russian Объект, способный заблокировать вызывающий поток до уведомления о продолжении.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
|
|
||||||
@@ -39,39 +36,27 @@
|
|||||||
* It uses a PIMutex to lock the thread when one of its wait functions is called. The thread remains
|
* It uses a PIMutex to lock the thread when one of its wait functions is called. The thread remains
|
||||||
* blocked until woken up by another thread that calls a notification function on the same PIConditionVariable object.
|
* blocked until woken up by another thread that calls a notification function on the same PIConditionVariable object.
|
||||||
*/
|
*/
|
||||||
//! \~english Condition variable for thread synchronization
|
|
||||||
//! \~russian Условная переменная для синхронизации потоков
|
|
||||||
class PIP_EXPORT PIConditionVariable {
|
class PIP_EXPORT PIConditionVariable {
|
||||||
public:
|
public:
|
||||||
NO_COPY_CLASS(PIConditionVariable);
|
NO_COPY_CLASS(PIConditionVariable);
|
||||||
//! \~english Constructs condition variable
|
|
||||||
//! \~russian Создает условную переменную
|
|
||||||
explicit PIConditionVariable();
|
explicit PIConditionVariable();
|
||||||
//! \~english Destroys condition variable
|
|
||||||
//! \~russian Уничтожает условную переменную
|
|
||||||
virtual ~PIConditionVariable();
|
virtual ~PIConditionVariable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Unblocks one of the threads currently waiting for this condition. If no threads are waiting, the function
|
* \brief Unblocks one of the threads currently waiting for this condition. If no threads are waiting, the function
|
||||||
* does nothing. If more than one, it is unspecified which of the threads is selected.
|
* does nothing. If more than one, it is unspecified which of the threads is selected.
|
||||||
*/
|
*/
|
||||||
//! \~english Wakes one waiting thread
|
|
||||||
//! \~russian Будит один ожидающий поток
|
|
||||||
void notifyOne();
|
void notifyOne();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Unblocks all threads currently waiting for this condition. If no threads are waiting, the function does
|
* \brief Unblocks all threads currently waiting for this condition. If no threads are waiting, the function does
|
||||||
* nothing.
|
* nothing.
|
||||||
*/
|
*/
|
||||||
//! \~english Wakes all waiting threads
|
|
||||||
//! \~russian Будит все ожидающие потоки
|
|
||||||
void notifyAll();
|
void notifyAll();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief see wait(PIMutex &, const std::function<bool()>&)
|
* \brief see wait(PIMutex &, const std::function<bool()>&)
|
||||||
*/
|
*/
|
||||||
//! \~english Wait until notified
|
|
||||||
//! \~russian Ожидает уведомления
|
|
||||||
virtual void wait(PIMutex & lk);
|
virtual void wait(PIMutex & lk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,15 +83,11 @@ public:
|
|||||||
* @param condition A callable object or function that takes no arguments and returns a value that can be evaluated
|
* @param condition A callable object or function that takes no arguments and returns a value that can be evaluated
|
||||||
* as a bool. This is called repeatedly until it evaluates to true.
|
* as a bool. This is called repeatedly until it evaluates to true.
|
||||||
*/
|
*/
|
||||||
//! \~english Wait until notified with condition predicate
|
|
||||||
//! \~russian Ожидает уведомления с условием
|
|
||||||
virtual void wait(PIMutex & lk, const std::function<bool()> & condition);
|
virtual void wait(PIMutex & lk, const std::function<bool()> & condition);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief see waitFor(PIMutex &, int, const std::function<bool()>&)
|
* \brief see waitFor(PIMutex &, int, const std::function<bool()>&)
|
||||||
*/
|
*/
|
||||||
//! \~english Wait for timeout
|
|
||||||
//! \~russian Ожидает таймаут
|
|
||||||
virtual bool waitFor(PIMutex & lk, PISystemTime timeout);
|
virtual bool waitFor(PIMutex & lk, PISystemTime timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,8 +115,6 @@ public:
|
|||||||
* as a bool. This is called repeatedly until it evaluates to true.
|
* as a bool. This is called repeatedly until it evaluates to true.
|
||||||
* @return false if timeout reached or true if wakeup condition is true
|
* @return false if timeout reached or true if wakeup condition is true
|
||||||
*/
|
*/
|
||||||
//! \~english Wait for timeout or until notified with condition predicate
|
|
||||||
//! \~russian Ожидает таймаут или уведомление с условием
|
|
||||||
virtual bool waitFor(PIMutex & lk, PISystemTime timeout, const std::function<bool()> & condition);
|
virtual bool waitFor(PIMutex & lk, PISystemTime timeout, const std::function<bool()> & condition);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
//! \file pigrabberbase.h
|
/*! \file pigrabberbase.h
|
||||||
//! \ingroup Thread
|
* \ingroup Thread
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Abstract class for creating grabbers
|
* \~english Abstract class for create grabbers
|
||||||
//! \~russian Базовый класс для создания грабберов
|
* \~russian Базовый класс для создания грабберов
|
||||||
//!
|
*/
|
||||||
//! \details
|
|
||||||
//! \~english Base class for thread-based data acquisition with queue support.
|
|
||||||
//! \~russian Базовый класс для получения данных в потоке с поддержкой очереди.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Abstract class for create grabbers
|
Abstract class for create grabbers
|
||||||
@@ -34,33 +31,18 @@
|
|||||||
#include "pitime.h"
|
#include "pitime.h"
|
||||||
|
|
||||||
|
|
||||||
//! \~english Base class for data grabber threads
|
|
||||||
//! \~russian Базовый класс для потоков получения данных
|
|
||||||
template<typename T = PIByteArray>
|
template<typename T = PIByteArray>
|
||||||
class PIGrabberBase: public PIThread {
|
class PIGrabberBase: public PIThread {
|
||||||
PIOBJECT_SUBCLASS(PIGrabberBase, PIThread);
|
PIOBJECT_SUBCLASS(PIGrabberBase, PIThread);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs grabber
|
|
||||||
//! \~russian Создает граббер
|
|
||||||
PIGrabberBase() {
|
PIGrabberBase() {
|
||||||
is_opened = false;
|
is_opened = false;
|
||||||
is_recording = false;
|
is_recording = false;
|
||||||
}
|
}
|
||||||
//! \~english Destroys grabber
|
|
||||||
//! \~russian Уничтожает граббер
|
|
||||||
virtual ~PIGrabberBase() { stopGrabber(false); }
|
virtual ~PIGrabberBase() { stopGrabber(false); }
|
||||||
|
|
||||||
//! \~english Returns if grabber is opened
|
|
||||||
//! \~russian Возвращает открыт ли граббер
|
|
||||||
virtual bool isOpened() const { return is_opened; }
|
virtual bool isOpened() const { return is_opened; }
|
||||||
|
|
||||||
//! \~english Returns if grabber is recording
|
|
||||||
//! \~russian Возвращает записывает ли граббер
|
|
||||||
virtual bool isRecording() const { return is_recording; }
|
virtual bool isRecording() const { return is_recording; }
|
||||||
|
|
||||||
//! \~english Start recording to file
|
|
||||||
//! \~russian Начинает запись в файл
|
|
||||||
virtual void startRecord(const PIString & filename) {
|
virtual void startRecord(const PIString & filename) {
|
||||||
if (!isOpened()) return;
|
if (!isOpened()) return;
|
||||||
if (isRecording()) return;
|
if (isRecording()) return;
|
||||||
@@ -69,8 +51,6 @@ public:
|
|||||||
is_recording = true;
|
is_recording = true;
|
||||||
rec_mutex.unlock();
|
rec_mutex.unlock();
|
||||||
}
|
}
|
||||||
//! \~english Stop recording
|
|
||||||
//! \~russian Останавливает запись
|
|
||||||
virtual void stopRecord() {
|
virtual void stopRecord() {
|
||||||
if (!isOpened()) return;
|
if (!isOpened()) return;
|
||||||
if (!isRecording()) return;
|
if (!isRecording()) return;
|
||||||
@@ -79,9 +59,6 @@ public:
|
|||||||
stopRecordInternal();
|
stopRecordInternal();
|
||||||
rec_mutex.unlock();
|
rec_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns last grabbed data
|
|
||||||
//! \~russian Возвращает последние полученные данные
|
|
||||||
T last() const {
|
T last() const {
|
||||||
T ret;
|
T ret;
|
||||||
last_mutex.lock();
|
last_mutex.lock();
|
||||||
@@ -89,9 +66,6 @@ public:
|
|||||||
last_mutex.unlock();
|
last_mutex.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns if queue is empty
|
|
||||||
//! \~russian Возвращает пустая ли очередь
|
|
||||||
bool isEmpty() {
|
bool isEmpty() {
|
||||||
bool ret;
|
bool ret;
|
||||||
que_mutex.lock();
|
que_mutex.lock();
|
||||||
@@ -99,9 +73,6 @@ public:
|
|||||||
que_mutex.unlock();
|
que_mutex.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns queue size
|
|
||||||
//! \~russian Возвращает размер очереди
|
|
||||||
int queSize() {
|
int queSize() {
|
||||||
int ret;
|
int ret;
|
||||||
que_mutex.lock();
|
que_mutex.lock();
|
||||||
@@ -109,9 +80,6 @@ public:
|
|||||||
que_mutex.unlock();
|
que_mutex.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Dequeues data from queue
|
|
||||||
//! \~russian Извлекает данные из очереди
|
|
||||||
T dequeue() {
|
T dequeue() {
|
||||||
T ret;
|
T ret;
|
||||||
// piCoutObj << "start";
|
// piCoutObj << "start";
|
||||||
@@ -124,9 +92,6 @@ public:
|
|||||||
que_mutex.unlock();
|
que_mutex.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Stop grabber thread
|
|
||||||
//! \~russian Останавливает поток граббера
|
|
||||||
void stopGrabber(bool wait_forever = true) {
|
void stopGrabber(bool wait_forever = true) {
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
stop();
|
stop();
|
||||||
@@ -139,18 +104,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Open grabber
|
|
||||||
//! \~russian Открывает граббер
|
|
||||||
bool open() {
|
bool open() {
|
||||||
bool ret = openInternal();
|
bool ret = openInternal();
|
||||||
if (!is_opened && ret) opened();
|
if (!is_opened && ret) opened();
|
||||||
is_opened = ret;
|
is_opened = ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Close grabber
|
|
||||||
//! \~russian Закрывает граббер
|
|
||||||
void close() {
|
void close() {
|
||||||
bool em = is_opened;
|
bool em = is_opened;
|
||||||
closeInternal();
|
closeInternal();
|
||||||
@@ -158,21 +117,12 @@ public:
|
|||||||
if (em) closed();
|
if (em) closed();
|
||||||
is_opened = false;
|
is_opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns diagnostics
|
|
||||||
//! \~russian Возвращает диагностику
|
|
||||||
const PIDiagnostics & diag() const { return diag_; }
|
const PIDiagnostics & diag() const { return diag_; }
|
||||||
|
|
||||||
//! \~english Clear queue
|
|
||||||
//! \~russian Очищает очередь
|
|
||||||
void clear() {
|
void clear() {
|
||||||
que_mutex.lock();
|
que_mutex.lock();
|
||||||
que.clear();
|
que.clear();
|
||||||
que_mutex.unlock();
|
que_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Restart grabber
|
|
||||||
//! \~russian Перезапускает граббер
|
|
||||||
void restart() {
|
void restart() {
|
||||||
clear();
|
clear();
|
||||||
close();
|
close();
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
//! \file pipipelinethread.h
|
/*! \file pipipelinethread.h
|
||||||
//! \ingroup Thread
|
* \ingroup Thread
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Class for creating multithread pipeline
|
* \~english Class for create multihread pipeline
|
||||||
//! \~russian Класс для создания многопоточного конвейера
|
* \~russian Класс для создания многопоточного конвейера
|
||||||
//!
|
*/
|
||||||
//! \details
|
|
||||||
//! \~english Pipeline thread for processing data through stages in separate threads.
|
|
||||||
//! \~russian Конвейерный поток для обработки данных через этапы в отдельных потоках.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Class for create multihread pipeline
|
Class for create multihread pipeline
|
||||||
@@ -34,22 +31,16 @@
|
|||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
|
|
||||||
|
|
||||||
//! \~english Pipeline thread template class
|
|
||||||
//! \~russian Шаблонный класс конвейерного потока
|
|
||||||
template<typename Tin, typename Tout>
|
template<typename Tin, typename Tout>
|
||||||
class PIPipelineThread: public PIThread {
|
class PIPipelineThread: public PIThread {
|
||||||
PIOBJECT_SUBCLASS(PIPipelineThread, PIThread);
|
PIOBJECT_SUBCLASS(PIPipelineThread, PIThread);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs pipeline thread
|
|
||||||
//! \~russian Создает конвейерный поток
|
|
||||||
PIPipelineThread() {
|
PIPipelineThread() {
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
max_size = 0;
|
max_size = 0;
|
||||||
wait_next_pipe = false;
|
wait_next_pipe = false;
|
||||||
}
|
}
|
||||||
//! \~english Destroys pipeline thread
|
|
||||||
//! \~russian Уничтожает конвейерный поток
|
|
||||||
~PIPipelineThread() {
|
~PIPipelineThread() {
|
||||||
stop();
|
stop();
|
||||||
cv.notifyAll();
|
cv.notifyAll();
|
||||||
@@ -58,8 +49,6 @@ public:
|
|||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//! \~english Connect to next pipeline stage
|
|
||||||
//! \~russian Подключает к следующему этапу конвейера
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void connectTo(PIPipelineThread<Tout, T> * next) {
|
void connectTo(PIPipelineThread<Tout, T> * next) {
|
||||||
CONNECT3(void, Tout, bool, bool *, this, calculated, next, enqueue);
|
CONNECT3(void, Tout, bool, bool *, this, calculated, next, enqueue);
|
||||||
@@ -83,21 +72,9 @@ public:
|
|||||||
}
|
}
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Enqueue data for processing
|
|
||||||
//! \~russian Добавляет данные в очередь на обработку
|
|
||||||
void enqueue(const Tin & v, bool wait = false) { enqueue(v, wait, nullptr); }
|
void enqueue(const Tin & v, bool wait = false) { enqueue(v, wait, nullptr); }
|
||||||
|
|
||||||
//! \~english Returns pointer to counter
|
|
||||||
//! \~russian Возвращает указатель на счетчик
|
|
||||||
const ullong * counterPtr() const { return &cnt; }
|
const ullong * counterPtr() const { return &cnt; }
|
||||||
|
|
||||||
//! \~english Returns items processed counter
|
|
||||||
//! \~russian Возвращает количество обработанных элементов
|
|
||||||
ullong counter() const { return cnt; }
|
ullong counter() const { return cnt; }
|
||||||
|
|
||||||
//! \~english Returns if input queue is empty
|
|
||||||
//! \~russian Возвращает пустая ли входная очередь
|
|
||||||
bool isEmpty() {
|
bool isEmpty() {
|
||||||
bool ret;
|
bool ret;
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
@@ -105,9 +82,6 @@ public:
|
|||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns input queue size
|
|
||||||
//! \~russian Возвращает размер входной очереди
|
|
||||||
int queSize() {
|
int queSize() {
|
||||||
int ret;
|
int ret;
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
@@ -115,9 +89,6 @@ public:
|
|||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Clear input queue
|
|
||||||
//! \~russian Очищает входную очередь
|
|
||||||
void clear() {
|
void clear() {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
mutex_wait.lock();
|
mutex_wait.lock();
|
||||||
@@ -126,9 +97,6 @@ public:
|
|||||||
mutex_wait.unlock();
|
mutex_wait.unlock();
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Stop calculation
|
|
||||||
//! \~russian Останавливает вычисления
|
|
||||||
void stopCalc(int wait_delay = 100) {
|
void stopCalc(int wait_delay = 100) {
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
stop();
|
stop();
|
||||||
@@ -140,9 +108,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns last processed result
|
|
||||||
//! \~russian Возвращает последний обработанный результат
|
|
||||||
Tout getLast() {
|
Tout getLast() {
|
||||||
Tout ret;
|
Tout ret;
|
||||||
mutex_last.lock();
|
mutex_last.lock();
|
||||||
@@ -151,12 +116,8 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns max queue size
|
|
||||||
//! \~russian Возвращает максимальный размер очереди
|
|
||||||
uint maxQueSize() { return max_size; }
|
uint maxQueSize() { return max_size; }
|
||||||
|
|
||||||
//! \~english Set max queue size
|
|
||||||
//! \~russian Устанавливает максимальный размер очереди
|
|
||||||
void setMaxQueSize(uint count) {
|
void setMaxQueSize(uint count) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
max_size = count;
|
max_size = count;
|
||||||
@@ -164,17 +125,10 @@ public:
|
|||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Returns if waiting for next pipeline
|
|
||||||
//! \~russian Возвращает ожидает ли следующий конвейер
|
|
||||||
bool isWaitNextPipe() { return wait_next_pipe; }
|
bool isWaitNextPipe() { return wait_next_pipe; }
|
||||||
|
|
||||||
//! \~english Set waiting for next pipeline
|
|
||||||
//! \~russian Устанавливает ожидание следующего конвейера
|
|
||||||
void setWaitNextPipe(bool wait) { wait_next_pipe = wait; }
|
void setWaitNextPipe(bool wait) { wait_next_pipe = wait; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \~english Processing function - must be implemented
|
|
||||||
//! \~russian Функция обработки - должна быть реализована
|
|
||||||
virtual Tout calc(Tin & v, bool & ok) = 0;
|
virtual Tout calc(Tin & v, bool & ok) = 0;
|
||||||
|
|
||||||
uint max_size;
|
uint max_size;
|
||||||
|
|||||||
@@ -1,29 +1,26 @@
|
|||||||
//! \file piprotectedvariable.h
|
/*! \file piprotectedvariable.h
|
||||||
//! \ingroup Thread
|
* \ingroup Thread
|
||||||
//! \brief
|
* \~\brief
|
||||||
//! \~english Thread-safe variable
|
* \~english Thread-safe variable
|
||||||
//! \~russian Потокобезопасная переменная
|
* \~russian Потокобезопасная переменная
|
||||||
//!
|
*/
|
||||||
//! \details
|
|
||||||
//! \~english Template class for thread-safe variable access with mutex protection.
|
|
||||||
//! \~russian Шаблонный класс для потокобезопасного доступа к переменной с защитой мьютексом.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Thread-safe variable
|
Thread-safe variable
|
||||||
Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
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
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Lesser General Public License for more details.
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
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/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIPROTECTEDVARIABLE_H
|
#ifndef PIPROTECTEDVARIABLE_H
|
||||||
@@ -32,37 +29,25 @@
|
|||||||
#include "pimutex.h"
|
#include "pimutex.h"
|
||||||
|
|
||||||
|
|
||||||
//! \~english Thread-safe variable template class
|
|
||||||
//! \~russian Шаблонный класс потокобезопасной переменной
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class PIP_EXPORT PIProtectedVariable {
|
class PIP_EXPORT PIProtectedVariable {
|
||||||
public:
|
public:
|
||||||
//! \~english Pointer wrapper for thread-safe access
|
//! \~english
|
||||||
//! \~russian Обертка указателя для потокобезопасного доступа
|
//! \~russian
|
||||||
class PIP_EXPORT Pointer {
|
class PIP_EXPORT Pointer {
|
||||||
friend class PIProtectedVariable<T>;
|
friend class PIProtectedVariable<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Copy constructor
|
|
||||||
//! \~russian Конструктор копирования
|
|
||||||
Pointer(const Pointer & v): pv(v.pv), counter(v.counter + 1) {}
|
Pointer(const Pointer & v): pv(v.pv), counter(v.counter + 1) {}
|
||||||
//! \~english Destructor - unlocks mutex
|
|
||||||
//! \~russian Деструктор - разблокирует мьютекс
|
|
||||||
~Pointer() {
|
~Pointer() {
|
||||||
if (counter == 0) pv.mutex.unlock();
|
if (counter == 0) pv.mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \~english Access member
|
|
||||||
//! \~russian Доступ к члену
|
|
||||||
T * operator->() { return &pv.var; }
|
T * operator->() { return &pv.var; }
|
||||||
//! \~english Access value
|
|
||||||
//! \~russian Доступ к значению
|
|
||||||
T & operator*() { return pv.var; }
|
T & operator*() { return pv.var; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pointer() = delete;
|
Pointer() = delete;
|
||||||
//! \~english Construct from PIProtectedVariable
|
|
||||||
//! \~russian Конструктор из PIProtectedVariable
|
|
||||||
Pointer(PIProtectedVariable<T> & v): pv(v) {}
|
Pointer(PIProtectedVariable<T> & v): pv(v) {}
|
||||||
|
|
||||||
PIProtectedVariable<T> & pv;
|
PIProtectedVariable<T> & pv;
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
//! \file pithreadpoolexecutor.h
|
|
||||||
//! \ingroup Thread
|
|
||||||
//! \brief
|
|
||||||
//! \~english Thread pool executor
|
|
||||||
//! \~russian Исполнитель пула потоков
|
|
||||||
//!
|
|
||||||
//! \details
|
|
||||||
//! \~english Executes tasks in a pool of worker threads.
|
|
||||||
//! \~russian Выполняет задачи в пуле рабочих потоков.
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
|
|
||||||
@@ -35,16 +26,10 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
|
||||||
//! \~english Thread pool executor for running tasks
|
|
||||||
//! \~russian Исполнитель пула потоков для выполнения задач
|
|
||||||
class PIP_EXPORT PIThreadPoolExecutor {
|
class PIP_EXPORT PIThreadPoolExecutor {
|
||||||
public:
|
public:
|
||||||
//! \~english Constructs executor with core pool size
|
|
||||||
//! \~russian Создает исполнитель с размером ядра пула
|
|
||||||
explicit PIThreadPoolExecutor(int corePoolSize);
|
explicit PIThreadPoolExecutor(int corePoolSize);
|
||||||
|
|
||||||
//! \~english Destroys executor
|
|
||||||
//! \~russian Уничтожает исполнитель
|
|
||||||
virtual ~PIThreadPoolExecutor();
|
virtual ~PIThreadPoolExecutor();
|
||||||
|
|
||||||
//! \brief Executes the given task sometime in the future. The task execute in an existing pooled thread. If the task
|
//! \brief Executes the given task sometime in the future. The task execute in an existing pooled thread. If the task
|
||||||
@@ -52,27 +37,17 @@ public:
|
|||||||
//! reached.
|
//! reached.
|
||||||
//!
|
//!
|
||||||
//! \param runnable not empty function for thread pool execution
|
//! \param runnable not empty function for thread pool execution
|
||||||
//! \~english Execute task in thread pool
|
|
||||||
//! \~russian Выполняет задачу в пуле потоков
|
|
||||||
void execute(const std::function<void()> & runnable);
|
void execute(const std::function<void()> & runnable);
|
||||||
|
|
||||||
//! \~english Stop all threads immediately
|
|
||||||
//! \~russian Немедленно останавливает все потоки
|
|
||||||
void shutdownNow();
|
void shutdownNow();
|
||||||
|
|
||||||
//! \brief Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be
|
//! \brief Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be
|
||||||
//! accepted. Invocation has no additional effect if already shut down. This method does not wait for previously
|
//! accepted. Invocation has no additional effect if already shut down. This method does not wait for previously
|
||||||
//! submitted tasks to complete execution. Use awaitTermination to do that.
|
//! submitted tasks to complete execution. Use awaitTermination to do that.
|
||||||
//! \~english Initiates orderly shutdown
|
|
||||||
//! \~russian Инициирует упорядоченное завершение
|
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
//! \~english Returns if executor is shutdown
|
|
||||||
//! \~russian Возвращает остановлен ли исполнитель
|
|
||||||
bool isShutdown() const;
|
bool isShutdown() const;
|
||||||
|
|
||||||
//! \~english Wait for termination
|
|
||||||
//! \~russian Ожидает завершения
|
|
||||||
bool awaitTermination(PISystemTime timeout);
|
bool awaitTermination(PISystemTime timeout);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
//! \file colors_p.h
|
|
||||||
//! \ingroup Types
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Color collection
|
|
||||||
//! \~russian Коллекция цветов
|
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Color collection
|
Color collection
|
||||||
@@ -28,27 +23,13 @@
|
|||||||
#include "pivarianttypes.h"
|
#include "pivarianttypes.h"
|
||||||
|
|
||||||
|
|
||||||
//! \ingroup Types
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Color collection singleton for CSS color names.
|
|
||||||
//! \~russian Синглтон коллекции цветов для CSS имен цветов.
|
|
||||||
class PIColorCollection {
|
class PIColorCollection {
|
||||||
public:
|
public:
|
||||||
//! \~english Returns singleton instance of color collection.
|
|
||||||
//! \~russian Возвращает синглтон экземпляр коллекции цветов.
|
|
||||||
static PIColorCollection & instance();
|
static PIColorCollection & instance();
|
||||||
|
|
||||||
//! \~english Returns color by CSS name.
|
|
||||||
//! \~russian Возвращает цвет по CSS имени.
|
|
||||||
PIVariantTypes::Color getCSSColor(const PIString & name) const { return css_color.value(name); }
|
PIVariantTypes::Color getCSSColor(const PIString & name) const { return css_color.value(name); }
|
||||||
|
|
||||||
//! \~english Returns CSS name by color.
|
|
||||||
//! \~russian Возвращает CSS имя по цвету.
|
|
||||||
PIString getCSSName(const PIVariantTypes::Color color) const { return css_name.value(color); }
|
PIString getCSSName(const PIVariantTypes::Color color) const { return css_name.value(color); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! \~english Private constructor.
|
|
||||||
//! \~russian Приватный конструктор.
|
|
||||||
PIColorCollection();
|
PIColorCollection();
|
||||||
PIMap<PIString, PIVariantTypes::Color> css_color;
|
PIMap<PIString, PIVariantTypes::Color> css_color;
|
||||||
PIMap<PIVariantTypes::Color, PIString> css_name;
|
PIMap<PIVariantTypes::Color, PIString> css_name;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//! \file pibitarray.h
|
/*! \file pibitarray.h
|
||||||
//! \ingroup Types
|
* \~\brief
|
||||||
//! \~\brief
|
* \~english Bit array
|
||||||
//! \~english Bit array
|
* \~russian Битовый массив
|
||||||
//! \~russian Битовый массив
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Bit array
|
Bit array
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pibytearray.h
|
/*! \file pibytearray.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english Byte array
|
* \~english Byte array
|
||||||
//! \~russian Байтовый массив
|
* \~russian Байтовый массив
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Byte array
|
Byte array
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pidatetime.h
|
/*! \file pidatetime.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english Time and date structs
|
* \~english Time and date structs
|
||||||
//! \~russian Типы времени и даты
|
* \~russian Типы времени и даты
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Time and date structs
|
Time and date structs
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file piflags.h
|
/*! \file piflags.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english General flags class
|
* \~english General flags class
|
||||||
//! \~russian Универсальные флаги
|
* \~russian Универсальные флаги
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
General flags class
|
General flags class
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
//! \file pinetworkaddress.h
|
/*! \file pinetworkaddress.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english Network address
|
* \~english Network address
|
||||||
//! \~russian Сетевой адрес
|
* \~russian Сетевой адрес
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Network address
|
Network address
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pipropertystorage.h
|
/*! \file pipropertystorage.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english Properties array
|
* \~english Properties array
|
||||||
//! \~russian Массив свойств
|
* \~russian Массив свойств
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Storage of properties for GUI usage
|
Storage of properties for GUI usage
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pisystemtime.h
|
/*! \file pisystemtime.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english System time structs and methods
|
* \~english System time structs and methods
|
||||||
//! \~russian Типы и методы системного времени
|
* \~russian Типы и методы системного времени
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Time structs
|
Time structs
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pitime.h
|
/*! \file pitime.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \~\brief
|
||||||
//! \~english System time, time and date
|
* \~english System time, time and date
|
||||||
//! \~russian Системное время, время и дата
|
* \~russian Системное время, время и дата
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Ivan Pelipenko peri4ko@yandex.ru
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pivaluetree.h
|
/*! \file pivaluetree.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \brief
|
||||||
//! \~english Attributed values tree
|
* \~english Attributed values tree
|
||||||
//! \~russian Дерево атрибутированных значений
|
* \~russian Дерево атрибутированных значений
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Attributed values tree
|
Attributed values tree
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pivariant.h
|
/*! \file pivariant.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \brief
|
||||||
//! \~english Variant type
|
* \~english Variant type
|
||||||
//! \~russian Вариативный тип
|
* \~russian Вариативный тип
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Variant type
|
Variant type
|
||||||
@@ -101,21 +102,21 @@ struct __PIVariantTypeInfo__ {
|
|||||||
typedef const T & ConstReferenceType;
|
typedef const T & ConstReferenceType;
|
||||||
};
|
};
|
||||||
|
|
||||||
# define __TYPEINFO_SINGLE(PT, T) \
|
# define __TYPEINFO_SINGLE(PT, T) \
|
||||||
template<> \
|
template<> \
|
||||||
struct __PIVariantTypeInfo__<T> { \
|
struct __PIVariantTypeInfo__<T> { \
|
||||||
typedef PT PureType; \
|
typedef PT PureType; \
|
||||||
typedef const PT ConstPureType; \
|
typedef const PT ConstPureType; \
|
||||||
typedef PT * PointerType; \
|
typedef PT * PointerType; \
|
||||||
typedef const PT * ConstPointerType; \
|
typedef const PT * ConstPointerType; \
|
||||||
typedef PT & ReferenceType; \
|
typedef PT & ReferenceType; \
|
||||||
typedef const PT & ConstReferenceType; \
|
typedef const PT & ConstReferenceType; \
|
||||||
};
|
};
|
||||||
|
|
||||||
# define REGISTER_VARIANT_TYPEINFO(T) \
|
# define REGISTER_VARIANT_TYPEINFO(T) \
|
||||||
__TYPEINFO_SINGLE(T, T &) \
|
__TYPEINFO_SINGLE(T, T &) \
|
||||||
__TYPEINFO_SINGLE(T, const T) \
|
__TYPEINFO_SINGLE(T, const T) \
|
||||||
__TYPEINFO_SINGLE(T, const T &)
|
__TYPEINFO_SINGLE(T, const T &)
|
||||||
|
|
||||||
|
|
||||||
class PIP_EXPORT __PIVariantInfoStorage__ {
|
class PIP_EXPORT __PIVariantInfoStorage__ {
|
||||||
@@ -124,67 +125,72 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# define REGISTER_VARIANT(classname) \
|
# define REGISTER_VARIANT(classname) \
|
||||||
template<> \
|
template<> \
|
||||||
inline PIString __PIVariantFunctions__<classname>::typeNameHelper() { \
|
inline PIString __PIVariantFunctions__<classname>::typeNameHelper() { \
|
||||||
static PIString tn = PIStringAscii(#classname); \
|
static PIString tn = PIStringAscii(#classname); \
|
||||||
return tn; \
|
return tn; \
|
||||||
} \
|
} \
|
||||||
template<> \
|
template<> \
|
||||||
inline uint __PIVariantFunctions__<classname>::typeIDHelper() { \
|
inline uint __PIVariantFunctions__<classname>::typeIDHelper() { \
|
||||||
static uint ret = PIStringAscii(#classname).hash(); \
|
static uint ret = PIStringAscii(#classname).hash(); \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
REGISTER_VARIANT_TYPEINFO(classname) \
|
REGISTER_VARIANT_TYPEINFO(classname) \
|
||||||
STATIC_INITIALIZER_BEGIN \
|
STATIC_INITIALIZER_BEGIN \
|
||||||
uint type_id = __PIVariantFunctions__<classname>::typeIDHelper(); \
|
uint type_id = __PIVariantFunctions__<classname>::typeIDHelper(); \
|
||||||
PIString type_name = __PIVariantFunctions__<classname>::typeNameHelper(); \
|
PIString type_name = __PIVariantFunctions__<classname>::typeNameHelper(); \
|
||||||
if (__PIVariantInfoStorage__::get().contains(type_id)) return; \
|
if (__PIVariantInfoStorage__::get().contains(type_id)) return; \
|
||||||
PIByteArray empty; \
|
PIByteArray empty; \
|
||||||
empty << classname(); \
|
empty << classname(); \
|
||||||
__PIVariantInfoStorage__::get()[type_id] = new __PIVariantInfo__(type_name, empty); \
|
__PIVariantInfoStorage__::get()[type_id] = new __PIVariantInfo__(type_name, empty); \
|
||||||
STATIC_INITIALIZER_END
|
STATIC_INITIALIZER_END
|
||||||
|
|
||||||
|
|
||||||
# define REGISTER_VARIANT_CAST_H(classname_from, classname_to) \
|
# define REGISTER_VARIANT_CAST_H(classname_from, classname_to) \
|
||||||
template<> \
|
template<> \
|
||||||
template<> \
|
template<> \
|
||||||
inline classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v);
|
inline classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v);
|
||||||
|
|
||||||
# define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \
|
# define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \
|
||||||
template<> \
|
template<> \
|
||||||
template<> \
|
template<> \
|
||||||
inline PIByteArray __PIVariantFunctions__<classname_from>::castHelper<classname_to>(PIByteArray v) { \
|
inline PIByteArray __PIVariantFunctions__<classname_from>::castHelper<classname_to>(PIByteArray v) { \
|
||||||
classname_from f; \
|
classname_from f; \
|
||||||
v >> f; \
|
v >> f; \
|
||||||
classname_to t = __PIVariantFunctions__<classname_from>::castVariant<classname_to>(f); \
|
classname_to t = __PIVariantFunctions__<classname_from>::castVariant<classname_to>(f); \
|
||||||
PIByteArray ret; \
|
PIByteArray ret; \
|
||||||
ret << t; \
|
ret << t; \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
|
||||||
STATIC_INITIALIZER_BEGIN \
|
|
||||||
__PIVariantInfo__ * vi(__PIVariantInfoStorage__::get().value(__PIVariantFunctions__<classname_from>::typeIDHelper(), nullptr)); \
|
|
||||||
if (!vi) { \
|
|
||||||
piCout << "Warning! Using REGISTER_VARIANT_CAST(" #classname_from ", " #classname_to ") before REGISTER_VARIANT(" #classname_from \
|
|
||||||
"), ignore."; \
|
|
||||||
return; \
|
|
||||||
} \
|
} \
|
||||||
vi->cast[__PIVariantFunctions__<classname_to>::typeIDHelper()] = __PIVariantFunctions__<classname_from>::castHelper<classname_to>; \
|
STATIC_INITIALIZER_BEGIN \
|
||||||
STATIC_INITIALIZER_END \
|
__PIVariantInfo__ * vi(__PIVariantInfoStorage__::get().value(__PIVariantFunctions__<classname_from>::typeIDHelper(), nullptr)); \
|
||||||
template<> \
|
if (!vi) { \
|
||||||
template<> \
|
piCout << "Warning! Using REGISTER_VARIANT_CAST(" #classname_from ", " #classname_to \
|
||||||
classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v)
|
") before REGISTER_VARIANT(" #classname_from "), ignore."; \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
vi->cast[__PIVariantFunctions__<classname_to>::typeIDHelper()] = \
|
||||||
|
__PIVariantFunctions__<classname_from>::castHelper<classname_to>; \
|
||||||
|
STATIC_INITIALIZER_END \
|
||||||
|
template<> \
|
||||||
|
template<> \
|
||||||
|
classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(const classname_from & v)
|
||||||
|
|
||||||
# define REGISTER_VARIANT_CAST(classname_from, classname_to) \
|
# define REGISTER_VARIANT_CAST(classname_from, classname_to) \
|
||||||
REGISTER_VARIANT_CAST_H(classname_from, classname_to) \
|
REGISTER_VARIANT_CAST_H(classname_from, classname_to) \
|
||||||
REGISTER_VARIANT_CAST_CPP(classname_from, classname_to)
|
REGISTER_VARIANT_CAST_CPP(classname_from, classname_to)
|
||||||
|
|
||||||
|
|
||||||
# define REGISTER_VARIANT_CAST_SIMPLE(classname_from, classname_to) \
|
# define REGISTER_VARIANT_CAST_SIMPLE(classname_from, classname_to) \
|
||||||
REGISTER_VARIANT_CAST(classname_from, classname_to) { return classname_to(v); }
|
REGISTER_VARIANT_CAST(classname_from, classname_to) { \
|
||||||
|
return classname_to(v); \
|
||||||
|
}
|
||||||
# define REGISTER_VARIANT_CAST_SIMPLE_H(classname_from, classname_to) REGISTER_VARIANT_CAST_H(classname_from, classname_to)
|
# define REGISTER_VARIANT_CAST_SIMPLE_H(classname_from, classname_to) REGISTER_VARIANT_CAST_H(classname_from, classname_to)
|
||||||
# define REGISTER_VARIANT_CAST_SIMPLE_CPP(classname_from, classname_to) \
|
# define REGISTER_VARIANT_CAST_SIMPLE_CPP(classname_from, classname_to) \
|
||||||
REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) { return classname_to(v); }
|
REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) { \
|
||||||
|
return classname_to(v); \
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -1176,7 +1182,7 @@ REGISTER_VARIANT_CAST(PIGeoPosition, PIString) {
|
|||||||
g.setEllipsoidModel(PIEllipsoidModel::WGS84Ellipsoid());
|
g.setEllipsoidModel(PIEllipsoidModel::WGS84Ellipsoid());
|
||||||
g.transformTo(PIGeoPosition::Geodetic);
|
g.transformTo(PIGeoPosition::Geodetic);
|
||||||
return PIString::fromNumber(g.latitudeGeodetic(), 'f', 8) + ", " + PIString::fromNumber(g.longitude(), 'f', 8) + ", " +
|
return PIString::fromNumber(g.latitudeGeodetic(), 'f', 8) + ", " + PIString::fromNumber(g.longitude(), 'f', 8) + ", " +
|
||||||
PIString::fromNumber(g.height(), 'f', 2);
|
PIString::fromNumber(g.height(), 'f', 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_VARIANT_CAST(PIString, PIGeoPosition) {
|
REGISTER_VARIANT_CAST(PIString, PIGeoPosition) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pivariantsimple.h
|
/*! \file pivariantsimple.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \brief
|
||||||
//! \~english Simple variant type
|
* \~english Simple variant type
|
||||||
//! \~russian Простой вариативный тип
|
* \~russian Простой вариативный тип
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Variant simple type
|
Variant simple type
|
||||||
@@ -177,27 +178,35 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define REGISTER_PIVARIANTSIMPLE(Type) \
|
#define REGISTER_PIVARIANTSIMPLE(Type) \
|
||||||
template<> \
|
template<> \
|
||||||
class __VariantFunctions__<Type>: public __VariantFunctionsBase__ { \
|
class __VariantFunctions__<Type>: public __VariantFunctionsBase__ { \
|
||||||
public: \
|
public: \
|
||||||
__VariantFunctionsBase__ * instance() final { \
|
__VariantFunctionsBase__ * instance() final { \
|
||||||
static __VariantFunctions__<Type> ret; \
|
static __VariantFunctions__<Type> ret; \
|
||||||
return &ret; \
|
return &ret; \
|
||||||
} \
|
} \
|
||||||
PIString typeName() const final { \
|
PIString typeName() const final { \
|
||||||
static PIString ret(#Type); \
|
static PIString ret(#Type); \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
uint hash() const final { \
|
uint hash() const final { \
|
||||||
static uint ret = typeName().hash(); \
|
static uint ret = typeName().hash(); \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
void newT(void *& ptr, const void * value) final { ptr = (void *)(new Type(*(const Type *)value)); } \
|
void newT(void *& ptr, const void * value) final { \
|
||||||
void newNullT(void *& ptr) final { ptr = (void *)(new Type()); } \
|
ptr = (void *)(new Type(*(const Type *)value)); \
|
||||||
void assignT(void *& ptr, const void * value) final { *(Type *)ptr = *(const Type *)value; } \
|
} \
|
||||||
void deleteT(void *& ptr) final { delete (Type *)(ptr); } \
|
void newNullT(void *& ptr) final { \
|
||||||
};
|
ptr = (void *)(new Type()); \
|
||||||
|
} \
|
||||||
|
void assignT(void *& ptr, const void * value) final { \
|
||||||
|
*(Type *)ptr = *(const Type *)value; \
|
||||||
|
} \
|
||||||
|
void deleteT(void *& ptr) final { \
|
||||||
|
delete (Type *)(ptr); \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
REGISTER_PIVARIANTSIMPLE(std::function<void(void *)>)
|
REGISTER_PIVARIANTSIMPLE(std::function<void(void *)>)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! \file pivarianttypes.h
|
/*! \file pivarianttypes.h
|
||||||
//! \ingroup Types
|
* \ingroup Types
|
||||||
//! \~\brief
|
* \brief
|
||||||
//! \~english Types for PIVariant
|
* \~english Types for PIVariant
|
||||||
//! \~russian Типы для PIVariant
|
* \~russian Типы для PIVariant
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Variant types
|
Variant types
|
||||||
|
|||||||
@@ -23,171 +23,82 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! \~english Units base classes
|
|
||||||
//! \~russian Базовые классы единиц измерения
|
|
||||||
//! \defgroup Units Units
|
|
||||||
//! \~\brief
|
|
||||||
//! \~english Unit conversions
|
|
||||||
//! \~russian Преобразование единиц измерения
|
|
||||||
//!
|
|
||||||
//! \~\details
|
|
||||||
//! \~english \section cmake_module_Units Building with CMake
|
|
||||||
//! \~russian \section cmake_module_Units Сборка с использованием CMake
|
|
||||||
//!
|
|
||||||
//! \~\code
|
|
||||||
//! find_package(PIP REQUIRED)
|
|
||||||
//! target_link_libraries([target] PIP)
|
|
||||||
//! \endcode
|
|
||||||
//!
|
|
||||||
//! \~english \par Common
|
|
||||||
//! \~russian \par Общее
|
|
||||||
//!
|
|
||||||
//! \~english
|
|
||||||
//! These files provides unit conversion framework.
|
|
||||||
//!
|
|
||||||
//! \~russian
|
|
||||||
//! Эти файлы обеспечивают фреймворк преобразования единиц.
|
|
||||||
//!
|
|
||||||
//! \~\authors
|
|
||||||
//! \~english
|
|
||||||
//! Ivan Pelipenko peri4ko@yandex.ru;
|
|
||||||
//! Andrey Bychkov work.a.b@yandex.ru;
|
|
||||||
//! \~russian
|
|
||||||
//! Иван Пелипенко peri4ko@yandex.ru;
|
|
||||||
//! Андрей Бычков work.a.b@yandex.ru;
|
|
||||||
//!
|
|
||||||
|
|
||||||
#ifndef PIUNITS_BASE_H
|
#ifndef PIUNITS_BASE_H
|
||||||
#define PIUNITS_BASE_H
|
#define PIUNITS_BASE_H
|
||||||
|
|
||||||
#include "pitranslator.h"
|
#include "pitranslator.h"
|
||||||
|
|
||||||
//! \~english Macro to declare unit class beginning
|
#define DECLARE_UNIT_CLASS_BEGIN(Name, StartIndex) \
|
||||||
//! \~russian Макрос для объявления начала класса единиц
|
namespace PIUnits { \
|
||||||
#define DECLARE_UNIT_CLASS_BEGIN(Name, StartIndex) \
|
namespace Class { \
|
||||||
namespace PIUnits { \
|
class PIP_EXPORT Name \
|
||||||
namespace Class { \
|
: public Internal::ClassBase \
|
||||||
class PIP_EXPORT Name \
|
, public Internal::Registrator<Name> { \
|
||||||
: public Internal::ClassBase \
|
private: \
|
||||||
, public Internal::Registrator<Name> { \
|
friend class Internal::Registrator<Name>; \
|
||||||
private: \
|
constexpr static int typeStart = StartIndex; \
|
||||||
friend class Internal::Registrator<Name>; \
|
PIString name(int type) const override; \
|
||||||
constexpr static int typeStart = StartIndex; \
|
PIString unit(int type) const override; \
|
||||||
PIString name(int type) const override; \
|
PIString valueToString(double v, char format, int prec) const override; \
|
||||||
PIString unit(int type) const override; \
|
double convert(double v, int from, int to) const override; \
|
||||||
PIString valueToString(double v, char format, int prec) const override; \
|
bool supportPrefixes(int type) const override; \
|
||||||
double convert(double v, int from, int to) const override; \
|
bool supportPrefixesNon3(int type) const override; \
|
||||||
bool supportPrefixes(int type) const override; \
|
bool supportPrefixesGreater(int type) const override; \
|
||||||
bool supportPrefixesNon3(int type) const override; \
|
bool supportPrefixesSmaller(int type) const override; \
|
||||||
bool supportPrefixesGreater(int type) const override; \
|
\
|
||||||
bool supportPrefixesSmaller(int type) const override; \
|
public: \
|
||||||
\
|
PIString className() const override { \
|
||||||
public: \
|
return piTr(#Name, "PIUnits"); \
|
||||||
PIString className() const override { return piTr(#Name, "PIUnits"); } \
|
} \
|
||||||
uint classID() const override { \
|
uint classID() const override { \
|
||||||
static uint ret = PIStringAscii(#Name).hash(); \
|
static uint ret = PIStringAscii(#Name).hash(); \
|
||||||
return ret; \
|
return ret; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \~english Macro to declare unit class end
|
#define DECLARE_UNIT_CLASS_END(Name) \
|
||||||
//! \~russian Макрос для объявления конца класса единиц
|
} \
|
||||||
#define DECLARE_UNIT_CLASS_END(Name) \
|
; \
|
||||||
} \
|
} \
|
||||||
; \
|
} \
|
||||||
} \
|
STATIC_INITIALIZER_BEGIN \
|
||||||
} \
|
PIUnits::Class::Name::registerSelf(); \
|
||||||
STATIC_INITIALIZER_BEGIN \
|
STATIC_INITIALIZER_END
|
||||||
PIUnits::Class::Name::registerSelf(); \
|
|
||||||
STATIC_INITIALIZER_END
|
|
||||||
|
|
||||||
namespace PIUnits {
|
namespace PIUnits {
|
||||||
|
|
||||||
//! \~english Get class name for type
|
|
||||||
//! \~russian Получить имя класса для типа
|
|
||||||
PIP_EXPORT PIString className(int type);
|
PIP_EXPORT PIString className(int type);
|
||||||
|
|
||||||
//! \~english Get unit name for type
|
|
||||||
//! \~russian Получить имя единицы для типа
|
|
||||||
PIP_EXPORT PIString name(int type);
|
PIP_EXPORT PIString name(int type);
|
||||||
|
|
||||||
//! \~english Get unit symbol for type
|
|
||||||
//! \~russian Получить символ единицы для типа
|
|
||||||
PIP_EXPORT PIString unit(int type);
|
PIP_EXPORT PIString unit(int type);
|
||||||
|
|
||||||
namespace Class {
|
namespace Class {
|
||||||
|
|
||||||
//! \~english Invalid type marker
|
|
||||||
//! \~russian Маркер недопустимого типа
|
|
||||||
enum {
|
enum {
|
||||||
Invalid = -1
|
Invalid = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Internal namespace for unit classes implementation
|
|
||||||
//! \~russian Внутреннее пространство имен для реализации классов единиц
|
|
||||||
class PIP_EXPORT Internal {
|
class PIP_EXPORT Internal {
|
||||||
public:
|
public:
|
||||||
//! \~english Base class for all unit classes
|
|
||||||
//! \~russian Базовый класс для всех классов единиц
|
|
||||||
class PIP_EXPORT ClassBase {
|
class PIP_EXPORT ClassBase {
|
||||||
public:
|
public:
|
||||||
//! \~english Get class ID
|
|
||||||
//! \~russian Получить ID класса
|
|
||||||
virtual uint classID() const = 0;
|
virtual uint classID() const = 0;
|
||||||
|
|
||||||
//! \~english Get class name
|
|
||||||
//! \~russian Получить имя класса
|
|
||||||
virtual PIString className() const = 0;
|
virtual PIString className() const = 0;
|
||||||
|
|
||||||
//! \~english Get name for unit type
|
|
||||||
//! \~russian Получить имя для типа единицы
|
|
||||||
virtual PIString name(int type) const = 0;
|
virtual PIString name(int type) const = 0;
|
||||||
|
|
||||||
//! \~english Get unit symbol for type
|
|
||||||
//! \~russian Получить символ единицы для типа
|
|
||||||
virtual PIString unit(int type) const = 0;
|
virtual PIString unit(int type) const = 0;
|
||||||
|
|
||||||
//! \~english Convert value to string
|
|
||||||
//! \~russian Преобразовать значение в строку
|
|
||||||
virtual PIString valueToString(double v, char format = 'g', int prec = 5) const = 0;
|
virtual PIString valueToString(double v, char format = 'g', int prec = 5) const = 0;
|
||||||
|
|
||||||
//! \~english Convert value between units
|
|
||||||
//! \~russian Преобразовать значение между единицами
|
|
||||||
virtual double convert(double v, int from, int to) const = 0;
|
virtual double convert(double v, int from, int to) const = 0;
|
||||||
|
|
||||||
//! \~english Check if prefixes are supported
|
|
||||||
//! \~russian Проверить поддерживаются ли префиксы
|
|
||||||
virtual bool supportPrefixes(int type) const { return true; }
|
virtual bool supportPrefixes(int type) const { return true; }
|
||||||
|
|
||||||
//! \~english Check if non-3 prefixes are supported
|
|
||||||
//! \~russian Проверить поддерживаются ли не-3 префиксы
|
|
||||||
virtual bool supportPrefixesNon3(int type) const { return false; }
|
virtual bool supportPrefixesNon3(int type) const { return false; }
|
||||||
|
|
||||||
//! \~english Check if greater prefixes are supported
|
|
||||||
//! \~russian Проверить поддерживаются ли большие префиксы
|
|
||||||
virtual bool supportPrefixesGreater(int type) const { return true; }
|
virtual bool supportPrefixesGreater(int type) const { return true; }
|
||||||
|
|
||||||
//! \~english Check if smaller prefixes are supported
|
|
||||||
//! \~russian Проверить поддерживаются ли меньшие префиксы
|
|
||||||
virtual bool supportPrefixesSmaller(int type) const { return true; }
|
virtual bool supportPrefixesSmaller(int type) const { return true; }
|
||||||
|
|
||||||
//! \~english Get all available types
|
|
||||||
//! \~russian Получить все доступные типы
|
|
||||||
const PIVector<int> & allTypes() const { return types; }
|
const PIVector<int> & allTypes() const { return types; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \~english List of types
|
|
||||||
//! \~russian Список типов
|
|
||||||
PIVector<int> types;
|
PIVector<int> types;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Template for self-registration of unit classes
|
|
||||||
//! \~russian Шаблон для саморегистрации классов единиц
|
|
||||||
template<typename P>
|
template<typename P>
|
||||||
class Registrator {
|
class Registrator {
|
||||||
public:
|
public:
|
||||||
//! \~english Register unit class
|
|
||||||
//! \~russian Зарегистрировать класс единиц
|
|
||||||
static void registerSelf() {
|
static void registerSelf() {
|
||||||
auto * uc = new P();
|
auto * uc = new P();
|
||||||
for (int t = P::typeStart; t < P::_LastType; ++t) {
|
for (int t = P::typeStart; t < P::_LastType; ++t) {
|
||||||
@@ -197,25 +108,14 @@ public:
|
|||||||
if (!Internal::allTypeClasses.contains(uc)) Internal::allTypeClasses << uc;
|
if (!Internal::allTypeClasses.contains(uc)) Internal::allTypeClasses << uc;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Map of type to class instance
|
|
||||||
//! \~russian Карта типа к экземпляру класса
|
|
||||||
static PIMap<int, ClassBase *> typeClasses;
|
static PIMap<int, ClassBase *> typeClasses;
|
||||||
|
|
||||||
//! \~english List of all registered classes
|
|
||||||
//! \~russian Список всех зарегистрированных классов
|
|
||||||
static PIVector<ClassBase *> allTypeClasses;
|
static PIVector<ClassBase *> allTypeClasses;
|
||||||
|
|
||||||
//! \~english Unknown name placeholder
|
|
||||||
//! \~russian Заполнитель для неизвестного имени
|
|
||||||
static const PIString unknown;
|
static const PIString unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace Class
|
} // namespace Class
|
||||||
|
|
||||||
//! \~english Get all registered unit classes
|
|
||||||
//! \~russian Получить все зарегистрированные классы единиц
|
|
||||||
PIP_EXPORT PIVector<Class::Internal::ClassBase *> allClasses();
|
PIP_EXPORT PIVector<Class::Internal::ClassBase *> allClasses();
|
||||||
|
|
||||||
} // namespace PIUnits
|
} // namespace PIUnits
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
//! \~english Unit prefixes
|
/*! \file piunits_prefix.h
|
||||||
//! \~russian Префиксы единиц измерения
|
* \ingroup Core
|
||||||
|
* \~\brief
|
||||||
|
* \~english Unit prefixes
|
||||||
|
* \~russian Префиксы единиц измерения
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Unit prefix
|
Unit prefix
|
||||||
@@ -26,59 +30,41 @@
|
|||||||
|
|
||||||
namespace PIUnits {
|
namespace PIUnits {
|
||||||
|
|
||||||
//! \~english Unit prefix class
|
|
||||||
//! \~russian Класс префикса единиц
|
|
||||||
class PIP_EXPORT Prefix {
|
class PIP_EXPORT Prefix {
|
||||||
friend class Value;
|
friend class Value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! \~english Prefix values
|
|
||||||
//! \~russian Значения префиксов
|
|
||||||
enum {
|
enum {
|
||||||
None, //!< No prefix
|
None,
|
||||||
|
|
||||||
Deca = 0x100, //!< da 10^1 10
|
Deca = 0x100, // da 10^1 10
|
||||||
Hecto, //!< h 10^2 100
|
Hecto, // h 10^2 100
|
||||||
Kilo, //!< k 10^3 1000
|
Kilo, // k 10^3 1000
|
||||||
Mega, //!< M 10^6 1000000
|
Mega, // M 10^6 1000000
|
||||||
Giga, //!< G 10^9 1000000000
|
Giga, // G 10^9 1000000000
|
||||||
Tera, //!< T 10^12 1000000000000
|
Tera, // T 10^12 1000000000000
|
||||||
Peta, //!< P 10^15 1000000000000000
|
Peta, // P 10^15 1000000000000000
|
||||||
Exa, //!< E 10^18 1000000000000000000
|
Exa, // E 10^18 1000000000000000000
|
||||||
Zetta, //!< Z 10^21 1000000000000000000000
|
Zetta, // Z 10^21 1000000000000000000000
|
||||||
Yotta, //!< Y 10^24 1000000000000000000000000
|
Yotta, // Y 10^24 1000000000000000000000000
|
||||||
Ronna, //!< R 10^27 1000000000000000000000000000
|
Ronna, // R 10^27 1000000000000000000000000000
|
||||||
Quetta, //!< Q 10^30 1000000000000000000000000000000
|
Quetta, // Q 10^30 1000000000000000000000000000000
|
||||||
|
|
||||||
Deci = 0x200, //!< d 10^−1 0.1
|
Deci = 0x200, // d 10^−1 0.1
|
||||||
Centi, //!< c 10^−2 0.01
|
Centi, // c 10^−2 0.01
|
||||||
Milli, //!< m 10^−3 0.001
|
Milli, // m 10^−3 0.001
|
||||||
Micro, //!< μ 10^−6 0.000001
|
Micro, // μ 10^−6 0.000001
|
||||||
Nano, //!< n 10^−9 0.000000001
|
Nano, // n 10^−9 0.000000001
|
||||||
Pico, //!< p 10^−12 0.000000000001
|
Pico, // p 10^−12 0.000000000001
|
||||||
Femto, //!< f 10^−15 0.000000000000001
|
Femto, // f 10^−15 0.000000000000001
|
||||||
Atto, //!< a 10^−18 0.000000000000000001
|
Atto, // a 10^−18 0.000000000000000001
|
||||||
Zepto, //!< z 10^−21 0.000000000000000000001
|
Zepto, // z 10^−21 0.000000000000000000001
|
||||||
Yocto, //!< y 10^−24 0.000000000000000000000001
|
Yocto, // y 10^−24 0.000000000000000000000001
|
||||||
Ronto, //!< r 10^−27 0.000000000000000000000000001
|
Ronto, // r 10^−27 0.000000000000000000000000001
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Get prefix name
|
|
||||||
//! \~russian Получить имя префикса
|
|
||||||
//! \param prefix Prefix value
|
|
||||||
//! \return Prefix name
|
|
||||||
static PIString name(int prefix);
|
static PIString name(int prefix);
|
||||||
|
|
||||||
//! \~english Get prefix symbol
|
|
||||||
//! \~russian Получить символ префикса
|
|
||||||
//! \param prefix Prefix value
|
|
||||||
//! \return Prefix symbol
|
|
||||||
static PIString prefix(int prefix);
|
static PIString prefix(int prefix);
|
||||||
|
|
||||||
//! \~english Get multiplier for prefix
|
|
||||||
//! \~russian Получить множитель для префикса
|
|
||||||
//! \param prefix Prefix value
|
|
||||||
//! \return Multiplier value
|
|
||||||
static double multiplier(int prefix);
|
static double multiplier(int prefix);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -87,8 +73,6 @@ private:
|
|||||||
static Prefix & instance();
|
static Prefix & instance();
|
||||||
static PIString valueToString(double v, void * type_class, int type, char format = 'g', int prec = 5);
|
static PIString valueToString(double v, void * type_class, int type, char format = 'g', int prec = 5);
|
||||||
|
|
||||||
//! \~english Prefix data structure
|
|
||||||
//! \~russian Структура данных префикса
|
|
||||||
struct P {
|
struct P {
|
||||||
PIString name;
|
PIString name;
|
||||||
PIString prefix;
|
PIString prefix;
|
||||||
@@ -97,12 +81,7 @@ private:
|
|||||||
bool non3;
|
bool non3;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \~english Get prefix by value
|
|
||||||
//! \~russian Получить префикс по значению
|
|
||||||
const P getPrefix(int p) const;
|
const P getPrefix(int p) const;
|
||||||
|
|
||||||
//! \~english Get prefix for value
|
|
||||||
//! \~russian Получить префикс для значения
|
|
||||||
const P getPrefixForValue(double v, bool use_non3, bool use_greater, bool use_smaller) const;
|
const P getPrefixForValue(double v, bool use_non3, bool use_greater, bool use_smaller) const;
|
||||||
|
|
||||||
PIMap<int, P> prefixes;
|
PIMap<int, P> prefixes;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
//! \~english Unit value class
|
/*! \file piunits_value.h
|
||||||
//! \~russian Класс значения единицы
|
* \ingroup Core
|
||||||
|
* \~\brief
|
||||||
|
* \~english Unit value
|
||||||
|
* \~russian Единица измерения
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
PIP - Platform Independent Primitives
|
PIP - Platform Independent Primitives
|
||||||
Unit value
|
Unit value
|
||||||
@@ -27,67 +31,27 @@
|
|||||||
|
|
||||||
namespace PIUnits {
|
namespace PIUnits {
|
||||||
|
|
||||||
//! \~english Unit value representation
|
|
||||||
//! \~russian Представление значения единицы
|
|
||||||
class PIP_EXPORT Value {
|
class PIP_EXPORT Value {
|
||||||
public:
|
public:
|
||||||
//! \~english Constructor
|
|
||||||
//! \~russian Конструктор
|
|
||||||
//! \param v Value
|
|
||||||
//! \param t Unit type
|
|
||||||
Value(double v = 0., int t = Class::Invalid);
|
Value(double v = 0., int t = Class::Invalid);
|
||||||
|
|
||||||
//! \~english Check if value is valid
|
|
||||||
//! \~russian Проверить значение на корректность
|
|
||||||
//! \return true if valid
|
|
||||||
bool isValid() const { return m_type >= 0 && m_class; }
|
bool isValid() const { return m_type >= 0 && m_class; }
|
||||||
|
|
||||||
//! \~english Check if value is not valid
|
|
||||||
//! \~russian Проверить значение на некорректность
|
|
||||||
//! \return true if not valid
|
|
||||||
bool isNotValid() const { return m_type < 0 || !m_class; }
|
bool isNotValid() const { return m_type < 0 || !m_class; }
|
||||||
|
|
||||||
//! \~english Get raw value
|
|
||||||
//! \~russian Получить сырое значение
|
|
||||||
double value() const { return m_value; }
|
double value() const { return m_value; }
|
||||||
|
|
||||||
//! \~english Convert to string
|
|
||||||
//! \~russian Преобразовать в строку
|
|
||||||
//! \param format Format specifier
|
|
||||||
//! \param prec Precision
|
|
||||||
//! \return String representation
|
|
||||||
PIString toString(char format = 'g', int prec = 5) const;
|
PIString toString(char format = 'g', int prec = 5) const;
|
||||||
|
|
||||||
//! \~english Convert to different unit type
|
|
||||||
//! \~russian Преобразовать в другой тип единицы
|
|
||||||
//! \param type_to Target unit type
|
|
||||||
//! \return true if successful
|
|
||||||
bool convert(int type_to);
|
bool convert(int type_to);
|
||||||
|
|
||||||
//! \~english Get converted value
|
|
||||||
//! \~russian Получить преобразованное значение
|
|
||||||
//! \param type_to Target unit type
|
|
||||||
//! \return Converted value
|
|
||||||
Value converted(int type_to);
|
Value converted(int type_to);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! \~english Numeric value
|
double m_value = 0.;
|
||||||
//! \~russian Числовое значение
|
int m_type = -1;
|
||||||
double m_value;
|
Class::Internal::ClassBase * m_class = nullptr;
|
||||||
|
|
||||||
//! \~english Unit type
|
|
||||||
//! \~russian Тип единицы
|
|
||||||
int m_type;
|
|
||||||
|
|
||||||
//! \~english Class pointer
|
|
||||||
//! \~russian Указатель на класс
|
|
||||||
Class::Internal::ClassBase * m_class;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace PIUnits
|
}; // namespace PIUnits
|
||||||
|
|
||||||
//! \~english Output stream operator
|
|
||||||
//! \~russian Оператор вывода в поток
|
|
||||||
inline PICout operator<<(PICout s, const PIUnits::Value & v) {
|
inline PICout operator<<(PICout s, const PIUnits::Value & v) {
|
||||||
s << v.toString();
|
s << v.toString();
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
@@ -379,6 +379,419 @@ TEST_F(Vector2DTest, addRow_with_shorter_vector_uses_min) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== APPEND ROWS TESTS ====================
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendRows_adds_rows_at_bottom) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
vec.appendRows(5, 42);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows + 5);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols);
|
||||||
|
|
||||||
|
// Original data preserved
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = 0; c < oldCols; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New rows filled with 42
|
||||||
|
for (size_t r = oldRows; r < vec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < oldCols; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendRows_with_zero_count_does_nothing) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
vec.appendRows(0);
|
||||||
|
EXPECT_EQ(vec, oldVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendRows_on_empty_matrix) {
|
||||||
|
PIVector2D<int> empty;
|
||||||
|
empty.appendRows(5, 99);
|
||||||
|
EXPECT_TRUE(empty.isNotEmpty());
|
||||||
|
EXPECT_EQ(empty.rows(), 5);
|
||||||
|
EXPECT_EQ(empty.cols(), 1);
|
||||||
|
EXPECT_EQ(empty.size(), empty.entries(99));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendRows_with_default_value) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
|
||||||
|
vec.appendRows(3);
|
||||||
|
|
||||||
|
for (size_t r = oldRows; r < vec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < vec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== APPEND COLUMNS TESTS ====================
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendColumns_adds_columns_at_right) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
vec.appendColumns(3, 99);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols + 3);
|
||||||
|
|
||||||
|
// Original data preserved in original columns
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = 0; c < oldCols; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New columns filled with 99
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = oldCols; c < vec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), 99);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendColumns_with_zero_count_does_nothing) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
vec.appendColumns(0);
|
||||||
|
EXPECT_EQ(vec, oldVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendColumns_on_empty_matrix) {
|
||||||
|
PIVector2D<int> empty;
|
||||||
|
empty.appendColumns(5, 99);
|
||||||
|
EXPECT_TRUE(empty.isNotEmpty());
|
||||||
|
EXPECT_EQ(empty.cols(), 5);
|
||||||
|
EXPECT_EQ(empty.rows(), 1);
|
||||||
|
EXPECT_EQ(empty.size(), empty.entries(99));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, appendColumns_single_column) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
|
||||||
|
vec.appendColumns(1, 77);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldVec.rows());
|
||||||
|
EXPECT_EQ(vec.cols(), oldVec.cols() + 1);
|
||||||
|
|
||||||
|
// Check original data
|
||||||
|
for (size_t r = 0; r < vec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < oldVec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), oldVec.element(r, c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check new column
|
||||||
|
for (size_t r = 0; r < vec.rows(); ++r) {
|
||||||
|
EXPECT_EQ(vec.element(r, oldVec.cols()), 77);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== DELETE ROWS TESTS ====================
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteRows_removes_rows_from_middle) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
vec.deleteRows(5, 3);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows - 3);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols);
|
||||||
|
|
||||||
|
// Rows before deleted remain
|
||||||
|
for (size_t r = 0; r < 5; ++r) {
|
||||||
|
for (size_t c = 0; c < oldCols; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rows after deleted shifted up
|
||||||
|
for (size_t r = 5; r < vec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < oldCols; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>((r + 3) * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteRows_at_end_works) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
vec.deleteRows(oldRows - 2, 2);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows - 2);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols);
|
||||||
|
|
||||||
|
// All remaining rows should have original content
|
||||||
|
for (size_t r = 0; r < vec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < oldCols; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteRows_beyond_bounds_is_limited) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
size_t count = 10;
|
||||||
|
|
||||||
|
vec.deleteRows(oldRows - 2, count);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows - count);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols);
|
||||||
|
|
||||||
|
// All remaining rows should have original content
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = 0; c < vec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All new rows should have original content
|
||||||
|
for (size_t r = oldRows; r < vec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < vec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>((r+count) * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteRows_invalid_start_does_nothing) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
vec.deleteRows(oldVec.rows() + 10, 2);
|
||||||
|
EXPECT_EQ(vec, oldVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteRows_zero_count_does_nothing) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
vec.deleteRows(5, 0);
|
||||||
|
EXPECT_EQ(vec, oldVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteRows_all_rows_creates_empty) {
|
||||||
|
vec.deleteRows(0, vec.rows());
|
||||||
|
EXPECT_TRUE(vec.isEmpty());
|
||||||
|
EXPECT_EQ(vec.rows(), 0);
|
||||||
|
EXPECT_EQ(vec.cols(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== DELETE COLUMNS TESTS ====================
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteColumns_removes_columns_from_middle) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
vec.deleteColumns(4, 3);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols - 3);
|
||||||
|
|
||||||
|
// Columns before deleted remain
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = 0; c < 4; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Columns after deleted shifted left
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = 4; c < vec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c + 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteColumns_at_end_works) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
vec.deleteColumns(oldCols - 2, 2);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols - 2);
|
||||||
|
|
||||||
|
// All remaining columns should have original content
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = 0; c < vec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteColumns_beyond_bounds_is_limited) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
vec.deleteColumns(oldCols - 2, 10);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteColumns_invalid_start_does_nothing) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
vec.deleteColumns(oldVec.cols() + 10, 2);
|
||||||
|
EXPECT_EQ(vec, oldVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteColumns_zero_count_does_nothing) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
vec.deleteColumns(5, 0);
|
||||||
|
EXPECT_EQ(vec, oldVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, deleteColumns_all_columns_preserves_rows) {
|
||||||
|
vec.deleteColumns(0, vec.cols());
|
||||||
|
EXPECT_EQ(vec.rows(), ROWS_COUNT_INIT);
|
||||||
|
EXPECT_EQ(vec.cols(), 0);
|
||||||
|
EXPECT_EQ(vec.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== ADD COLUMN TESTS ====================
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_appends_column_to_empty) {
|
||||||
|
PIVector2D<int> empty;
|
||||||
|
PIVector<int> newCol(5);
|
||||||
|
for (size_t i = 0; i < 5; ++i)
|
||||||
|
newCol[i] = static_cast<int>(100 + i);
|
||||||
|
|
||||||
|
empty.addColumn(newCol);
|
||||||
|
|
||||||
|
EXPECT_EQ(empty.rows(), 5);
|
||||||
|
EXPECT_EQ(empty.cols(), 1);
|
||||||
|
for (size_t r = 0; r < 5; ++r) {
|
||||||
|
EXPECT_EQ(empty.element(r, 0), static_cast<int>(100 + r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_appends_column_to_existing) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
PIVector<int> newCol(oldRows, [](size_t i){return -900 - (int)i;});
|
||||||
|
vec.addColumn(newCol);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.rows(), oldRows);
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols + 1);
|
||||||
|
|
||||||
|
// Check that old data is preserved
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
for (size_t c = 0; c < oldCols; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), static_cast<int>(r * COLS_COUNT_INIT + c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check new column
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
EXPECT_EQ(vec.element(r, oldCols), -900 - (int)r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_with_shorter_vector_uses_min) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
size_t shortLen = oldRows - 10;
|
||||||
|
PIVector<int> shortCol(shortLen, 777);
|
||||||
|
|
||||||
|
vec.addColumn(shortCol);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols + 1);
|
||||||
|
|
||||||
|
// First shortLen rows should be 777
|
||||||
|
for (size_t r = 0; r < shortLen; ++r) {
|
||||||
|
EXPECT_EQ(vec.element(r, oldCols), 777);
|
||||||
|
}
|
||||||
|
// Remaining rows should be default-initialized (0)
|
||||||
|
for (size_t r = shortLen; r < oldRows; ++r) {
|
||||||
|
EXPECT_EQ(vec.element(r, oldCols), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_with_longer_vector_truncates) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
size_t longLen = oldRows + 10;
|
||||||
|
PIVector<int> longCol(longLen, 555);
|
||||||
|
|
||||||
|
vec.addColumn(longCol);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.cols(), oldCols + 1);
|
||||||
|
|
||||||
|
// All rows should be 555 (only first oldRows elements are used)
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
EXPECT_EQ(vec.element(r, oldCols), 555);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_with_empty_source_does_nothing_on_empty) {
|
||||||
|
PIVector2D<int> empty;
|
||||||
|
PIVector<int> emptyCol;
|
||||||
|
|
||||||
|
empty.addColumn(emptyCol);
|
||||||
|
EXPECT_TRUE(empty.isEmpty());
|
||||||
|
EXPECT_EQ(empty.rows(), 0);
|
||||||
|
EXPECT_EQ(empty.cols(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_with_empty_source_adds_default_column) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
|
||||||
|
vec.addColumn({});
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.cols(), oldVec.cols());
|
||||||
|
EXPECT_EQ(vec.rows(), oldVec.rows());
|
||||||
|
|
||||||
|
for (size_t r = 0; r < oldVec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < oldVec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), oldVec.element(r, c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_with_Col_proxy_works) {
|
||||||
|
auto oldVec = vec;
|
||||||
|
const size_t colIndex = 5;
|
||||||
|
|
||||||
|
auto srcCol = oldVec.col(colIndex);
|
||||||
|
vec.addColumn(srcCol);
|
||||||
|
|
||||||
|
EXPECT_EQ(vec.cols(), oldVec.cols() + 1);
|
||||||
|
EXPECT_EQ(vec.rows(), oldVec.rows());
|
||||||
|
|
||||||
|
for (size_t r = 0; r < oldVec.rows(); ++r) {
|
||||||
|
for (size_t c = 0; c < oldVec.cols(); ++c) {
|
||||||
|
EXPECT_EQ(vec.element(r, c), oldVec.element(r, c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t r = 0; r < vec.rows(); ++r) {
|
||||||
|
// EXPECT_EQ(vec.element(r, oldVec.cols()), int());
|
||||||
|
EXPECT_EQ(vec.element(r, oldVec.cols()), oldVec.element(r, colIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, addColumn_with_ColConst_proxy_works) {
|
||||||
|
size_t oldRows = vec.rows();
|
||||||
|
size_t oldCols = vec.cols();
|
||||||
|
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto srcCol = constVec.col(7);
|
||||||
|
// Need a non-const array to add to
|
||||||
|
PIVector2D<int> mutableVec = vec; // copy
|
||||||
|
mutableVec.addColumn(srcCol);
|
||||||
|
|
||||||
|
EXPECT_EQ(mutableVec.cols(), oldCols + 1);
|
||||||
|
|
||||||
|
for (size_t r = 0; r < oldRows; ++r) {
|
||||||
|
EXPECT_EQ(mutableVec.element(r, oldCols), vec.element(r, 7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== RESIZE TESTS ====================
|
// ==================== RESIZE TESTS ====================
|
||||||
class Vector2DResizeTest: public Vector2DTest {
|
class Vector2DResizeTest: public Vector2DTest {
|
||||||
protected:
|
protected:
|
||||||
@@ -470,17 +883,15 @@ TEST_F(Vector2DTest, contains_finds_element_in_flat_vector) {
|
|||||||
TEST_F(Vector2DTest, contains_with_start_parameter_works) {
|
TEST_F(Vector2DTest, contains_with_start_parameter_works) {
|
||||||
int target = 10 * COLS_COUNT_INIT + 15;
|
int target = 10 * COLS_COUNT_INIT + 15;
|
||||||
EXPECT_TRUE(vec.contains(target));
|
EXPECT_TRUE(vec.contains(target));
|
||||||
EXPECT_TRUE(vec.contains(target, target)); // start exactly at target (inclusive)
|
|
||||||
EXPECT_FALSE(vec.contains(target, target + 1)); // start after target
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(Vector2DTest, contains_vector_of_elements_works) {
|
TEST_F(Vector2DTest, contains_vector_of_elements_works) {
|
||||||
PIVector<int> searchFor;
|
PIVector<int> searchFor;
|
||||||
searchFor << 100 << 200 << 300;
|
searchFor << 100 << 200 << 300;
|
||||||
EXPECT_TRUE(vec.contains(searchFor));
|
EXPECT_TRUE(vec.asPlainVector().containsAll(searchFor));
|
||||||
|
|
||||||
searchFor << -999;
|
searchFor << -999;
|
||||||
EXPECT_FALSE(vec.contains(searchFor));
|
EXPECT_FALSE(vec.asPlainVector().containsAll(searchFor));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(Vector2DTest, entries_counts_occurrences) {
|
TEST_F(Vector2DTest, entries_counts_occurrences) {
|
||||||
@@ -652,6 +1063,53 @@ TEST_F(Vector2DTest, transposed_returns_correct_dimensions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DTransposeTest, emptyMatrix_returnsEmpty) {
|
||||||
|
PIVector2D<int> empty;
|
||||||
|
auto transposed = empty.transposed();
|
||||||
|
EXPECT_TRUE(transposed.isEmpty());
|
||||||
|
EXPECT_EQ(transposed.rows(), 0);
|
||||||
|
EXPECT_EQ(transposed.cols(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DTransposeTest, singleElement_returnsSame) {
|
||||||
|
PIVector2D<int> single(1, 1, 42);
|
||||||
|
auto transposed = single.transposed();
|
||||||
|
EXPECT_EQ(transposed.rows(), 1);
|
||||||
|
EXPECT_EQ(transposed.cols(), 1);
|
||||||
|
EXPECT_EQ(transposed.element(0, 0), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DTransposeTest, oneRow_becomesOneColumn) {
|
||||||
|
PIVector2D<int> rowVec(1, 5);
|
||||||
|
for (size_t c = 0; c < 5; ++c)
|
||||||
|
rowVec.element(0, c) = static_cast<int>(c);
|
||||||
|
auto transposed = rowVec.transposed();
|
||||||
|
EXPECT_EQ(transposed.rows(), 5);
|
||||||
|
EXPECT_EQ(transposed.cols(), 1);
|
||||||
|
for (size_t r = 0; r < 5; ++r) {
|
||||||
|
EXPECT_EQ(transposed.element(r, 0), static_cast<int>(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DTransposeTest, oneColumn_becomesOneRow) {
|
||||||
|
PIVector2D<int> colVec(5, 1);
|
||||||
|
for (size_t r = 0; r < 5; ++r)
|
||||||
|
colVec.element(r, 0) = static_cast<int>(r);
|
||||||
|
auto transposed = colVec.transposed();
|
||||||
|
EXPECT_EQ(transposed.rows(), 1);
|
||||||
|
EXPECT_EQ(transposed.cols(), 5);
|
||||||
|
for (size_t c = 0; c < 5; ++c) {
|
||||||
|
EXPECT_EQ(transposed.element(0, c), static_cast<int>(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, transposed_doesNotModifyOriginal) {
|
||||||
|
auto original = vec; // копия для сравнения
|
||||||
|
auto transposed = vec.transposed();
|
||||||
|
// Проверяем, что исходный массив не изменился
|
||||||
|
EXPECT_EQ(vec, original);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(Vector2DTest, reverseRows_reverses_row_order) {
|
TEST_F(Vector2DTest, reverseRows_reverses_row_order) {
|
||||||
auto original = vec;
|
auto original = vec;
|
||||||
vec.reverseRows();
|
vec.reverseRows();
|
||||||
@@ -767,36 +1225,36 @@ TEST_F(Vector2DTest, forEach_modifying_changes_elements) {
|
|||||||
|
|
||||||
TEST_F(Vector2DTest, indexOf_returns_correct_pair) {
|
TEST_F(Vector2DTest, indexOf_returns_correct_pair) {
|
||||||
auto p = vec.indexOf(vec.element(10, 15));
|
auto p = vec.indexOf(vec.element(10, 15));
|
||||||
EXPECT_EQ(p.first, 10);
|
EXPECT_EQ(p.row, 10);
|
||||||
EXPECT_EQ(p.second, 15);
|
EXPECT_EQ(p.col, 15);
|
||||||
p = vec.indexOf(-999);
|
p = vec.indexOf(-999);
|
||||||
EXPECT_EQ(p.first, -1);
|
EXPECT_EQ(p.row, -1);
|
||||||
EXPECT_EQ(p.second, -1);
|
EXPECT_EQ(p.col, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(Vector2DTest, indexWhere_returns_correct_pair) {
|
TEST_F(Vector2DTest, indexWhere_returns_correct_pair) {
|
||||||
vec.element(5, 5) = -42;
|
vec.element(5, 5) = -42;
|
||||||
auto isTarget = [](const int & e) { return e == -42; };
|
auto isTarget = [](const int & e) { return e == -42; };
|
||||||
auto p = vec.indexWhere(isTarget);
|
auto p = vec.indexWhere(isTarget);
|
||||||
EXPECT_EQ(p.first, 5);
|
EXPECT_EQ(p.row, 5);
|
||||||
EXPECT_EQ(p.second, 5);
|
EXPECT_EQ(p.col, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(Vector2DTest, lastIndexOf_works) {
|
TEST_F(Vector2DTest, lastIndexOf_works) {
|
||||||
int val = vec.element(10, 10);
|
int val = vec.element(10, 10);
|
||||||
vec.element(20, 20) = val; // duplicate
|
vec.element(20, 20) = val; // duplicate
|
||||||
auto p = vec.lastIndexOf(val);
|
auto p = vec.lastIndexOf(val);
|
||||||
EXPECT_EQ(p.first, 20);
|
EXPECT_EQ(p.row, 20);
|
||||||
EXPECT_EQ(p.second, 20);
|
EXPECT_EQ(p.col, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(Vector2DTest, lastIndexWhere_works) {
|
TEST_F(Vector2DTest, lastIndexWhere_works) {
|
||||||
auto isLarge = [](const int & e) { return e > 500; };
|
auto isLarge = [](const int & e) { return e > 500; };
|
||||||
auto p = vec.lastIndexWhere(isLarge);
|
auto p = vec.lastIndexWhere(isLarge);
|
||||||
EXPECT_GE(p.first, 0);
|
EXPECT_GE(p.row, 0);
|
||||||
EXPECT_GE(p.second, 0);
|
EXPECT_GE(p.col, 0);
|
||||||
// The last element with value >500 should be the largest index
|
// The last element with value >500 should be the largest index
|
||||||
size_t lastFlat = p.first * vec.cols() + p.second;
|
size_t lastFlat = p.row * vec.cols() + p.col;
|
||||||
size_t expectedLastFlat = vec.size() - 1;
|
size_t expectedLastFlat = vec.size() - 1;
|
||||||
EXPECT_EQ(lastFlat, expectedLastFlat);
|
EXPECT_EQ(lastFlat, expectedLastFlat);
|
||||||
}
|
}
|
||||||
@@ -993,6 +1451,242 @@ TEST(Vector2DEdgeTest, single_element_vector) {
|
|||||||
EXPECT_EQ(single.element(0, 0), 42);
|
EXPECT_EQ(single.element(0, 0), 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== PROXY ADDITIONAL OPERATIONS TESTS ====================
|
||||||
|
TEST_F(Vector2DTest, row_proxy_forEach_modifies_elements) {
|
||||||
|
auto row = vec[5];
|
||||||
|
row.forEach([](int & e) { e += 100; });
|
||||||
|
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(5, c), 5 * COLS_COUNT_INIT + c + 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, row_proxy_forEach_const_iterates) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto row = constVec[5];
|
||||||
|
size_t count = 0;
|
||||||
|
row.forEach([&count](const int &) { ++count; });
|
||||||
|
EXPECT_EQ(count, COLS_COUNT_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, row_proxy_fill_sets_all_elements) {
|
||||||
|
auto row = vec[12];
|
||||||
|
row.fill(999);
|
||||||
|
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
|
||||||
|
EXPECT_EQ(vec.element(12, c), 999);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, row_proxy_contains_finds_element) {
|
||||||
|
auto row = vec[8];
|
||||||
|
EXPECT_TRUE(row.contains(vec.element(8, 10)));
|
||||||
|
EXPECT_FALSE(row.contains(-999));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, row_proxy_entries_counts_occurrences) {
|
||||||
|
auto row = vec[15];
|
||||||
|
// Add a duplicate
|
||||||
|
int val = vec.element(15, 5);
|
||||||
|
vec.element(15, 20) = val;
|
||||||
|
EXPECT_EQ(row.entries(val), 2);
|
||||||
|
EXPECT_EQ(row.entries(-999), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, row_proxy_entries_with_predicate_counts_matches) {
|
||||||
|
auto row = vec[20];
|
||||||
|
auto isEven = [](const int & e) { return e % 2 == 0; };
|
||||||
|
int expected = 0;
|
||||||
|
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
|
||||||
|
if (row[c] % 2 == 0) ++expected;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(row.entries(isEven), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, row_proxy_any_returns_true_if_any_match) {
|
||||||
|
auto row = vec[25];
|
||||||
|
auto isNegative = [](const int & e) { return e < 0; };
|
||||||
|
EXPECT_FALSE(row.any(isNegative));
|
||||||
|
auto isPositive = [](const int & e) { return e >= 0; };
|
||||||
|
EXPECT_TRUE(row.any(isPositive));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, row_proxy_every_returns_true_if_all_match) {
|
||||||
|
auto row = vec[30];
|
||||||
|
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
|
||||||
|
EXPECT_TRUE(row.every(isLessThanMax));
|
||||||
|
auto isEven = [](const int & e) { return e % 2 == 0; };
|
||||||
|
EXPECT_FALSE(row.every(isEven));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
TEST_F(Vector2DTest, col_proxy_forEach_modifies_elements) {
|
||||||
|
auto col = vec.col(7);
|
||||||
|
col.forEach([](int & e) { e += 50; });
|
||||||
|
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
|
||||||
|
EXPECT_EQ(vec.element(r, 7), r * COLS_COUNT_INIT + 7 + 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, col_proxy_forEach_const_iterates) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto col = constVec.col(9);
|
||||||
|
size_t count = 0;
|
||||||
|
col.forEach([&count](const int &) { ++count; });
|
||||||
|
EXPECT_EQ(count, ROWS_COUNT_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, col_proxy_fill_sets_all_elements) {
|
||||||
|
auto col = vec.col(11);
|
||||||
|
col.fill(777);
|
||||||
|
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
|
||||||
|
EXPECT_EQ(vec.element(r, 11), 777);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, col_proxy_contains_finds_element) {
|
||||||
|
auto col = vec.col(13);
|
||||||
|
EXPECT_TRUE(col.contains(vec.element(5, 13)));
|
||||||
|
EXPECT_FALSE(col.contains(-999));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, col_proxy_entries_counts_occurrences) {
|
||||||
|
auto col = vec.col(17);
|
||||||
|
int val = vec.element(3, 17);
|
||||||
|
vec.element(22, 17) = val; // duplicate
|
||||||
|
EXPECT_EQ(col.entries(val), 2);
|
||||||
|
EXPECT_EQ(col.entries(-999), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, col_proxy_entries_with_predicate_counts_matches) {
|
||||||
|
auto col = vec.col(19);
|
||||||
|
auto isOdd = [](const int & e) { return e % 2 != 0; };
|
||||||
|
int expected = 0;
|
||||||
|
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
|
||||||
|
if (col[r] % 2 != 0) ++expected;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(col.entries(isOdd), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, col_proxy_any_returns_true_if_any_match) {
|
||||||
|
auto col = vec.col(21);
|
||||||
|
auto isNegative = [](const int & e) { return e < 0; };
|
||||||
|
EXPECT_FALSE(col.any(isNegative));
|
||||||
|
auto isPositive = [](const int & e) { return e >= 0; };
|
||||||
|
EXPECT_TRUE(col.any(isPositive));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, col_proxy_every_returns_true_if_all_match) {
|
||||||
|
auto col = vec.col(23);
|
||||||
|
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
|
||||||
|
EXPECT_TRUE(col.every(isLessThanMax));
|
||||||
|
auto isEven = [](const int & e) { return e % 2 == 0; };
|
||||||
|
EXPECT_FALSE(col.every(isEven));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
TEST_F(Vector2DTest, rowconst_proxy_forEach_iterates) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto row = constVec[5];
|
||||||
|
size_t count = 0;
|
||||||
|
row.forEach([&count](const int &) { ++count; });
|
||||||
|
EXPECT_EQ(count, COLS_COUNT_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, rowconst_proxy_contains_finds_element) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto row = constVec[6];
|
||||||
|
EXPECT_TRUE(row.contains(vec.element(6, 10)));
|
||||||
|
EXPECT_FALSE(row.contains(-999));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, rowconst_proxy_entries_counts_occurrences) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto row = constVec[7];
|
||||||
|
int val = vec.element(7, 5);
|
||||||
|
// We can't modify through const proxy, but duplicates already exist from previous tests
|
||||||
|
EXPECT_GE(row.entries(val), 1); // at least one
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, rowconst_proxy_entries_with_predicate_counts_matches) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto row = constVec[9];
|
||||||
|
auto isEven = [](const int & e) { return e % 2 == 0; };
|
||||||
|
int expected = 0;
|
||||||
|
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
|
||||||
|
if (vec.element(9, c) % 2 == 0) ++expected;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(row.entries(isEven), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, rowconst_proxy_any_returns_true_if_any_match) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto row = constVec[10];
|
||||||
|
auto isNegative = [](const int & e) { return e < 0; };
|
||||||
|
EXPECT_FALSE(row.any(isNegative));
|
||||||
|
auto isPositive = [](const int & e) { return e >= 0; };
|
||||||
|
EXPECT_TRUE(row.any(isPositive));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, rowconst_proxy_every_returns_true_if_all_match) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto row = constVec[11];
|
||||||
|
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
|
||||||
|
EXPECT_TRUE(row.every(isLessThanMax));
|
||||||
|
auto isEven = [](const int & e) { return e % 2 == 0; };
|
||||||
|
EXPECT_FALSE(row.every(isEven));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
TEST_F(Vector2DTest, colconst_proxy_forEach_iterates) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto col = constVec.col(25);
|
||||||
|
size_t count = 0;
|
||||||
|
col.forEach([&count](const int &) { ++count; });
|
||||||
|
EXPECT_EQ(count, ROWS_COUNT_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, colconst_proxy_contains_finds_element) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto col = constVec.col(27);
|
||||||
|
EXPECT_TRUE(col.contains(vec.element(4, 27)));
|
||||||
|
EXPECT_FALSE(col.contains(-999));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, colconst_proxy_entries_counts_occurrences) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto col = constVec.col(29);
|
||||||
|
int val = vec.element(8, 29);
|
||||||
|
EXPECT_GE(col.entries(val), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, colconst_proxy_entries_with_predicate_counts_matches) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto col = constVec.col(31);
|
||||||
|
auto isOdd = [](const int & e) { return e % 2 != 0; };
|
||||||
|
int expected = 0;
|
||||||
|
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
|
||||||
|
if (vec.element(r, 31) % 2 != 0) ++expected;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(col.entries(isOdd), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, colconst_proxy_any_returns_true_if_any_match) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto col = constVec.col(33);
|
||||||
|
auto isNegative = [](const int & e) { return e < 0; };
|
||||||
|
EXPECT_FALSE(col.any(isNegative));
|
||||||
|
auto isPositive = [](const int & e) { return e >= 0; };
|
||||||
|
EXPECT_TRUE(col.any(isPositive));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, colconst_proxy_every_returns_true_if_all_match) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
auto col = constVec.col(0);
|
||||||
|
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
|
||||||
|
EXPECT_TRUE(col.every(isLessThanMax));
|
||||||
|
auto isNotEven = [](const int & e) { return e % 2 != 0; };
|
||||||
|
EXPECT_FALSE(col.every(isNotEven));
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== OUTPUT TESTS ====================
|
// ==================== OUTPUT TESTS ====================
|
||||||
TEST_F(Vector2DTest, picout_operator_works) {
|
TEST_F(Vector2DTest, picout_operator_works) {
|
||||||
// Just test that it compiles and doesn't crash
|
// Just test that it compiles and doesn't crash
|
||||||
@@ -1010,3 +1704,94 @@ TEST_F(Vector2DTest, iostream_operator_works) {
|
|||||||
// No assertion, just ensure it runs
|
// No assertion, just ensure it runs
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ==================== INDEX STRUCTURE ACCESS TESTS ====================
|
||||||
|
TEST_F(Vector2DTest, operator_bracket_with_index_allows_read_access) {
|
||||||
|
PIVector2D<int>::Index idx = {5, 7};
|
||||||
|
int value = vec[idx];
|
||||||
|
int expected = vec.element(5, 7);
|
||||||
|
EXPECT_EQ(value, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, operator_bracket_with_index_allows_write_access) {
|
||||||
|
PIVector2D<int>::Index idx = {10, 15};
|
||||||
|
vec[idx] = 999;
|
||||||
|
EXPECT_EQ(vec.element(10, 15), 999);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, operator_bracket_with_const_index_works) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
PIVector2D<int>::Index idx = {3, 12};
|
||||||
|
int value = constVec[idx];
|
||||||
|
int expected = vec.element(3, 12);
|
||||||
|
EXPECT_EQ(value, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, element_function_with_index_works) {
|
||||||
|
PIVector2D<int>::Index idx = {8, 20};
|
||||||
|
int value = vec.element(idx);
|
||||||
|
int expected = vec.element(8, 20);
|
||||||
|
EXPECT_EQ(value, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, element_function_with_index_modifies_value) {
|
||||||
|
PIVector2D<int>::Index idx = {12, 8};
|
||||||
|
vec.element(idx) = 555;
|
||||||
|
EXPECT_EQ(vec.element(12, 8), 555);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, element_function_with_const_index_works) {
|
||||||
|
const auto & constVec = vec;
|
||||||
|
PIVector2D<int>::Index idx = {7, 5};
|
||||||
|
int value = constVec.element(idx);
|
||||||
|
int expected = vec.element(7, 5);
|
||||||
|
EXPECT_EQ(value, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, at_function_with_index_works) {
|
||||||
|
PIVector2D<int>::Index idx = {4, 11};
|
||||||
|
int value = vec.at(idx);
|
||||||
|
int expected = vec.at(4, 11);
|
||||||
|
EXPECT_EQ(value, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Vector2DTest, index_structure_with_brace_initialization_works) {
|
||||||
|
vec[{0, 0}] = 100;
|
||||||
|
EXPECT_EQ(vec.element(0, 0), 100);
|
||||||
|
|
||||||
|
vec[{static_cast<ssize_t>(ROWS_COUNT_INIT - 1), static_cast<ssize_t>(COLS_COUNT_INIT - 1)}] = 200;
|
||||||
|
EXPECT_EQ(vec.element(ROWS_COUNT_INIT - 1, COLS_COUNT_INIT - 1), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DIndexTest, default_constructor_initializes_to_invalid) {
|
||||||
|
PIVector2D<int>::Index idx;
|
||||||
|
EXPECT_TRUE(idx.isNotValid());
|
||||||
|
EXPECT_FALSE(idx.isValid());
|
||||||
|
EXPECT_EQ(idx.row, -1);
|
||||||
|
EXPECT_EQ(idx.col, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DIndexTest, parameterized_constructor_initializes_correctly) {
|
||||||
|
PIVector2D<int>::Index idx(5, 10);
|
||||||
|
EXPECT_TRUE(idx.isValid());
|
||||||
|
EXPECT_FALSE(idx.isNotValid());
|
||||||
|
EXPECT_EQ(idx.row, 5);
|
||||||
|
EXPECT_EQ(idx.col, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DIndexTest, isValid_returns_true_for_non_negative_values) {
|
||||||
|
PIVector2D<int>::Index idx(0, 0);
|
||||||
|
EXPECT_TRUE(idx.isValid());
|
||||||
|
EXPECT_FALSE(idx.isNotValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2DIndexTest, isNotValid_returns_true_for_negative_values) {
|
||||||
|
PIVector2D<int>::Index idx1;
|
||||||
|
EXPECT_TRUE(idx1.isNotValid());
|
||||||
|
|
||||||
|
PIVector2D<int>::Index idx2(-1, 5);
|
||||||
|
EXPECT_TRUE(idx2.isNotValid());
|
||||||
|
|
||||||
|
PIVector2D<int>::Index idx3(5, -1);
|
||||||
|
EXPECT_TRUE(idx3.isNotValid());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user