version 5.4.0

remove CORS default header from PIHTTPServer
fix several docs
fix PIMathVector::dot return type
add units directory with PIUnits facility
This commit is contained in:
2025-09-26 21:33:45 +03:00
parent daab41e41e
commit 5db97ca959
30 changed files with 1888 additions and 556 deletions

View File

@@ -13,51 +13,51 @@ public:
};
//! ~english Main HTTP client class for performing requests with event callbacks.
//! ~russian Основной класс HTTP-клиента для выполнения запросов с callback-ми событий.
//! \~english Main HTTP client class for performing requests with event callbacks.
//! \~russian Основной класс HTTP-клиента для выполнения запросов с callback-ми событий.
class PIP_HTTP_CLIENT_EXPORT PIHTTPClient: private PIHTTPClientBase {
friend class PIHTTPClientBase;
friend class CurlThreadPool;
public:
//! ~english Creates a new HTTP request instance with the specified URL, method and message.
//! ~russian Создает новый экземпляр HTTP-запроса с указанным URL, методом и сообщением.
//! \~english Creates a new HTTP request instance with the specified URL, method and message.
//! \~russian Создает новый экземпляр HTTP-запроса с указанным URL, методом и сообщением.
static PIHTTPClient * create(const PIString & url, PIHTTP::Method method = PIHTTP::Method::Get, const PIHTTP::MessageConst & req = {});
//! ~english Sets a callback for successful request completion (no parameters).
//! ~russian Устанавливает callback для успешного завершения запроса (без параметров).
//! \~english Sets a callback for successful request completion (no parameters).
//! \~russian Устанавливает callback для успешного завершения запроса (без параметров).
PIHTTPClient * onFinish(std::function<void()> f);
//! ~english Sets a callback for successful request completion (with response).
//! ~russian Устанавливает callback для успешного завершения запроса (с ответом).
//! \~english Sets a callback for successful request completion (with response).
//! \~russian Устанавливает callback для успешного завершения запроса (с ответом).
PIHTTPClient * onFinish(std::function<void(const PIHTTP::MessageConst &)> f);
//! ~english Sets a callback for request errors (no parameters).
//! ~russian Устанавливает callback для ошибок запроса (без параметров).
//! \~english Sets a callback for request errors (no parameters).
//! \~russian Устанавливает callback для ошибок запроса (без параметров).
PIHTTPClient * onError(std::function<void()> f);
//! ~english Sets a callback for request errors (with error response).
//! ~russian Устанавливает callback для ошибок запроса (с ответом об ошибке).
//! \~english Sets a callback for request errors (with error response).
//! \~russian Устанавливает callback для ошибок запроса (с ответом об ошибке).
PIHTTPClient * onError(std::function<void(const PIHTTP::MessageConst &)> f);
//! ~english Sets a callback for request abortion (no parameters).
//! ~russian Устанавливает callback для прерывания запроса (без параметров).
//! \~english Sets a callback for request abortion (no parameters).
//! \~russian Устанавливает callback для прерывания запроса (без параметров).
PIHTTPClient * onAbort(std::function<void()> f);
//! ~english Sets a callback for request abortion (with abort response).
//! ~russian Устанавливает callback для прерывания запроса (с ответом о прерывании).
//! \~english Sets a callback for request abortion (with abort response).
//! \~russian Устанавливает callback для прерывания запроса (с ответом о прерывании).
PIHTTPClient * onAbort(std::function<void(const PIHTTP::MessageConst &)> f);
//! ~english Starts the HTTP request execution.
//! ~russian Начинает выполнение HTTP-запроса.
//! \~english Starts the HTTP request execution.
//! \~russian Начинает выполнение HTTP-запроса.
void start();
//! ~english Aborts the current HTTP request.
//! ~russian Прерывает текущий HTTP-запрос.
//! \~english Aborts the current HTTP request.
//! \~russian Прерывает текущий HTTP-запрос.
void abort();
//! ~english Returns the last error message.
//! ~russian Возвращает последнее сообщение об ошибке.
//! \~english Returns the last error message.
//! \~russian Возвращает последнее сообщение об ошибке.
PIString lastError() const { return last_error; }
private:

View File

@@ -9,68 +9,68 @@
namespace PIHTTP {
//! ~english Immutable HTTP message container with accessors for message components
//! ~russian Контейнер для неизменяемого HTTP-сообщения с методами доступа к компонентам
//! \~english Immutable HTTP message container with accessors for message components
//! \~russian Контейнер для неизменяемого HTTP-сообщения с методами доступа к компонентам
class PIP_EXPORT MessageConst {
public:
//! ~english Gets the HTTP method used in the message
//! ~russian Возвращает HTTP-метод, использованный в сообщении
//! \~english Gets the HTTP method used in the message
//! \~russian Возвращает HTTP-метод, использованный в сообщении
PIHTTP::Method method() const { return m_method; }
//! ~english Gets the HTTP status code
//! ~russian Возвращает HTTP-статус код
//! \~english Gets the HTTP status code
//! \~russian Возвращает HTTP-статус код
PIHTTP::Code code() const { return m_code; }
//! ~english Checks if status code is informational (1xx)
//! ~russian Проверяет, является ли статус код информационным (1xx)
//! \~english Checks if status code is informational (1xx)
//! \~russian Проверяет, является ли статус код информационным (1xx)
bool isCodeInformational() const;
//! ~english Checks if status code indicates success (2xx)
//! ~russian Проверяет, указывает ли статус код на успех (2xx)
//! \~english Checks if status code indicates success (2xx)
//! \~russian Проверяет, указывает ли статус код на успех (2xx)
bool isCodeSuccess() const;
//! ~english Checks if status code indicates redirection (3xx)
//! ~russian Проверяет, указывает ли статус код на перенаправление (3xx)
//! \~english Checks if status code indicates redirection (3xx)
//! \~russian Проверяет, указывает ли статус код на перенаправление (3xx)
bool isCodeRedirection() const;
//! ~english Checks if status code indicates client error (4xx)
//! ~russian Проверяет, указывает ли статус код на ошибку клиента (4xx)
//! \~english Checks if status code indicates client error (4xx)
//! \~russian Проверяет, указывает ли статус код на ошибку клиента (4xx)
bool isCodeClientError() const;
//! ~english Checks if status code indicates server error (5xx)
//! ~russian Проверяет, указывает ли статус код на ошибку сервера (5xx)
//! \~english Checks if status code indicates server error (5xx)
//! \~russian Проверяет, указывает ли статус код на ошибку сервера (5xx)
bool isCodeServerError() const;
//! ~english Checks if status code indicates any error (4xx or 5xx)
//! ~russian Проверяет, указывает ли статус код на любую ошибку (4xx или 5xx)
//! \~english Checks if status code indicates any error (4xx or 5xx)
//! \~russian Проверяет, указывает ли статус код на любую ошибку (4xx или 5xx)
bool isCodeError() const { return isCodeClientError() || isCodeServerError(); }
//! ~english Gets the request/response path
//! ~russian Возвращает путь запроса/ответа
//! \~english Gets the request/response path
//! \~russian Возвращает путь запроса/ответа
const PIString & path() const { return m_path; }
//! ~english Gets path components as list
//! ~russian Возвращает компоненты пути в виде списка
//! \~english Gets path components as list
//! \~russian Возвращает компоненты пути в виде списка
PIStringList pathList() const { return m_path.split('/').removeAll({}); }
//! ~english Gets the message body
//! ~russian Возвращает тело сообщения
//! \~english Gets the message body
//! \~russian Возвращает тело сообщения
const PIByteArray & body() const { return m_body; }
//! ~english Gets all message headers
//! ~russian Возвращает все заголовки сообщения
//! \~english Gets all message headers
//! \~russian Возвращает все заголовки сообщения
const PIMap<PIString, PIString> & headers() const { return m_headers; }
//! ~english Gets URL query arguments
//! ~russian Возвращает URL query аргументы
//! \~english Gets URL query arguments
//! \~russian Возвращает URL query аргументы
const PIMap<PIString, PIString> & queryArguments() const { return m_query_arguments; }
//! ~english Gets URL path arguments
//! ~russian Возвращает URL path аргументы
//! \~english Gets URL path arguments
//! \~russian Возвращает URL path аргументы
const PIMap<PIString, PIString> & pathArguments() const { return m_path_arguments; }
//! ~english Gets all message arguments (query + path)
//! ~russian Возвращает все аргументы сообщения (query + path)
//! \~english Gets all message arguments (query + path)
//! \~russian Возвращает все аргументы сообщения (query + path)
const PIMap<PIString, PIString> & arguments() const { return m_arguments; }
protected:
@@ -83,24 +83,24 @@ protected:
};
//! ~english Mutable HTTP message container with modifiers for message components
//! ~russian Контейнер для изменяемого HTTP-сообщения с методами модификации
//! \~english Mutable HTTP message container with modifiers for message components
//! \~russian Контейнер для изменяемого HTTP-сообщения с методами модификации
class PIP_EXPORT MessageMutable: public MessageConst {
public:
//! ~english Sets the HTTP method
//! ~russian Устанавливает HTTP-метод
//! \~english Sets the HTTP method
//! \~russian Устанавливает HTTP-метод
MessageMutable & setMethod(PIHTTP::Method m);
//! ~english Sets the HTTP status code
//! ~russian Устанавливает HTTP-статус код
//! \~english Sets the HTTP status code
//! \~russian Устанавливает HTTP-статус код
MessageMutable & setCode(PIHTTP::Code c);
//! ~english Sets the request/response path
//! ~russian Устанавливает путь запроса/ответа
//! \~english Sets the request/response path
//! \~russian Устанавливает путь запроса/ответа
MessageMutable & setPath(PIString p);
//! ~english Sets the message body
//! ~russian Устанавливает тело сообщения
//! \~english Sets the message body
//! \~russian Устанавливает тело сообщения
MessageMutable & setBody(PIByteArray b);
const PIMap<PIString, PIString> & headers() const { return m_headers; }
@@ -111,50 +111,50 @@ public:
PIMap<PIString, PIString> & headers() { return m_headers; }
//! ~english Adds a header to the message
//! ~russian Добавляет заголовок к сообщению
//! \~english Adds a header to the message
//! \~russian Добавляет заголовок к сообщению
MessageMutable & addHeader(const PIString & header, const PIString & value);
//! ~english Removes a header from the message
//! ~russian Удаляет заголовок из сообщения
//! \~english Removes a header from the message
//! \~russian Удаляет заголовок из сообщения
MessageMutable & removeHeader(const PIString & header);
//! ~english Gets reference to URL query arguments
//! ~russian Возвращает ссылку на URL query аргументы
//! \~english Gets reference to URL query arguments
//! \~russian Возвращает ссылку на URL query аргументы
PIMap<PIString, PIString> & queryArguments() { return m_query_arguments; }
//! ~english Adds an URL query argument to the message
//! ~russian Добавляет URL query аргумент к сообщению
//! \~english Adds an URL query argument to the message
//! \~russian Добавляет URL query аргумент к сообщению
MessageMutable & addQueryArgument(const PIString & arg, const PIString & value);
//! ~english Removes an URL query argument from the message
//! ~russian Удаляет URL query аргумент из сообщения
//! \~english Removes an URL query argument from the message
//! \~russian Удаляет URL query аргумент из сообщения
MessageMutable & removeQueryArgument(const PIString & arg);
//! ~english Gets reference to URL path arguments
//! ~russian Возвращает ссылку на URL path аргументы
//! \~english Gets reference to URL path arguments
//! \~russian Возвращает ссылку на URL path аргументы
PIMap<PIString, PIString> & pathArguments() { return m_path_arguments; }
//! ~english Adds an URL path argument to the message
//! ~russian Добавляет URL path аргумент к сообщению
//! \~english Adds an URL path argument to the message
//! \~russian Добавляет URL path аргумент к сообщению
MessageMutable & addPathArgument(const PIString & arg, const PIString & value);
//! ~english Removes an URL path argument from the message
//! ~russian Удаляет URL query path из сообщения
//! \~english Removes an URL path argument from the message
//! \~russian Удаляет URL query path из сообщения
MessageMutable & removePathArgument(const PIString & arg);
//! ~english Creates message from HTTP status code
//! ~russian Создает сообщение из HTTP-статус кода
//! \~english Creates message from HTTP status code
//! \~russian Создает сообщение из HTTP-статус кода
static MessageMutable fromCode(PIHTTP::Code c);
//! ~english Creates message from HTTP method
//! ~russian Создает сообщение из HTTP-метода
//! \~english Creates message from HTTP method
//! \~russian Создает сообщение из HTTP-метода
static MessageMutable fromMethod(PIHTTP::Method m);
};
//! ~english Gets string representation of HTTP method
//! ~russian Возвращает строковое представление HTTP-метода
//! \~english Gets string representation of HTTP method
//! \~russian Возвращает строковое представление HTTP-метода
PIP_EXPORT const char * methodName(Method m);

View File

@@ -7,8 +7,8 @@
struct MicrohttpdServerConnection;
//! ~english Base HTTP server class implementing core functionality
//! ~runnan Базовый класс HTTP сервера, реализующий основную функциональность
//! \~english Base HTTP server class implementing core functionality
//! \~russian Базовый класс HTTP сервера, реализующий основную функциональность
class PIP_HTTP_SERVER_EXPORT MicrohttpdServer: public PIObject {
PIOBJECT(MicrohttpdServer)
friend struct MicrohttpdServerConnection;
@@ -17,75 +17,75 @@ public:
MicrohttpdServer();
virtual ~MicrohttpdServer();
//! ~english Server configuration options
//! ~russian Опции конфигурации сервера
//! \~english Server configuration options
//! \~russian Опции конфигурации сервера
enum class Option {
ConnectionLimit, //!< ~english Maximum concurrent connections
//!< ~russian Максимальное количество соединений
ConnectionTimeout, //!< ~english Connection timeout in seconds
//!< ~russian Таймаут соединения в секундах
HTTPSEnabled, //!< ~english Enable HTTPS support
//!< ~russian Включить поддержку HTTPS
HTTPSMemKey, //!< ~english SSL key in memory (PIByteArray)
//!< ~russian SSL ключ в памяти (PIByteArray)
HTTPSMemCert, //!< ~english SSL certificate in memory (PIByteArray)
//!< ~russian SSL сертификат в памяти (PIByteArray)
HTTPSKeyPassword //!< ~english SSL key password (PIByteArray)
//!< ~russian Пароль SSL ключа (PIByteArray)
ConnectionLimit, //!< \~english Maximum concurrent connections
//!< \~russian Максимальное количество соединений
ConnectionTimeout, //!< \~english Connection timeout in seconds
//!< \~russian Таймаут соединения в секундах
HTTPSEnabled, //!< \~english Enable HTTPS support
//!< \~russian Включить поддержку HTTPS
HTTPSMemKey, //!< \~english SSL key in memory (PIByteArray)
//!< \~russian SSL ключ в памяти (PIByteArray)
HTTPSMemCert, //!< \~english SSL certificate in memory (PIByteArray)
//!< \~russian SSL сертификат в памяти (PIByteArray)
HTTPSKeyPassword //!< \~english SSL key password (PIByteArray)
//!< \~russian Пароль SSL ключа (PIByteArray)
};
//! ~english Sets server option
//! ~russian Устанавливает опцию сервера
//! \~english Sets server option
//! \~russian Устанавливает опцию сервера
void setOption(Option o, PIVariant v);
//! ~english Sets server favicon
//! ~russian Устанавливает фавикон сервера
//! \~english Sets server favicon
//! \~russian Устанавливает фавикон сервера
void setFavicon(const PIByteArray & im);
//! ~english Starts server on specified address
//! ~russian Запускает сервер на указанном адресе
//! \~english Starts server on specified address
//! \~russian Запускает сервер на указанном адресе
bool listen(PINetworkAddress addr);
//! ~english Starts server on all interfaces
//! ~russian Запускает сервер на всех интерфейсах
//! \~english Starts server on all interfaces
//! \~russian Запускает сервер на всех интерфейсах
bool listenAll(ushort port) { return listen({0, port}); }
//! ~english Checks if server is running
//! ~russian Проверяет, работает ли сервер
//! \~english Checks if server is running
//! \~russian Проверяет, работает ли сервер
bool isListen() const;
//! ~english Stops the server
//! ~russian Останавливает сервер
//! \~english Stops the server
//! \~russian Останавливает сервер
void stop();
//! ~english Enables basic authentication
//! ~russian Включает базовую аутентификацию
//! \~english Enables basic authentication
//! \~russian Включает базовую аутентификацию
void enableBasicAuth() { setBasicAuthEnabled(true); }
//! ~english Disables basic authentication
//! ~russian Выключает базовую аутентификацию
//! \~english Disables basic authentication
//! \~russian Выключает базовую аутентификацию
void disableBasicAuth() { setBasicAuthEnabled(false); }
//! ~english Set basic authentication enabled to "yes"
//! ~russian Устанавливает базовую аутентификацию в "yes"
//! \~english Set basic authentication enabled to "yes"
//! \~russian Устанавливает базовую аутентификацию в "yes"
void setBasicAuthEnabled(bool yes) { use_basic_auth = yes; }
//! ~english Return if basic authentication enabled
//! ~russian Возвращает включена ли базовая аутентификация
//! \~english Return if basic authentication enabled
//! \~russian Возвращает включена ли базовая аутентификация
bool isBasicAuthEnabled() const { return use_basic_auth; }
//! ~english Sets basic authentication realm
//! ~russian Устанавливает область аутентификации
//! \~english Sets basic authentication realm
//! \~russian Устанавливает область аутентификации
void setBasicAuthRealm(const PIString & r) { realm = r; }
//! ~english Sets request processing callback
//! ~russian Устанавливает callback для обработки запросов
//! \~english Sets request processing callback
//! \~russian Устанавливает callback для обработки запросов
void setRequestCallback(std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)> c) { callback = c; }
//! ~english Sets basic authentication callback
//! ~russian Устанавливает callback для базовой аутентификации
//! \~english Sets basic authentication callback
//! \~russian Устанавливает callback для базовой аутентификации
void setBasicAuthCallback(std::function<bool(const PIString &, const PIString &)> c) { callback_auth = c; }
private:

View File

@@ -3,8 +3,8 @@
#include "microhttpd_server.h"
//! ~english HTTP server
//! ~russian HTTP сервер
//! \~english HTTP server
//! \~russian HTTP сервер
class PIP_HTTP_SERVER_EXPORT PIHTTPServer: public MicrohttpdServer {
PIOBJECT_SUBCLASS(PIHTTPServer, MicrohttpdServer)
@@ -15,12 +15,12 @@ public:
using RequestFunction = std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)>;
//! ~english Registers handler for specific path and HTTP method
//! ~russian Регистрирует обработчик для указанного пути и HTTP метода
//! \~english Registers handler for specific path and HTTP method
//! \~russian Регистрирует обработчик для указанного пути и HTTP метода
bool registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor);
//! ~english Registers handler for specific path and HTTP method
//! ~russian Регистрирует обработчик для указанного пути и HTTP метода
//! \~english Registers handler for specific path and HTTP method
//! \~russian Регистрирует обработчик для указанного пути и HTTP метода
template<typename T>
bool
registerPath(const PIString & path, PIHTTP::Method method, T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) {
@@ -28,36 +28,36 @@ public:
}
//! ~english Registers handler for unregistered pathes
//! ~russian Регистрирует обработчик для незарегистрированных путей
//! \~english Registers handler for unregistered pathes
//! \~russian Регистрирует обработчик для незарегистрированных путей
void registerUnhandled(RequestFunction functor);
//! ~english Registers handler for unregistered pathes
//! ~russian Регистрирует обработчик для незарегистрированных путей
//! \~english Registers handler for unregistered pathes
//! \~russian Регистрирует обработчик для незарегистрированных путей
template<typename T>
void registerUnhandled(T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) {
registerUnhandled([o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); });
}
//! ~english Unregisters handler for specific path and method
//! ~russian Удаляет обработчик для указанного пути и метода
//! \~english Unregisters handler for specific path and method
//! \~russian Удаляет обработчик для указанного пути и метода
void unregisterPath(const PIString & path, PIHTTP::Method method);
//! ~english Unregisters all handlers for specific path
//! ~russian Удаляет все обработчики для указанного пути
//! \~english Unregisters all handlers for specific path
//! \~russian Удаляет все обработчики для указанного пути
void unregisterPath(const PIString & path);
//! ~english Adds header to all server responses
//! ~russian Добавляет заголовок ко всем ответам сервера
//! \~english Adds header to all server responses
//! \~russian Добавляет заголовок ко всем ответам сервера
void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; }
//! ~english Removes header from server responses
//! ~russian Удаляет заголовок из ответов сервера
//! \~english Removes header from server responses
//! \~russian Удаляет заголовок из ответов сервера
void removeReplyHeader(const PIString & name) { reply_headers.remove(name); }
//! ~english Clears all custom response headers
//! ~russian Очищает все пользовательские заголовки ответов
//! \~english Clears all custom response headers
//! \~russian Очищает все пользовательские заголовки ответов
void clearReplyHeaders() { reply_headers.clear(); }
private:

