//! \~\file piunits_base.h //! \~\ingroup Units //! \~\brief //! \~english Shared unit conversion infrastructure //! \~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 . */ //! \~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; //! \~russian //! Иван Пелипенко peri4ko@yandex.ru; //! #ifndef PIUNITS_BASE_H #define PIUNITS_BASE_H #include "pitranslator.h" //! \~\ingroup Units //! \~\brief //! \~english Starts declaration of a unit family class in namespace %PIUnits::Class. //! \~russian Начинает объявление класса семейства единиц в пространстве имен %PIUnits::Class. #define DECLARE_UNIT_CLASS_BEGIN(Name, StartIndex) \ namespace PIUnits { \ namespace Class { \ class PIP_EXPORT Name \ : public Internal::ClassBase \ , public Internal::Registrator { \ private: \ friend class Internal::Registrator; \ 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; \ } //! \~\ingroup Units //! \~\brief //! \~english Completes unit family class declaration and registers it globally. //! \~russian Завершает объявление класса семейства единиц и регистрирует его глобально. #define DECLARE_UNIT_CLASS_END(Name) \ } \ ; \ } \ } \ STATIC_INITIALIZER_BEGIN \ PIUnits::Class::Name::registerSelf(); \ STATIC_INITIALIZER_END //! \~\ingroup Units //! \~\brief //! \~english Namespace containing unit metadata and conversion helpers. //! \~russian Пространство имен с метаданными и вспомогательными средствами преобразования единиц. namespace PIUnits { //! \~\ingroup Units //! \~english Returns unit family name for type identifier "type". //! \~russian Возвращает имя семейства единиц для идентификатора типа "type". PIP_EXPORT PIString className(int type); //! \~\ingroup Units //! \~english Returns localized unit name for type identifier "type". //! \~russian Возвращает локализованное имя единицы для идентификатора типа "type". PIP_EXPORT PIString name(int type); //! \~\ingroup Units //! \~english Returns localized unit symbol for type identifier "type". //! \~russian Возвращает локализованное обозначение единицы для идентификатора типа "type". PIP_EXPORT PIString unit(int type); //! \~\ingroup Units //! \~\brief //! \~english Namespace containing unit family descriptors. //! \~russian Пространство имен с описателями семейств единиц. namespace Class { //! \~\ingroup Units //! \~english Common invalid unit type value. //! \~russian Общее значение недопустимого типа единицы. enum { Invalid = -1 /** \~english Invalid unit type \~russian Недопустимый тип единицы */ }; //! \~\ingroup Units //! \~\brief //! \~english Internal registry and base interfaces for unit families. //! \~russian Внутренний реестр и базовые интерфейсы для семейств единиц. class PIP_EXPORT Internal { public: //! \~\ingroup Units //! \~\brief //! \~english Base interface implemented by every unit family descriptor. //! \~russian Базовый интерфейс, реализуемый каждым описателем семейства единиц. class PIP_EXPORT ClassBase { public: //! \~english Returns stable identifier of the unit family. //! \~russian Возвращает стабильный идентификатор семейства единиц. virtual uint classID() const = 0; //! \~english Returns localized family name. //! \~russian Возвращает локализованное имя семейства. virtual PIString className() const = 0; //! \~english Returns localized name of unit type "type". //! \~russian Возвращает локализованное имя типа единицы "type". virtual PIString name(int type) const = 0; //! \~english Returns localized symbol of unit type "type". //! \~russian Возвращает локализованное обозначение типа единицы "type". virtual PIString unit(int type) const = 0; //! \~english Formats numeric value "v" without unit symbol. //! \~russian Форматирует числовое значение "v" без обозначения единицы. virtual PIString valueToString(double v, char format = 'g', int prec = 5) const = 0; //! \~english Converts numeric value "v" from unit "from" to unit "to". //! \~russian Преобразует числовое значение "v" из единицы "from" в единицу "to". virtual double convert(double v, int from, int to) const = 0; //! \~english Returns whether unit type "type" supports automatic SI prefixes. //! \~russian Возвращает, поддерживает ли тип единицы "type" автоматические SI-префиксы. virtual bool supportPrefixes(int type) const { return true; } //! \~english Returns whether non-multiple-of-three prefixes are allowed for unit type "type". //! \~russian Возвращает, разрешены ли немножественные трем префиксы для типа единицы "type". virtual bool supportPrefixesNon3(int type) const { return false; } //! \~english Returns whether prefixes larger than the base unit are allowed for type "type". //! \~russian Возвращает, разрешены ли префиксы больше базовой единицы для типа "type". virtual bool supportPrefixesGreater(int type) const { return true; } //! \~english Returns whether prefixes smaller than the base unit are allowed for type "type". //! \~russian Возвращает, разрешены ли префиксы меньше базовой единицы для типа "type". virtual bool supportPrefixesSmaller(int type) const { return true; } //! \~english Returns all registered unit type identifiers of this family. //! \~russian Возвращает все зарегистрированные идентификаторы типов этой семьи единиц. const PIVector & allTypes() const { return types; } protected: PIVector types; }; //! \~\ingroup Units //! \~\brief //! \~english Helper that registers every type declared by unit family "P". //! \~russian Вспомогательный класс, регистрирующий все типы, объявленные семейством единиц "P". template class Registrator { public: //! \~english Registers unit family "P" in shared lookup tables. //! \~russian Регистрирует семейство единиц "P" в общих таблицах поиска. 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; } }; //! \~english Maps unit type identifiers to owning family descriptors. //! \~russian Сопоставляет идентификаторы типов единиц с описателями их семейств. static PIMap typeClasses; //! \~english Stores all registered unit family descriptors. //! \~russian Хранит все зарегистрированные описатели семейств единиц. static PIVector allTypeClasses; //! \~english Fallback string for unknown unit types. //! \~russian Строка-заглушка для неизвестных типов единиц. static const PIString unknown; }; } // namespace Class //! \~\ingroup Units //! \~english Returns all registered unit family descriptors. //! \~russian Возвращает все зарегистрированные описатели семейств единиц. PIP_EXPORT PIVector allClasses(); } // namespace PIUnits #endif