@@ -1,8 +1,15 @@
/*! @file pibase.h
* @ brief Base types and functions
* \ brief
* \~english Base types and functions
* \~russian Базовые типы и методы
*
* \details
* \~english
* This file implements first layer above the system and
* declares some basic useful functions
* \~russian
* Этот файл реализует первый слой после системы и объявляет
* несколько базовых полезных методов
*/
/*
PIP - Platform Independent Primitives
@@ -33,87 +40,143 @@
# include "string.h"
# include <limits>
//! \~english
//! Meta-information section for any entity.
//! Parsing by \a pip_cmg and can be accessed by \a PICodeInfo.
//! Contains sequence of key=value pairs, e.g.
//! \~russian
//! Секция метаинформации для любой сущности.
//! Парсится \a pip_cmg и доступна с помощью \a PICodeInfo.
//! Содержит набор пар ключ=значение, например
//! \~
//! PIMETA(id=12345,tag="my string")
# define PIMETA(...)
# ifdef DOXYGEN
//! Major value of PIP version
//! \brief
//! \~english Major value of PIP version
//! \~russian Мажорная версия PIP
# define PIP_VERSION_MAJOR
//! Minor value of PIP version
//! \brief
//! \~english Minor value of PIP version
//! \~russian Минорная версия PIP
# define PIP_VERSION_MINOR
//! Revision value of PIP version
//! \brief
//! \~english Revision value of PIP version
//! \~russian Ревизия версии PIP
# define PIP_VERSION_REVISION
//! Suffix of PIP version
//! \brief
//! \~english Suffix of PIP version
//! \~russian Суффикс версии PIP
# define PIP_VERSION_SUFFIX
//! Version of PIP in hex - 0x##(Major)##(Minor)##(Revision)
//! \brief
//! \~english Version of PIP in hex - 0x##(Major)##(Minor)##(Revision)
//! \~russian Версия PIP в hex - 0x##(Major)##(Minor)##(Revision)
# define PIP_VERSION
//! Macro is defined when compile-time debug is enabled
//! \brief
//! \~english Macro is defined when compile-time debug is enabled
//! \~russian Макрос объявлен когда включена compile-time отладка
# define PIP_DEBUG
//! Macro is defined when host is any Windows
//! \brief
//! \~english Macro is defined when host is any Windows
//! \~russian Макрос объявлен когда система Windows
# define WINDOWS
//! Macro is defined when host is QNX or Blackberry
//! \brief
//! \~english Macro is defined when host is QNX or Blackberry
//! \~russian Макрос объявлен когда система QNX или Blackberry
# define QNX
//! Macro is defined when host is Blackberry
//! \brief
//! \~english Macro is defined when host is Blackberry
//! \~russian Макрос объявлен когда система Blackberry
# define BLACKBERRY
//! Macro is defined when host is FreeBSD
//! \brief
//! \~english Macro is defined when host is FreeBSD
//! \~russian Макрос объявлен когда система FreeBSD
# define FREE_BSD
//! Macro is defined when host is Mac OS
//! \brief
//! \~english Macro is defined when host is Mac OS
//! \~russian Макрос объявлен когда система Mac OS
# define MAC_OS
//! Macro is defined when host is Android
//! \brief
//! \~english Macro is defined when host is Android
//! \~russian Макрос объявлен когда система Android
# define ANDROID
//! Macro is defined when host is any Linux
//! \brief
//! \~english Macro is defined when host is any Linux
//! \~russian Макрос объявлен когда система Linux
# define LINUX
//! Macro is defined when compiler is GCC or MinGW
//! \brief
//! \~english Macro is defined when compiler is GCC or MinGW
//! \~russian Макрос объявлен когда компилятор GCC или MinGW
# define CC_GCC
//! Macro is defined when PIP is decided that host is support language
//! \brief
//! \~english Macro is defined when PIP is decided that host is support language
//! \~russian Макрос объявлен когда PIP решил что система поддерживает локализацию
# define HAS_LOCALE
//! Macro is defined when compiler is Visual Studio
//! \brief
//! \~english Macro is defined when compiler is Visual Studio
//! \~russian Макрос объявлен когда компилятор Visual Studio
# define CC_VC
//! Macro is defined when compiler is unknown
//! \brief
//! \~english Macro is defined when compiler is unknown
//! \~russian Макрос объявлен когда компилятор неизвестен
# define CC_OTHER
//! Macro is defined when PIP can use "rt" library for "PITimer::ThreadRT" timers implementation
//! \brief
//! \~english Macro is defined when PIP can use "rt" library for "PITimer::ThreadRT" timers implementation
//! \~russian Макрос объявлен когда PIP может использовать библиотеку "rt" для "PITimer::ThreadRT" реализации таймера
# define PIP_TIMER_RT
//! Macro to declare private section, export is optional
//! \brief
//! \~english Macro to declare private section, "export" is optional
//! \~russian Макрос для объявления частной секции, "export" необязателен
# define PRIVATE_DECLARATION(export)
//! Macro to start definition of private section
//! \brief
//! \~english Macro to start definition of private section
//! \~russian Макрос для начала реализации частной секции
# define PRIVATE_DEFINITION_START(Class)
//! Macro to end definition of private section
//! \brief
//! \~english Macro to end definition of private section
//! \~russian Макрос для окончания реализации частной секции
# define PRIVATE_DEFINITION_END(Class)
//! Macro to access private section by pointer
//! \brief
//! \~english Macro to access private section by pointer
//! \~russian Макрос для доступа к частной секции
# define PRIVATE
//! Macro to access private section by pointer without brakes ()
//! \brief
//! \~english Macro to access private section by pointer without brakes ()
//! \~russian Макрос для доступа к частной секции без обрамляющих скобок ()
# define PRIVATEWB
//! Macro to start static initializer
//! \brief
//! \~english Macro to start static initializer
//! \~russian Макрос для начала статической инициализации
# define STATIC_INITIALIZER_BEGIN
//! Macro to end static initializer
//! \brief
//! \~english Macro to end static initializer
//! \~russian Макрос для окончания статической инициализации
# define STATIC_INITIALIZER_END
@@ -140,6 +203,8 @@
extern long long __pi_perf_freq ;
# endif
# ifndef DOXYGEN
# ifdef ANDROID
///# define tcdrain(fd) ioctl(fd, TCSBRK, 1)
//inline int wctomb(char * c, wchar_t w) {*c = ((char * )&w)[0]; return 1;}
@@ -222,7 +287,7 @@
# define DEPRECATED
# endif
# endif //DOXYGEN
// Private data macros
# ifndef DOXYGEN
@@ -282,21 +347,32 @@
# endif
//! Macro used for infinite loop
//! \brief
//! \~english Macro used for infinite loop
//! \~russian Макрос для бесконечного цикла
# define FOREVER for (;;)
//! Macro used for infinite wait
//! \brief
//! \~english Macro used for infinite wait
//! \~russian Макрос для бесконечного ожидания
# define FOREVER_WAIT FOREVER piMinSleep;
//! Macro used for infinite wait
//! \brief
//! \~english Macro used for infinite wait
//! \~russian Макрос для бесконечного ожидания
# define WAIT_FOREVER FOREVER piMinSleep;
//! global variable enabling output to piCout, default is true
//! \brief
//! \~english Global variable enabling output to piCout, default is true
//! \~russian Глобальная переменная, включающая вывод в piCout, при старте true
extern PIP_EXPORT bool piDebug ;
//! global variable that set minimum real update interval
//! \brief
//! \~english Global variable that set minimum real update interval
//! for function PIInit::mountInfo(), default is 10000 ms
//! \~russian Глобальная переменная минимального ожидания между реальным обновлением
//! в методе PIInit::mountInfo(), по умолчанию 10000 мс
extern PIP_EXPORT double piMountInfoRefreshIntervalMs ;
typedef unsigned char uchar ;
@@ -307,12 +383,20 @@ typedef unsigned long long ullong;
typedef long long llong ;
typedef long double ldouble ;
/* ! @ brief Templated function for swap two values
* \details Example:\n \snippet piincludes.cpp swap */
// ! \ brief
//! \~english Templated function for swap two values
//! \~russian Шаблонный метод для перестановки двух значений
//! \details
//! \~english Example:\n \snippet piincludes.cpp swap
//! \~russian Пример:\n \snippet piincludes.cpp swap
template < typename T > inline void piSwap ( T & f , T & s ) { T t ( std : : move ( f ) ) ; f = std : : move ( s ) ; s = std : : move ( t ) ; }
/* ! @ brief Templated function for swap two values without "="
* \details Example:\n \snippet piinc lud es.cpp swapBinary */
// ! \ brief
//! \~english Templated function for swap two va lues without "="
//! \~russian Шаблонный метод для перестановки двух значений без использования "="
//! \details
//! \~english Example:\n \snippet piincludes.cpp swapBinary
//! \~russian Пример:\n \snippet piincludes.cpp swapBinary
template < typename T > inline void piSwapBinary ( T & f , T & s ) {
if ( ( size_t * ) & f = = ( size_t * ) & s ) return ;
size_t j = ( sizeof ( T ) / sizeof ( size_t ) ) , bs = j * sizeof ( size_t ) , bf = sizeof ( T ) ;
@@ -347,8 +431,12 @@ template<> inline void piSwapBinary(const void *& f, const void *& s) {
}
/* ! @ brief Function for compare two values without "=" by raw content
* \details Example:\n \snippet piincludes.cpp compareBinary */
// ! \ brief
//! \~english Function for compare two values without "==" by raw content
//! \~russian Метод для сравнения двух значений без использования "==" (по сырому содержимому)
//! \details
//! \~english Example:\n \snippet piincludes.cpp compareBinary
//! \~russian Пример:\n \snippet piincludes.cpp compareBinary
inline bool piCompareBinary ( const void * f , const void * s , size_t size ) {
for ( size_t i = 0 ; i < size ; + + i )
if ( ( ( const uchar * ) f ) [ i ] ! = ( ( const uchar * ) s ) [ i ] )
@@ -356,146 +444,304 @@ inline bool piCompareBinary(const void * f, const void * s, size_t size) {
return true ;
}
/* ! @ brief Templated function return round of float falue
* \details Round is the nearest integer v alue \n
* There are some macros:
* - \c piRoundf for "float"
* - \c piRoundd for "double"
*
* Example :
* \snippet piincludes.cpp round */
// ! \ brief
//! \~english Templated function return round of float f alue
//! \~russian Шаблонный метод, возвращающий округленное значение
//! \details
//! \~english
//! Round is the nearest integer value \n
//! There are some macros :
//! - \c piRoundf for "float"
//! - \c piRoundd for "double"
//!
//! Example:
//! \snippet piincludes.cpp round
//! \~russian
//! Округленное значение - это ближайшее целое число\n
//! Есть несколько макросов:
//! - \c piRoundf для "float"
//! - \c piRoundd для "double"
//!
//! Пример:
//! \snippet piincludes.cpp round
template < typename T > inline constexpr int piRound ( const T & v ) { return int ( v > = T ( 0. ) ? v + T ( 0.5 ) : v - T ( 0.5 ) ) ; }
/* ! @ brief Templated function return floor of float falue
* \details Floor is the largest integer that is not greater than v alue \n
* There are some macros:
* - \c piFloorf for "float"
* - \c piFloord for "double"
*
* Example :
* \snippet piincludes.cpp floor */
// ! \ brief
//! \~english Templated function return floor of float f alue
//! \~russian Шаблонный метод, возвращающий floor значение
//! \details
//! \~english
//! Floor is the largest integer that is not greater than "v" \n
//! There are some macros :
//! - \c piFloorf for "float"
//! - \c piFloord for "double"
//!
//! Example:
//! \snippet piincludes.cpp floor
//! \~russian
//! Floor значение - это наибольшее целое, не большее чем "v"\n
//! Есть несколько макросов:
//! - \c piFloorf для "float"
//! - \c piFloord для "double"
//!
//! Пример:
//! \snippet piincludes.cpp floor
template < typename T > inline constexpr int piFloor ( const T & v ) { return v < T ( 0 ) ? int ( v ) - 1 : int ( v ) ; }
/* ! @ brief Templated function return ceil of float falue
* \details Ceil is the smallest integer that is not less than v alue \n
* There are some macros:
* - \c piCeilf for "float"
* - \c piCeild for "double"
*
* Example :
* \snippet piincludes.cpp ceil */
// ! \ brief
//! \~english Templated function return ceil of float f alue
//! \~russian Шаблонный метод, возвращающий ceil значение
//! \details
//! \~english
//! Ceil is the smallest integer that is not less than "v" \n
//! There are some macros :
//! - \c piCeilf for "float"
//! - \c piCeild for "double"
//!
//! Example:
//! \snippet piincludes.cpp ceil
//! \~russian
//! Ceil значение - это наименьшее целое, не меньшее чем "v" \n
//! Есть несколько макросов:
//! - \c piCeilf для "float"
//! - \c piCeild для "double"
//!
//! Пример:
//! \snippet piincludes.cpp ceil
template < typename T > inline constexpr int piCeil ( const T & v ) { return v < T ( 0 ) ? int ( v ) : int ( v ) + 1 ; }
/* ! @ brief Templated function return absolute of numeric falue
* \details Absolute is the positive or equal 0 v alue \n
* There are some macros:
* - \c piAbss for "short"
* - \c piAbsi for "int"
* - \c piAbsl for "long"
* - \c piAbsll for "llong"
* - \c piAbsf for "floa t"
* - \c piAbsd for "double "
*
* Example:
* \snippet piincludes.cpp abs */
// ! \ brief
//! \~english Templated function return absolute of numeric f alue
//! \~russian Шаблонный метод, возвращающий модуль числового значения
//! \details
//! \~english
//! Absolute is the positive or equal 0 value \n
//! There are some macros:
//! - \c piAbss for "shor t"
//! - \c piAbsi for "int "
//! - \c piAbsl for "long"
//! - \c piAbsll for "llong"
//! - \c piAbsf for "float"
//! - \c piAbsd for "double"
//!
//! Example:
//! \snippet piincludes.cpp abs
//! \~russian
//! Модуль числового значения всегда >= 0 \n
//! Есть несколько макросов:
//! - \c piAbss для "short"
//! - \c piAbsi для "int"
//! - \c piAbsl для "long"
//! - \c piAbsll для "llong"
//! - \c piAbsf для "float"
//! - \c piAbsd для "double"
//!
//! Пример:
//! \snippet piincludes.cpp abs
template < typename T > inline constexpr T piAbs ( const T & v ) { return ( v > = T ( 0 ) ? v : - v ) ; }
/* ! @ brief Templated function return minimum of two values
* \details There are some macros:
* - \c piMins for "short"
* - \c piMini for "int"
* - \c piMinl for "long"
* - \c piMinll for "llong"
* - \c piMinf for "floa t"
* - \c piMind for "double "
*
* Example:
* \snippet piincludes.cpp min2 */
// ! \ brief
//! \~english Templated function return minimum of two values
//! \~russian Шаблонный метод, возвращающий минимум из двух значений
//! \details
//! \~english
//! There are some macros:
//! - \c piMins for "shor t"
//! - \c piMini for "int "
//! - \c piMinl for "long"
//! - \c piMinll for "llong"
//! - \c piM inf for "float"
//! - \c piMind for "double"
//!
//! Example:
//! \snippet piincludes.cpp min2
//! \~russian
//! Есть несколько макросов:
//! - \c piMins для "short"
//! - \c piMini для "int"
//! - \c piMinl для "long"
//! - \c piMinll для "llong"
//! - \c piMinf для "float"
//! - \c piMind для "double"
//!
//! Пример:
//! \snippet piincludes.cpp min2
template < typename T > inline constexpr T piMin ( const T & f , const T & s ) { return ( ( f > s ) ? s : f ) ; }
/* ! @ brief Templated function return minimum of tree values
* \details There are some macros:
* - \c piMins for "short"
* - \c piMini for "int"
* - \c piMinl for "long"
* - \c piMinll for "llong"
* - \c piMinf for "floa t"
* - \c piMind for "double "
*
* Example:
* \snippet piincludes.cpp min3 */
// ! \ brief
//! \~english Templated function return minimum of tree values
//! \~russian Шаблонный метод, возвращающий минимум из трех значений
//! \details
//! \~english
//! There are some macros:
//! - \c piMins for "shor t"
//! - \c piMini for "int "
//! - \c piMinl for "long"
//! - \c piMinll for "llong"
//! - \c piM inf for "float"
//! - \c piMind for "double"
//!
//! Example:
//! \snippet piincludes.cpp min3
//! \~russian
//! Есть несколько макросов:
//! - \c piMins для "short"
//! - \c piMini для "int"
//! - \c piMinl для "long"
//! - \c piMinll для "llong"
//! - \c piMinf для "float"
//! - \c piMind для "double"
//!
//! Пример:
//! \snippet piincludes.cpp min3
template < typename T > inline constexpr T piMin ( const T & f , const T & s , const T & t ) { return ( ( f < s & & f < t ) ? f : ( ( s < t ) ? s : t ) ) ; }
/* ! @ brief Templated function return maximum of two values
* \details There are some macros:
* - \c piMaxs for "short"
* - \c piMaxi for "int"
* - \c piMaxl for "long"
* - \c piMaxll for "llong"
* - \c piMaxf for "floa t"
* - \c piMaxd for "double "
*
* Example:
* \snippet piincludes.cpp max2 */
// ! \ brief
//! \~english Templated function return maximum of two values
//! \~russian Шаблонный метод, возвращающий максимум из двух значений
//! \details
//! \~english
//! There are some macros:
//! - \c piMaxs for "shor t"
//! - \c piMaxi for "int "
//! - \c piMaxl for "long"
//! - \c piMaxll for "llong"
//! - \c piMaxf for "float"
//! - \c piMaxd for "double"
//!
//! Example:
//! \snippet piincludes.cpp max2
//! \~russian
//! Есть несколько макросов:
//! - \c piMaxs для "short"
//! - \c piMaxi для "int"
//! - \c piMaxl для "long"
//! - \c piMaxll для "llong"
//! - \c piMaxf для "float"
//! - \c piMaxd для "double"
//!
//! Пример:
//! \snippet piincludes.cpp max2
template < typename T > inline constexpr T piMax ( const T & f , const T & s ) { return ( ( f < s ) ? s : f ) ; }
/* ! @ brief Templated function return maximum of tree values
* \details There are some macros:
* - \c piMaxs for "short"
* - \c piMaxi for "int"
* - \c piMaxl for "long"
* - \c piMaxll for "llong"
* - \c piMaxf for "floa t"
* - \c piMaxd for "double "
*
* Example:
* \snippet piincludes.cpp max3 */
// ! \ brief
//! \~english Templated function return maximum of tree values
//! \~russian Шаблонный метод, возвращающий максимум из трех значений
//! \details
//! \~english
//! There are some macros:
//! - \c piMaxs for "shor t"
//! - \c piMaxi for "int "
//! - \c piMaxl for "long"
//! - \c piMaxll for "llong"
//! - \c piMaxf for "float"
//! - \c piMaxd for "double"
//!
//! Example:
//! \snippet piincludes.cpp max3
//! \~russian
//! Есть несколько макросов:
//! - \c piMaxs для "short"
//! - \c piMaxi для "int"
//! - \c piMaxl для "long"
//! - \c piMaxll для "llong"
//! - \c piMaxf для "float"
//! - \c piMaxd для "double"
//!
//! Пример:
//! \snippet piincludes.cpp max3
template < typename T > inline constexpr T piMax ( const T & f , const T & s , const T & t ) { return ( ( f > s & & f > t ) ? f : ( ( s > t ) ? s : t ) ) ; }
/* ! @ brief Templated function return clamped value
* \details Clamped is the not greater than "max" and not lesser than "min" value \n
* There are some macros:
* - \c piClamps for "short"
* - \c piClampi for "int"
* - \c piClampl for "long"
* - \c piClampll for "llong"
* - \c piClampf for "floa t"
* - \c piClampd for "double "
*
* Example:
* \snippet piincludes.cpp clamp */
// ! \ brief
//! \~english Templated function return clamped value
//! \~russian Шаблонный метод, возвращающий ограниченное значение
//! \details
//! \~english
//! Clamped is the not greater than "max" and not lesser than "min" value \n
//! There are some macros:
//! - \c piClamps for "shor t"
//! - \c piClampi for "int "
//! - \c piClampl for "long"
//! - \c piClampll for "llong"
//! - \c piClampf for "float"
//! - \c piClampd for "double"
//!
//! Example:
//! \snippet piincludes.cpp clamp
//! \~russian
//! Ограниченное значение - не больше чем "max" и не меньше чем "min"
//! Есть несколько макросов:
//! - \c piClamps для "short"
//! - \c piClampi для "int"
//! - \c piClampl для "long"
//! - \c piClampll для "llong"
//! - \c piClampf для "float"
//! - \c piClampd для "double"
//!
//! Пример:
//! \snippet piincludes.cpp clamp
template < typename T > inline constexpr T piClamp ( const T & v , const T & min , const T & max ) { return ( v > max ? max : ( v < min ? min : v ) ) ; }
/// Function inverse byte order in memory block
//! \brief
//! \~english Function inverse byte order in memory block ([1..N] -> [N..1])
//! \~russian Метод для смены порядка байт в блоке памяти ([1..N] -> [N..1])
inline void piLetobe ( void * data , int size ) {
for ( int i = 0 ; i < size / 2 ; i + + )
piSwap < uchar > ( ( ( uchar * ) data ) [ size - i - 1 ] , ( ( uchar * ) data ) [ i ] ) ;
}
/* ! @ brief Function for compare two numeric values with epsilon
* \details Example:\n \snippet piinc lud es.cpp compare
* There are some macros:
* - \c piComparef for "float"
* - \c piCompared for "double"
*/
// ! \ brief
//! \~english Function for compare two numeric va lues with epsilon
//! \~russian Метод для сравнения двух чисел с порогом
//! \details
//! \~english
//! There are some macros:
//! - \c piComparef for "float"
//! - \c piCompared for "double"
//!
//! Example:
//! \snippet piincludes.cpp compare
//! \~russian
//! Есть несколько макросов:
//! - \c piComparef для "float"
//! - \c piCompared для "double"
//!
//! Пример:
//! \snippet piincludes.cpp compare
template < typename T >
inline bool piCompare ( const T & a , const T & b , const T & epsilon = std : : numeric_limits < T > : : epsilon ( ) ) {
return piAbs ( a - b ) < = epsilon ;
}
/// @ brief Templated function that inverse byte order of value "v"
//! \ brief
//! \~english Templated function that inverse byte order of value "v"
//! \~russian Шаблонный метод, меняющий порядок байт в переменной "v"
template < typename T > inline void piLetobe ( T * v ) { piLetobe ( v , sizeof ( T ) ) ; }
/* ! @ brief Templated function that returns "v" with inversed byte order
* \details This function used to convert values between little and big endian \n
* There are some macros:
* - \c piLetobes for "ushort"
* - \c piLetobei for "uint"
* - \c piLetobel for "ulong"
* - \c piLetobell for "ullong"
*
* Example:
* \snippet piincludes.cpp letobe */
// ! \ brief
//! \~english Templated function that returns "v" with inversed byte order
//! \~russian Шаблонный метод, возвращающий переменную "v" с измененным порядком байт
//! \details
//! \~english
//! This function used to convert values between little and big endian \n
//! There are some macros:
//! - \c piLetobes for "ushort"
//! - \c piLetobei for "uint"
//! - \c piLetobel for "ulong"
//! - \c piLetobell for "ullong"
//!
//! Example:
//! \snippet piincludes.cpp letobe
//! \~russian
//! Этот метод используется для изменения порядка байт между little и big endian
//! Есть несколько макросов:
//! - \c piLetobes для "ushort"
//! - \c piLetobei для "uint"
//! - \c piLetobel для "ulong"
//! - \c piLetobell для "ullong"
//!
//! Пример:
//! \snippet piincludes.cpp letobe
template < typename T > inline T piLetobe ( const T & v ) { T tv ( v ) ; piLetobe ( & tv , sizeof ( T ) ) ; return tv ; }
// specialization
@@ -512,7 +758,9 @@ template<> inline float piLetobe(const float & v) {
return a . f ;
}
/// @ brief Generic hash function, implements murmur3/32 algorithm
//! \ brief
//! \~english Generic hash function, implements murmur3/32 algorithm
//! \~russian Хэш-функция общего назначения, по алгоритму murmur3/32
inline uint piHashData ( const uchar * data , uint len , uint seed = 0 ) {
if ( ! data | | len < = 0 ) return 0u ;
uint h = seed ;