View File

@@ -315,7 +315,7 @@ public:
}
static _CVector cross(const _CVector & v1, const _CVector & v2) { return v1.cross(v2); }
static _CVector dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); }
static Type dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); }
static _CVector mul(const _CVector & v1, const _CVector & v2) { return v1.mul(v2); }
static _CVector mul(const Type & v1, const _CVector & v2) { return v2 * v1; }
static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; }
@@ -581,7 +581,7 @@ public:
static _CVector cross(const _CVector & v1, const _CVector & v2) { return v1.cross(v2); }
static _CVector dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); }
static Type dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); }
static _CVector mul(const _CVector & v1, const _CVector & v2) { return v1.mul(v2); }
static _CVector mul(const Type & v1, const _CVector & v2) { return v2 * v1; }
static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; }

37
libs/main/units/piunits.h Normal file
View File

@@ -0,0 +1,37 @@
/*! \file piunits.h
* \ingroup Core
* \~\brief
* \~english Unit conversions
* \~russian Преобразование единиц измерения
*/
/*
PIP - Platform Independent Primitives
Unit conversions
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_H
#define PIUNITS_H
#include "piunits_class_angle.h"
#include "piunits_class_distance.h"
#include "piunits_class_information.h"
#include "piunits_class_pressure.h"
#include "piunits_class_temperature.h"
#include "piunits_class_time.h"
#include "piunits_value.h"
#endif

View File

@@ -0,0 +1,52 @@
/*
PIP - Platform Independent Primitives
Unit conversions
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_base.h"
#include "piliterals_string.h"
PIMap<int, PIUnits::Class::Internal::ClassBase *> PIUnits::Class::Internal::typeClasses;
PIVector<PIUnits::Class::Internal::ClassBase *> PIUnits::Class::Internal::allTypeClasses;
const PIString PIUnits::Class::Internal::unknown = "?"_a;
PIString PIUnits::className(int type) {
auto * uc = Class::Internal::typeClasses.value(type);
if (!uc) return Class::Internal::unknown;
return uc->className();
}
PIString PIUnits::name(int type) {
auto * uc = Class::Internal::typeClasses.value(type);
if (!uc) return Class::Internal::unknown;
return uc->name(type);
}
PIString PIUnits::unit(int type) {
auto * uc = Class::Internal::typeClasses.value(type);
if (!uc) return Class::Internal::unknown;
return uc->unit(type);
}
PIVector<PIUnits::Class::Internal::ClassBase *> PIUnits::allClasses() {
return Class::Internal::allTypeClasses;
}

View File

@@ -0,0 +1,124 @@
/*! \file piunits_base.h
* \ingroup Core
* \~\brief
* \~english Unit conversions
* \~russian Преобразование единиц измерения
*/
/*
PIP - Platform Independent Primitives
Unit conversions
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_BASE_H
#define PIUNITS_BASE_H
#include "pitranslator.h"
#define DECLARE_UNIT_CLASS_BEGIN(Name, StartIndex) \
namespace PIUnits { \
namespace Class { \
class PIP_EXPORT Name \
: public Internal::ClassBase \
, public Internal::Registrator<Name> { \
private: \
friend class Internal::Registrator<Name>; \
constexpr static int typeStart = StartIndex; \
PIString name(int type) const override; \
PIString unit(int type) const override; \
PIString valueToString(double v, char format, int prec) const override; \
double convert(double v, int from, int to) const override; \
bool supportPrefixes(int type) const override; \
bool supportPrefixesNon3(int type) const override; \
bool supportPrefixesGreater(int type) const override; \
bool supportPrefixesSmaller(int type) const override; \
\
public: \
PIString className() const override { \
return piTr(#Name, "PIUnits"); \
} \
uint classID() const override { \
static uint ret = PIStringAscii(#Name).hash(); \
return ret; \
}
#define DECLARE_UNIT_CLASS_END(Name) \
} \
; \
} \
} \
STATIC_INITIALIZER_BEGIN \
PIUnits::Class::Name::registerSelf(); \
STATIC_INITIALIZER_END
namespace PIUnits {
PIP_EXPORT PIString className(int type);
PIP_EXPORT PIString name(int type);
PIP_EXPORT PIString unit(int type);
namespace Class {
enum {
Invalid = -1
};
class PIP_EXPORT Internal {
public:
class PIP_EXPORT ClassBase {
public:
virtual uint classID() const = 0;
virtual PIString className() const = 0;
virtual PIString name(int type) const = 0;
virtual PIString unit(int type) const = 0;
virtual PIString valueToString(double v, char format = 'g', int prec = 5) const = 0;
virtual double convert(double v, int from, int to) const = 0;
virtual bool supportPrefixes(int type) const { return true; }
virtual bool supportPrefixesNon3(int type) const { return false; }
virtual bool supportPrefixesGreater(int type) const { return true; }
virtual bool supportPrefixesSmaller(int type) const { return true; }
const PIVector<int> & allTypes() const { return types; }
protected:
PIVector<int> types;
};
template<typename P>
class Registrator {
public:
static void registerSelf() {
auto * uc = new P();
for (int t = P::typeStart; t < P::_LastType; ++t) {
uc->types << t;
Internal::typeClasses[t] = uc;
}
if (!Internal::allTypeClasses.contains(uc)) Internal::allTypeClasses << uc;
}
};
static PIMap<int, ClassBase *> typeClasses;
static PIVector<ClassBase *> allTypeClasses;
static const PIString unknown;
};
} // namespace Class
PIP_EXPORT PIVector<Class::Internal::ClassBase *> allClasses();
} // namespace PIUnits
#endif

View File

@@ -0,0 +1,74 @@
/*
PIP - Platform Independent Primitives
Angle units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_class_angle.h"
#include "pimathbase.h"
PIString PIUnits::Class::Angle::name(int type) const {
switch (type) {
case Degree: return "degree"_tr("PIUnitsAngle");
case Radian: return "radian"_tr("PIUnitsAngle");
}
return Class::Internal::unknown;
}
PIString PIUnits::Class::Angle::unit(int type) const {
switch (type) {
case Degree: return "°"_tr("PIUnitsAngle");
case Radian: return "rad"_tr("PIUnitsAngle");
}
return Class::Internal::unknown;
}
double PIUnits::Class::Angle::convert(double v, int from, int to) const {
switch (to) {
case Degree: return toDeg(v);
case Radian: return toRad(v);
}
return v;
}
PIString PIUnits::Class::Angle::valueToString(double v, char format, int prec) const {
return PIString::fromNumber(v, format, prec);
}
bool PIUnits::Class::Angle::supportPrefixes(int type) const {
return false;
}
bool PIUnits::Class::Angle::supportPrefixesNon3(int type) const {
return false;
}
bool PIUnits::Class::Angle::supportPrefixesGreater(int type) const {
return ClassBase::supportPrefixesGreater(type);
}
bool PIUnits::Class::Angle::supportPrefixesSmaller(int type) const {
return ClassBase::supportPrefixesSmaller(type);
}

View File

@@ -0,0 +1,39 @@
/*! \file piunits_class_angle.h
* \ingroup Core
* \~\brief
* \~english Angle units
* \~russian Единицы измерения угла
*/
/*
PIP - Platform Independent Primitives
Angle units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_CLASS_ANGLE_H
#define PIUNITS_CLASS_ANGLE_H
#include "piunits_base.h"
DECLARE_UNIT_CLASS_BEGIN(Angle, 0x200)
enum {
Degree = typeStart,
Radian,
_LastType,
};
DECLARE_UNIT_CLASS_END(Angle)
#endif

View File

@@ -0,0 +1,69 @@
/*
PIP - Platform Independent Primitives
Distance units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_class_distance.h"
PIString PIUnits::Class::Distance::name(int type) const {
switch (type) {
case Meter: return "meter"_tr("PIUnitsDistance");
}
return Class::Internal::unknown;
}
PIString PIUnits::Class::Distance::unit(int type) const {
switch (type) {
case Meter: return "m"_tr("PIUnitsDistance");
}
return Class::Internal::unknown;
}
double PIUnits::Class::Distance::convert(double v, int from, int to) const {
switch (to) {
case Meter: return v;
}
return v;
}
PIString PIUnits::Class::Distance::valueToString(double v, char format, int prec) const {
return PIString::fromNumber(v, format, prec);
}
bool PIUnits::Class::Distance::supportPrefixes(int type) const {
return true;
}
bool PIUnits::Class::Distance::supportPrefixesNon3(int type) const {
return true;
}
bool PIUnits::Class::Distance::supportPrefixesGreater(int type) const {
return ClassBase::supportPrefixesGreater(type);
}
bool PIUnits::Class::Distance::supportPrefixesSmaller(int type) const {
return ClassBase::supportPrefixesSmaller(type);
}

View File

@@ -0,0 +1,38 @@
/*! \file piunits_class_distance.h
* \ingroup Core
* \~\brief
* \~english Distance units
* \~russian Единицы измерения расстояния
*/
/*
PIP - Platform Independent Primitives
Distance units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_CLASS_DISTANCE_H
#define PIUNITS_CLASS_DISTANCE_H
#include "piunits_base.h"
DECLARE_UNIT_CLASS_BEGIN(Distance, 0x600)
enum {
Meter = typeStart,
_LastType,
};
DECLARE_UNIT_CLASS_END(Distance)
#endif

View File

@@ -0,0 +1,72 @@
/*
PIP - Platform Independent Primitives
Information units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_class_information.h"
PIString PIUnits::Class::Information::name(int type) const {
switch (type) {
case Bit: return "bit"_tr("PIUnitsInformation");
case Byte: return "byte"_tr("PIUnitsInformation");
}
return Class::Internal::unknown;
}
PIString PIUnits::Class::Information::unit(int type) const {
switch (type) {
case Bit: return "b"_tr("PIUnitsInformation");
case Byte: return "B"_tr("PIUnitsInformation");
}
return Class::Internal::unknown;
}
double PIUnits::Class::Information::convert(double v, int from, int to) const {
switch (to) {
case Bit: return v * 8;
case Byte: return v / 8;
}
return v;
}
PIString PIUnits::Class::Information::valueToString(double v, char format, int prec) const {
return PIString::fromNumber(static_cast<llong>(v));
}
bool PIUnits::Class::Information::supportPrefixes(int type) const {
return true;
}
bool PIUnits::Class::Information::supportPrefixesNon3(int type) const {
return false;
}
bool PIUnits::Class::Information::supportPrefixesGreater(int type) const {
return true;
}
bool PIUnits::Class::Information::supportPrefixesSmaller(int type) const {
return false;
}

View File

@@ -0,0 +1,39 @@
/*! \file piunits_class_information.h
* \ingroup Core
* \~\brief
* \~english Information units
* \~russian Единицы измерения информации
*/
/*
PIP - Platform Independent Primitives
Information units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_CLASS_INFORMATION_H
#define PIUNITS_CLASS_INFORMATION_H
#include "piunits_base.h"
DECLARE_UNIT_CLASS_BEGIN(Information, 0x100)
enum {
Bit = typeStart,
Byte,
_LastType,
};
DECLARE_UNIT_CLASS_END(Information)
#endif

View File

@@ -0,0 +1,86 @@
/*
PIP - Platform Independent Primitives
Pressure units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_class_pressure.h"
PIString PIUnits::Class::Pressure::name(int type) const {
switch (type) {
case Pascal: return "pascal"_tr("PIUnitsPressure");
case Atmosphere: return "atmosphere"_tr("PIUnitsPressure");
case Bar: return "bar"_tr("PIUnitsPressure");
case MillimetreOfMercury: return "mm Hg"_tr("PIUnitsPressure");
}
return Class::Internal::unknown;
}
PIString PIUnits::Class::Pressure::unit(int type) const {
switch (type) {
case Pascal: return "Pa"_tr("PIUnitsPressure");
case Atmosphere: return "atm"_tr("PIUnitsPressure");
case Bar: return "bar"_tr("PIUnitsPressure");
case MillimetreOfMercury: return "mmHg"_tr("PIUnitsPressure");
}
return Class::Internal::unknown;
}
double PIUnits::Class::Pressure::convert(double v, int from, int to) const {
double pa = v;
switch (from) {
case Atmosphere: pa /= 9.86923E-6; break;
case Bar: pa /= 1.E-5; break;
case MillimetreOfMercury: pa *= 133.322387415; break;
default: break;
}
switch (to) {
case Atmosphere: return pa * 9.86923E-6;
case Bar: return pa * 1.E-5;
case MillimetreOfMercury: return pa / 133.322387415;
default: break;
}
return pa;
}
PIString PIUnits::Class::Pressure::valueToString(double v, char format, int prec) const {
return PIString::fromNumber(v, format, prec);
}
bool PIUnits::Class::Pressure::supportPrefixes(int type) const {
if (type == Pascal) return true;
return false;
}
bool PIUnits::Class::Pressure::supportPrefixesNon3(int type) const {
return false;
}
bool PIUnits::Class::Pressure::supportPrefixesGreater(int type) const {
return ClassBase::supportPrefixesGreater(type);
}
bool PIUnits::Class::Pressure::supportPrefixesSmaller(int type) const {
return ClassBase::supportPrefixesSmaller(type);
}

View File

@@ -0,0 +1,41 @@
/*! \file piunits_class_pressure.h
* \ingroup Core
* \~\brief
* \~english Pressure units
* \~russian Единицы измерения давления
*/
/*
PIP - Platform Independent Primitives
Pressure units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_CLASS_PRESSURE_H
#define PIUNITS_CLASS_PRESSURE_H
#include "piunits_base.h"
DECLARE_UNIT_CLASS_BEGIN(Pressure, 0x500)
enum {
Pascal = typeStart,
Atmosphere,
Bar,
MillimetreOfMercury,
_LastType,
};
DECLARE_UNIT_CLASS_END(Pressure)
#endif

View File

@@ -0,0 +1,82 @@
/*
PIP - Platform Independent Primitives
Temperature units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_class_temperature.h"
PIString PIUnits::Class::Temperature::name(int type) const {
switch (type) {
case Kelvin: return "Kelvin"_tr("PIUnitsTemperature");
case Celsius: return "Celsius"_tr("PIUnitsTemperature");
case Fahrenheit: return "Fahrenheit"_tr("PIUnitsTemperature");
}
return Class::Internal::unknown;
}
PIString PIUnits::Class::Temperature::unit(int type) const {
switch (type) {
case Kelvin: return "K"_tr("PIUnitsTemperature");
case Celsius: return "°C"_tr("PIUnitsTemperature");
case Fahrenheit: return "°F"_tr("PIUnitsTemperature");
}
return Class::Internal::unknown;
}
double PIUnits::Class::Temperature::convert(double v, int from, int to) const {
double K = v;
switch (from) {
case Celsius: K += 273.15; break;
case Fahrenheit: K = (v + 459.67) * (5. / 9.); break;
default: break;
}
switch (to) {
case Celsius: return K - 273.15;
case Fahrenheit: return (K * (9. / 5.) - 459.67);
default: break;
}
return K;
}
PIString PIUnits::Class::Temperature::valueToString(double v, char format, int prec) const {
return PIString::fromNumber(v, format, prec);
}
bool PIUnits::Class::Temperature::supportPrefixes(int type) const {
if (type == Kelvin) return true;
return false;
}
bool PIUnits::Class::Temperature::supportPrefixesNon3(int type) const {
return false;
}
bool PIUnits::Class::Temperature::supportPrefixesGreater(int type) const {
return true;
}
bool PIUnits::Class::Temperature::supportPrefixesSmaller(int type) const {
return false;
}

View File

@@ -0,0 +1,40 @@
/*! \file piunits_class_temperature.h
* \ingroup Core
* \~\brief
* \~english Temperature units
* \~russian Единицы измерения температуры
*/
/*
PIP - Platform Independent Primitives
Temperature units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_CLASS_TEMPERATURE_H
#define PIUNITS_CLASS_TEMPERATURE_H
#include "piunits_base.h"
DECLARE_UNIT_CLASS_BEGIN(Temperature, 0x400)
enum {
Kelvin = typeStart,
Celsius,
Fahrenheit,
_LastType,
};
DECLARE_UNIT_CLASS_END(Temperature)
#endif

View File

@@ -0,0 +1,75 @@
/*
PIP - Platform Independent Primitives
Time units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_class_time.h"
PIString PIUnits::Class::Time::name(int type) const {
switch (type) {
case Second: return "second"_tr("PIUnitsTime");
case Hertz: return "hertz"_tr("PIUnitsTime");
}
return Class::Internal::unknown;
}
PIString PIUnits::Class::Time::unit(int type) const {
switch (type) {
case Second: return "s"_tr("PIUnitsTime");
case Hertz: return "Hz"_tr("PIUnitsTime");
}
return Class::Internal::unknown;
}
double PIUnits::Class::Time::convert(double v, int from, int to) const {
if (piCompared(v, 0.)) return 0.;
switch (to) {
case Second: return 1. / v;
case Hertz: return 1. / v;
}
return v;
}
PIString PIUnits::Class::Time::valueToString(double v, char format, int prec) const {
return PIString::fromNumber(v, format, prec);
}
bool PIUnits::Class::Time::supportPrefixes(int type) const {
return true;
}
bool PIUnits::Class::Time::supportPrefixesNon3(int type) const {
return false;
}
bool PIUnits::Class::Time::supportPrefixesGreater(int type) const {
if (type == Hertz) return true;
return false;
}
bool PIUnits::Class::Time::supportPrefixesSmaller(int type) const {
if (type == Second) return true;
return false;
}

View File

@@ -0,0 +1,39 @@
/*! \file piunits_class_time.h
* \ingroup Core
* \~\brief
* \~english Time units
* \~russian Единицы измерения времени
*/
/*
PIP - Platform Independent Primitives
Time units
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_CLASS_TIME_H
#define PIUNITS_CLASS_TIME_H
#include "piunits_base.h"
DECLARE_UNIT_CLASS_BEGIN(Time, 0x300)
enum {
Second = typeStart,
Hertz,
_LastType,
};
DECLARE_UNIT_CLASS_END(Time)
#endif

View File

@@ -0,0 +1,137 @@
/*
PIP - Platform Independent Primitives
Unit prefix
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_prefix.h"
#include "piliterals_string.h"
#include "pimathbase.h"
#include "pitranslator.h"
#include "piunits_base.h"
// quetta Q 10^30 1000000000000000000000000000000
// ronna R 10^27 1000000000000000000000000000
// yotta Y 10^24 1000000000000000000000000
// zetta Z 10^21 1000000000000000000000
// exa E 10^18 1000000000000000000
// peta P 10^15 1000000000000000
// tera T 10^12 1000000000000
// giga G 10^9 1000000000
// mega M 10^6 1000000
// kilo k 10^3 1000
// hecto h 10^2 100
// deca da 10^1 10
// — — 100 1 —
// deci d 10^1 0.1
// centi c 10^2 0.01
// milli m 10^3 0.001
// micro μ 10^6 0.000001
// nano n 10^9 0.000000001
// pico p 10^12 0.000000000001
// femto f 10^15 0.000000000000001
// atto a 10^18 0.000000000000000001
// zepto z 10^21 0.000000000000000000001
// yocto y 10^24 0.000000000000000000000001
// ronto r 10^27 0.000000000000000000000000001
PIString PIUnits::Prefix::name(int prefix) {
return instance().getPrefix(prefix).name;
}
PIString PIUnits::Prefix::prefix(int prefix) {
return instance().getPrefix(prefix).prefix;
}
PIString PIUnits::Prefix::valueToString(double v, void * type_class, int type, char format, int prec) {
auto * tc = reinterpret_cast<PIUnits::Class::Internal::ClassBase *>(type_class);
auto p =
instance().getPrefixForValue(v, tc->supportPrefixesNon3(type), tc->supportPrefixesGreater(type), tc->supportPrefixesSmaller(type));
return PIString::fromNumber(v / p.divider, format, prec) + " "_a + p.prefix;
}
double PIUnits::Prefix::multiplier(int prefix) {
return instance().getPrefix(prefix).divider;
}
PIUnits::Prefix::Prefix() {
def_prefix = {"", "", 0, 1., false};
// clang-format off
prefixes = {
{Deca, {"deca"_tr ("PIUnits"), "da"_tr("PIUnits") , 1 , pow10(1. ), true }},
{Hecto, {"hecto"_tr ("PIUnits"), "h"_tr ("PIUnits") , 2 , pow10(2. ), true }},
{Kilo, {"kilo"_tr ("PIUnits"), "k"_tr ("PIUnits") , 3 , pow10(3. ), false}},
{Mega, {"mega"_tr ("PIUnits"), "M"_tr ("PIUnits") , 6 , pow10(6. ), false}},
{Giga, {"giga"_tr ("PIUnits"), "G"_tr ("PIUnits") , 9 , pow10(9. ), false}},
{Tera, {"tera"_tr ("PIUnits"), "T"_tr ("PIUnits") , 12 , pow10(12. ), false}},
{Peta, {"peta"_tr ("PIUnits"), "P"_tr ("PIUnits") , 15 , pow10(15. ), false}},
{Exa, {"exa"_tr ("PIUnits"), "E"_tr ("PIUnits") , 18 , pow10(18. ), false}},
{Zetta, {"zetta"_tr ("PIUnits"), "Z"_tr ("PIUnits") , 21 , pow10(21. ), false}},
{Yotta, {"yotta"_tr ("PIUnits"), "Y"_tr ("PIUnits") , 24 , pow10(24. ), false}},
{Ronna, {"ronna"_tr ("PIUnits"), "R"_tr ("PIUnits") , 27 , pow10(27. ), false}},
{Quetta, {"quetta"_tr("PIUnits"), "Q"_tr ("PIUnits") , 30 , pow10(30. ), false}},
{Deci, {"deci"_tr ("PIUnits"), "d"_tr ("PIUnits") , -1 , pow10(-1. ), true }},
{Centi, {"centi"_tr ("PIUnits"), "c"_tr ("PIUnits") , -2 , pow10(-2. ), true }},
{Milli, {"milli"_tr ("PIUnits"), "m"_tr ("PIUnits") , -3 , pow10(-3. ), false}},
{Micro, {"micro"_tr ("PIUnits"), "u"_tr ("PIUnits") , -6 , pow10(-6. ), false}},
{Nano, {"nano"_tr ("PIUnits"), "n"_tr ("PIUnits") , -9 , pow10(-9. ), false}},
{Pico, {"pico"_tr ("PIUnits"), "p"_tr ("PIUnits") , -12, pow10(-12.), false}},
{Femto, {"femto"_tr ("PIUnits"), "f"_tr ("PIUnits") , -15, pow10(-15.), false}},
{Atto, {"atto"_tr ("PIUnits"), "a"_tr ("PIUnits") , -18, pow10(-18.), false}},
{Zepto, {"zepto"_tr ("PIUnits"), "z"_tr ("PIUnits") , -21, pow10(-21.), false}},
{Yocto, {"yocto"_tr ("PIUnits"), "y"_tr ("PIUnits") , -24, pow10(-24.), false}},
{Ronto, {"ronto"_tr ("PIUnits"), "r"_tr ("PIUnits") , -27, pow10(-27.), false}},
};
// clang-format on
auto it = prefixes.makeIterator();
while (it.next()) {
prefixes_by_pow[it.value().pow] = &it.value();
}
prefixes_by_pow[0] = &def_prefix;
}
const PIUnits::Prefix::P PIUnits::Prefix::getPrefixForValue(double v, bool use_non3, bool use_greater, bool use_smaller) const {
auto it = prefixes_by_pow.makeIterator();
const P * ret = &def_prefix;
while (it.next()) {
if (it.value()->pow < 0 && !use_smaller) continue;
if (it.value()->pow > 0 && !use_greater) continue;
if (it.value()->non3 && !use_non3) continue;
if (v < it.value()->divider) return *ret;
ret = it.value();
}
return def_prefix;
}
const PIUnits::Prefix::P PIUnits::Prefix::getPrefix(int p) const {
return prefixes.value(p, def_prefix);
}
PIUnits::Prefix & PIUnits::Prefix::instance() {
static Prefix ret;
return ret;
}

View File

@@ -0,0 +1,95 @@
/*! \file piunits_prefix.h
* \ingroup Core
* \~\brief
* \~english Unit prefixes
* \~russian Префиксы единиц измерения
*/
/*
PIP - Platform Independent Primitives
Unit prefix
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_PREFIX_H
#define PIUNITS_PREFIX_H
#include "pistring.h"
namespace PIUnits {
class PIP_EXPORT Prefix {
friend class Value;
public:
enum {
None,
Deca = 0x100, // da 10^1 10
Hecto, // h 10^2 100
Kilo, // k 10^3 1000
Mega, // M 10^6 1000000
Giga, // G 10^9 1000000000
Tera, // T 10^12 1000000000000
Peta, // P 10^15 1000000000000000
Exa, // E 10^18 1000000000000000000
Zetta, // Z 10^21 1000000000000000000000
Yotta, // Y 10^24 1000000000000000000000000
Ronna, // R 10^27 1000000000000000000000000000
Quetta, // Q 10^30 1000000000000000000000000000000
Deci = 0x200, // d 10^1 0.1
Centi, // c 10^2 0.01
Milli, // m 10^3 0.001
Micro, // μ 10^6 0.000001
Nano, // n 10^9 0.000000001
Pico, // p 10^12 0.000000000001
Femto, // f 10^15 0.000000000000001
Atto, // a 10^18 0.000000000000000001
Zepto, // z 10^21 0.000000000000000000001
Yocto, // y 10^24 0.000000000000000000000001
Ronto, // r 10^27 0.000000000000000000000000001
};
static PIString name(int prefix);
static PIString prefix(int prefix);
static double multiplier(int prefix);
private:
Prefix();
NO_COPY_CLASS(Prefix);
static Prefix & instance();
static PIString valueToString(double v, void * type_class, int type, char format = 'g', int prec = 5);
struct P {
PIString name;
PIString prefix;
int pow;
double divider;
bool non3;
};
const P getPrefix(int p) const;
const P getPrefixForValue(double v, bool use_non3, bool use_greater, bool use_smaller) const;
PIMap<int, P> prefixes;
PIMap<int, P *> prefixes_by_pow;
P def_prefix;
};
} // namespace PIUnits
#endif

View File

@@ -0,0 +1,60 @@
/*
PIP - Platform Independent Primitives
Unit value
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piunits_value.h"
#include "piliterals_string.h"
#include "piunits_prefix.h"
PIUnits::Value::Value(double v, int t) {
m_value = v;
m_class = Class::Internal::typeClasses.value(t);
if (m_class) m_type = t;
}
PIString PIUnits::Value::toString(char format, int prec) const {
if (isNotValid()) return Class::Internal::unknown;
PIString ret;
if (m_class->supportPrefixes(m_type)) {
ret = Prefix::valueToString(m_value, m_class, m_type, format, prec);
} else
ret = m_class->valueToString(m_value, format, prec) + " "_a;
ret += m_class->unit(m_type);
return ret;
}
bool PIUnits::Value::convert(int type_to) {
if (m_type == type_to) return true;
auto * class_to = Class::Internal::typeClasses.value(type_to);
if (!class_to) return false;
if (m_class->classID() != class_to->classID()) return false;
m_value = m_class->convert(m_value, m_type, type_to);
m_type = type_to;
return true;
}
PIUnits::Value PIUnits::Value::converted(int type_to) {
Value ret(*this);
if (!ret.convert(type_to)) return {};
return ret;
}

View File

@@ -0,0 +1,81 @@
/*! \file piunits_value.h
* \ingroup Core
* \~\brief
* \~english Unit value
* \~russian Единица измерения
*/
/*
PIP - Platform Independent Primitives
Unit value
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIUNITS_VALUE_H
#define PIUNITS_VALUE_H
#include "piunits_base.h"
namespace PIUnits {
/*
enum class Angle {
Degree = 0x200,
Radian,
};
enum class Time {
Second = 0x300,
Hertz,
};
enum class Temperature {
Kelvin = 0x400,
Celsius,
Fahrenheit,
};
enum class Pressure {
Pascal = 0x500,
};
enum class Distance {
Meter = 0x500,
};
};
*/
class PIP_EXPORT Value {
public:
Value(double v = 0., int t = Class::Invalid);
bool isValid() const { return m_type >= 0 && m_class; }
bool isNotValid() const { return m_type < 0 || !m_class; }
double value() const { return m_value; }
PIString toString(char format = 'g', int prec = 5) const;
bool convert(int type_to);
Value converted(int type_to);
private:
double m_value = 0.;
int m_type = -1;
Class::Internal::ClassBase * m_class = nullptr;
};
}; // namespace PIUnits
inline PICout operator<<(PICout s, const PIUnits::Value & v) {
s << v.toString();
return s;
}
#endif