/*! \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 . */ //! \~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 #define PIUNITS_BASE_H #include "pitranslator.h" //! \~english Macro to declare unit class beginning //! \~russian Макрос для объявления начала класса единиц #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; \ } //! \~english Macro to declare unit class end //! \~russian Макрос для объявления конца класса единиц #define DECLARE_UNIT_CLASS_END(Name) \ } \ ; \ } \ } \ STATIC_INITIALIZER_BEGIN \ PIUnits::Class::Name::registerSelf(); \ STATIC_INITIALIZER_END namespace PIUnits { //! \~english Get class name for type //! \~russian Получить имя класса для типа PIP_EXPORT PIString className(int type); //! \~english Get unit name for type //! \~russian Получить имя единицы для типа PIP_EXPORT PIString name(int type); //! \~english Get unit symbol for type //! \~russian Получить символ единицы для типа PIP_EXPORT PIString unit(int type); namespace Class { //! \~english Invalid type marker //! \~russian Маркер недопустимого типа enum { Invalid = -1 }; //! \~english Internal namespace for unit classes implementation //! \~russian Внутреннее пространство имен для реализации классов единиц class PIP_EXPORT Internal { public: //! \~english Base class for all unit classes //! \~russian Базовый класс для всех классов единиц class PIP_EXPORT ClassBase { public: //! \~english Get class ID //! \~russian Получить ID класса virtual uint classID() const = 0; //! \~english Get class name //! \~russian Получить имя класса virtual PIString className() const = 0; //! \~english Get name for unit type //! \~russian Получить имя для типа единицы virtual PIString name(int type) const = 0; //! \~english Get unit symbol for type //! \~russian Получить символ единицы для типа 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; //! \~english Convert value between units //! \~russian Преобразовать значение между единицами 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; } //! \~english Check if non-3 prefixes are supported //! \~russian Проверить поддерживаются ли не-3 префиксы virtual bool supportPrefixesNon3(int type) const { return false; } //! \~english Check if greater prefixes are supported //! \~russian Проверить поддерживаются ли большие префиксы virtual bool supportPrefixesGreater(int type) const { return true; } //! \~english Check if smaller prefixes are supported //! \~russian Проверить поддерживаются ли меньшие префиксы virtual bool supportPrefixesSmaller(int type) const { return true; } //! \~english Get all available types //! \~russian Получить все доступные типы const PIVector & allTypes() const { return types; } protected: //! \~english List of types //! \~russian Список типов PIVector types; }; //! \~english Template for self-registration of unit classes //! \~russian Шаблон для саморегистрации классов единиц template class Registrator { public: //! \~english Register unit class //! \~russian Зарегистрировать класс единиц 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 Map of type to class instance //! \~russian Карта типа к экземпляру класса static PIMap typeClasses; //! \~english List of all registered classes //! \~russian Список всех зарегистрированных классов static PIVector allTypeClasses; //! \~english Unknown name placeholder //! \~russian Заполнитель для неизвестного имени static const PIString unknown; }; } // namespace Class //! \~english Get all registered unit classes //! \~russian Получить все зарегистрированные классы единиц PIP_EXPORT PIVector allClasses(); } // namespace PIUnits #endif