/*! \file pibase.h * \ingroup Core * \~\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 Base types and functions 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 . */ #ifndef PIBASE_H #define PIBASE_H #include "pip_version.h" #include "piplatform.h" #include "pip_export.h" #include "pip_defs.h" #include //! \~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 //! \~\brief //! \~english Major value of PIP version //! \~russian Мажорная версия PIP # define PIP_VERSION_MAJOR //! \~\brief //! \~english Minor value of PIP version //! \~russian Минорная версия PIP # define PIP_VERSION_MINOR //! \~\brief //! \~english Revision value of PIP version //! \~russian Ревизия версии PIP # define PIP_VERSION_REVISION //! \~\brief //! \~english Suffix of PIP version //! \~russian Суффикс версии PIP # define PIP_VERSION_SUFFIX //! \~\brief //! \~english Version of PIP in hex - 0x##(Major)##(Minor)##(Revision) //! \~russian Версия PIP в hex - 0x##(Major)##(Minor)##(Revision) # define PIP_VERSION //! \~\brief //! \~english Macro is defined when compile-time debug is enabled //! \~russian Макрос объявлен когда включена compile-time отладка # define PIP_DEBUG //! \~\brief //! \~english Macro is defined when operation system is any Windows //! \~russian Макрос объявлен когда операционная система Windows # define WINDOWS //! \~\brief //! \~english Macro is defined when operation system is QNX or Blackberry //! \~russian Макрос объявлен когда операционная система QNX или Blackberry # define QNX //! \~\brief //! \~english Macro is defined when operation system is Blackberry //! \~russian Макрос объявлен когда операционная система Blackberry # define BLACKBERRY //! \~\brief //! \~english Macro is defined when operation system is FreeBSD //! \~russian Макрос объявлен когда операционная система FreeBSD # define FREE_BSD //! \~\brief //! \~english Macro is defined when operation system is Mac OS //! \~russian Макрос объявлен когда операционная система Mac OS # define MAC_OS //! \~\brief //! \~english Macro is defined when operation system is Android //! \~russian Макрос объявлен когда операционная система Android # define ANDROID //! \~\brief //! \~english Macro is defined when operation system is any Linux //! \~russian Макрос объявлен когда операционная система Linux # define LINUX //! \~\brief //! \~english Macro is defined when operation system is FreeRTOS //! \~russian Макрос объявлен когда операционная система FreeRTOS # define FREERTOS //! \~\brief //! \~english Macro is defined when compiler is GCC or MinGW //! \~russian Макрос объявлен когда компилятор GCC или MinGW # define CC_GCC //! \~\brief //! \~english Macro is defined when PIP is decided that host is support language //! \~russian Макрос объявлен когда PIP решил что система поддерживает локализацию # define HAS_LOCALE //! \~\brief //! \~english Macro is defined when PIP is building for embedded systems //! \~russian Макрос объявлен когда PIP собирается для встраиваемых систем # define MICRO_PIP //! \~\brief //! \~english Macro is defined when compiler is Visual Studio //! \~russian Макрос объявлен когда компилятор Visual Studio # define CC_VC //! \~\brief //! \~english Macro is defined when compiler is AVR GCC //! \~russian Макрос объявлен когда компилятор AVR GCC # define CC_AVR_GCC //! \~\brief //! \~english Macro is defined when compiler is unknown //! \~russian Макрос объявлен когда компилятор неизвестен # define CC_OTHER //! \~\brief //! \~english Macro is defined when PIP can use "rt" library for \a PITimer::ThreadRT timers implementation //! \~russian Макрос объявлен когда PIP может использовать библиотеку "rt" для \a PITimer::ThreadRT реализации таймера # define PIP_TIMER_RT //! \~\brief //! \~english Macro to declare private section, "export" is optional //! \~russian Макрос для объявления частной секции, "export" необязателен # define PRIVATE_DECLARATION(export) //! \~\brief //! \~english Macro to start definition of private section //! \~russian Макрос для начала реализации частной секции # define PRIVATE_DEFINITION_START(Class) //! \~\brief //! \~english Macro to end definition of private section //! \~russian Макрос для окончания реализации частной секции # define PRIVATE_DEFINITION_END(Class) //! \~\brief //! \~english Macro to access private section by pointer //! \~russian Макрос для доступа к частной секции # define PRIVATE //! \~\brief //! \~english Macro to access private section by pointer without brakes () //! \~russian Макрос для доступа к частной секции без обрамляющих скобок () # define PRIVATEWB //! \~\brief //! \~english Macro to start static initializer //! \~russian Макрос для начала статической инициализации # define STATIC_INITIALIZER_BEGIN //! \~\brief //! \~english Macro to end static initializer //! \~russian Макрос для окончания статической инициализации # define STATIC_INITIALIZER_END //! \~\brief //! \~english Macro to remove class copy availability //! \~russian Макрос для запрета копирования класса # define NO_COPY_CLASS(Class) //! \~\brief //! \~english Macro to supress compiler warning about unused variable //! \~russian Макрос для подавления предупреждения компилятора о неиспользуемой переменной # define NO_UNUSED(x) #undef MICRO_PIP #undef FREERTOS #endif //DOXYGEN #ifdef CC_AVR_GCC # include #endif #include #include #include #include #include #ifdef WINDOWS # ifdef CC_VC # define SHUT_RDWR 2 # pragma comment(lib, "Ws2_32.lib") # pragma comment(lib, "Iphlpapi.lib") # pragma comment(lib, "Psapi.lib") # ifdef ARCH_BITS_32 # define _X86_ # else # define _IA64_ # endif # else # define SHUT_RDWR SD_BOTH # endif typedef int socklen_t; 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;} //inline int mbtowc(wchar_t * w, const char * c, size_t) {*w = ((wchar_t * )&c)[0]; return 1;} #endif #ifdef MAC_OS # define environ (*_NSGetEnviron()) typedef long time_t; #endif #ifdef POSIX_SIGNALS # define PIP_INTERRUPT_SIGNAL SIGTERM #endif #ifdef LINUX # define environ __environ #endif #ifdef FREE_BSD extern char ** environ; #endif #ifndef NO_UNUSED # define NO_UNUSED(x) (void)x #endif #ifndef assert # define assert(x) # define assertm(exp, msg) #else # define assertm(exp, msg) assert(((void)msg, exp)) #endif #ifdef MICRO_PIP # define __PIP_TYPENAME__(T) "?" #else # define __PIP_TYPENAME__(T) typeid(T).name() #endif #ifdef CC_GCC # undef DEPRECATED # undef DEPRECATEDM # define DEPRECATED __attribute__((deprecated)) # define DEPRECATEDM(msg) __attribute__((deprecated(msg))) # if CC_GCC_VERSION > 0x025F // > 2.95 # pragma GCC diagnostic warning "-Wdeprecated-declarations" # ifdef LINUX # define HAS_LOCALE # endif # ifdef MAC_OS # pragma GCC diagnostic ignored "-Wundefined-bool-conversion" # pragma GCC diagnostic ignored "-Wc++11-extensions" # endif # endif # ifdef ANDROID # pragma GCC diagnostic ignored "-Wunused-parameter" # pragma GCC diagnostic ignored "-Wextra" # pragma GCC diagnostic ignored "-Wc++11-extensions" # pragma GCC diagnostic ignored "-Wundefined-bool-conversion" //# pragma GCC diagnostic ignored "-Wliteral-suffix" # endif #endif #ifdef CC_VC # undef DEPRECATED # undef DEPRECATEDM # define DEPRECATED __declspec(deprecated) # define DEPRECATEDM(msg) __declspec(deprecated(msg)) # pragma warning(disable: 4018) # pragma warning(disable: 4061) # pragma warning(disable: 4100) # pragma warning(disable: 4239) # pragma warning(disable: 4242) # pragma warning(disable: 4244) # pragma warning(disable: 4251) # pragma warning(disable: 4365) # pragma warning(disable: 4512) # pragma warning(disable: 4668) # pragma warning(disable: 4710) # pragma warning(disable: 4800) # pragma warning(disable: 4820) # pragma warning(disable: 4986) # pragma warning(disable: 4996) # ifdef ARCH_BITS_32 typedef long ssize_t; # else typedef long long ssize_t; # endif #endif #ifdef CC_OTHER # undef DEPRECATED # undef DEPRECATEDM # define DEPRECATED # define DEPRECATEDM(msg) #endif #endif //DOXYGEN // Private data macros #ifndef DOXYGEN #define PRIVATE_DECLARATION(e) \ struct __Private__; \ friend struct __Private__; \ struct e __PrivateInitializer__ { \ __PrivateInitializer__(); \ __PrivateInitializer__(const __PrivateInitializer__ & o); \ ~__PrivateInitializer__(); \ __PrivateInitializer__ & operator =(const __PrivateInitializer__ & o); \ __Private__ * p; \ }; \ __PrivateInitializer__ __privateinitializer__; #define PRIVATE_DEFINITION_START(c) \ struct c::__Private__ { #define PRIVATE_DEFINITION_END(c) \ }; \ c::__PrivateInitializer__::__PrivateInitializer__() {p = new c::__Private__();} \ c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ & ) {/*if (p) delete p;*/ p = new c::__Private__();} \ c::__PrivateInitializer__::~__PrivateInitializer__() {delete p; p = 0;} \ c::__PrivateInitializer__ & c::__PrivateInitializer__::operator =(const c::__PrivateInitializer__ & ) {if (p) delete p; p = new c::__Private__(); return *this;} #define PRIVATE (__privateinitializer__.p) #define PRIVATEWB __privateinitializer__.p #endif //DOXYGEN #define NO_COPY_CLASS(name) \ name(const name&) = delete; \ name& operator=(const name&) = delete; #define _PIP_ADD_COUNTER_WS(a, cnt) a##cnt #define _PIP_ADD_COUNTER_WF(a, cnt) _PIP_ADD_COUNTER_WS(a, cnt) #define _PIP_ADD_COUNTER(a) _PIP_ADD_COUNTER_WF(a, __COUNTER__) #define STATIC_INITIALIZER_BEGIN \ class { \ class _Initializer_ { \ public: \ _Initializer_() { #define STATIC_INITIALIZER_END \ } \ } _initializer_; \ } _PIP_ADD_COUNTER(_pip_initializer_); //! \~\brief //! \~english Minimal sleep in milliseconds for internal PIP using //! \~russian Минимальное значание задержки в милисекундах для внутреннего использования в библиотеке PIP //! \~\details //! \~english Using in \a piMinSleep(), \a PIThread, \a PITimer::Pool. By default 1ms. //! \~russian Используется в \a piMinSleep(), \a PIThread, \a PITimer::Pool. По умолчанию равна 1мс. #ifndef PIP_MIN_MSLEEP # ifndef MICRO_PIP # define PIP_MIN_MSLEEP 1. # else # define PIP_MIN_MSLEEP 10. # endif #endif //! \~\brief //! \~english Macro used for infinite loop //! \~russian Макрос для бесконечного цикла #define FOREVER for (;;) //! \~\brief //! \~english Macro used for infinite wait //! \~russian Макрос для бесконечного ожидания #define FOREVER_WAIT FOREVER piMinSleep(); //! \~\brief //! \~english Macro used for infinite wait //! \~russian Макрос для бесконечного ожидания #define WAIT_FOREVER FOREVER piMinSleep(); //! \~\brief //! \~english Global variable enabling output to piCout, default is true //! \~russian Глобальная переменная, включающая вывод в piCout, при старте true extern PIP_EXPORT bool piDebug; //! \~\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; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef unsigned long long ullong; typedef long long llong; typedef long double ldouble; //! \~\brief //! \~english Templated function for swap two values //! \~russian Шаблонный метод для перестановки двух значений //! \~\details //! \~english Example:\n \snippet piincludes.cpp swap //! \~russian Пример:\n \snippet piincludes.cpp swap template inline void piSwap(T & f, T & s) {T t(std::move(f)); f = std::move(s); s = std::move(t);} //! \~\brief //! \~english Templated function for swap two values without "=" //! \~russian Шаблонный метод для перестановки двух значений без использования "=" //! \~\details //! \~english Example:\n \snippet piincludes.cpp swapBinary //! \~russian Пример:\n \snippet piincludes.cpp swapBinary template 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); size_t i = 0; for (i = 0; i < j; ++i) { ((size_t*)(&f))[i] ^= ((size_t*)(&s))[i]; ((size_t*)(&s))[i] ^= ((size_t*)(&f))[i]; ((size_t*)(&f))[i] ^= ((size_t*)(&s))[i]; } for (i = bs; i < bf; ++i) { ((uchar*)(&f))[i] ^= ((uchar*)(&s))[i]; ((uchar*)(&s))[i] ^= ((uchar*)(&f))[i]; ((uchar*)(&f))[i] ^= ((uchar*)(&s))[i]; } } template<> inline void piSwapBinary(const void *& f, const void *& s) { if ((size_t*)f == (size_t*)s) return; size_t j = (sizeof(void *) / sizeof(size_t)), bs = j * sizeof(size_t), bf = sizeof(void *); size_t i = 0; void * pf = const_cast(f), * ps = const_cast(s); for (i = 0; i < j; ++i) { ((size_t*)(&pf))[i] ^= ((size_t*)(&ps))[i]; ((size_t*)(&ps))[i] ^= ((size_t*)(&pf))[i]; ((size_t*)(&pf))[i] ^= ((size_t*)(&ps))[i]; } for (i = bs; i < bf; ++i) { ((uchar*)(&pf))[i] ^= ((uchar*)(&ps))[i]; ((uchar*)(&ps))[i] ^= ((uchar*)(&pf))[i]; ((uchar*)(&pf))[i] ^= ((uchar*)(&ps))[i]; } } //! \~\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]) return false; return true; } //! \~\brief //! \~english Templated function return round of float falue //! \~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 inline constexpr int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));} //! \~\brief //! \~english Templated function return floor of float falue //! \~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 inline constexpr int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);} //! \~\brief //! \~english Templated function return ceil of float falue //! \~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 inline constexpr int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;} //! \~\brief //! \~english Templated function return absolute of numeric falue //! \~russian Шаблонный метод, возвращающий модуль числового значения //! \~\details //! \~english //! Absolute is the positive or equal 0 value \n //! There are some macros: //! - \c piAbss for "short" //! - \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 inline constexpr T piAbs(const T & v) {return (v >= T(0) ? v : -v);} //! \~\brief //! \~english Templated function return minimum of two values //! \~russian Шаблонный метод, возвращающий минимум из двух значений //! \~\details //! \~english //! There are some macros: //! - \c piMins for "short" //! - \c piMini for "int" //! - \c piMinl for "long" //! - \c piMinll for "llong" //! - \c piMinf 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 inline constexpr T piMin(const T & f, const T & s) {return ((f > s) ? s : f);} //! \~\brief //! \~english Templated function return minimum of tree values //! \~russian Шаблонный метод, возвращающий минимум из трех значений //! \~\details //! \~english //! There are some macros: //! - \c piMins for "short" //! - \c piMini for "int" //! - \c piMinl for "long" //! - \c piMinll for "llong" //! - \c piMinf 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 inline constexpr T piMin(const T & f, const T & s, const T & t) {return ((f < s && f < t) ? f : ((s < t) ? s : t));} //! \~\brief //! \~english Templated function return maximum of two values //! \~russian Шаблонный метод, возвращающий максимум из двух значений //! \~\details //! \~english //! There are some macros: //! - \c piMaxs for "short" //! - \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 inline constexpr T piMax(const T & f, const T & s) {return ((f < s) ? s : f);} //! \~\brief //! \~english Templated function return maximum of tree values //! \~russian Шаблонный метод, возвращающий максимум из трех значений //! \~\details //! \~english //! There are some macros: //! - \c piMaxs for "short" //! - \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 inline constexpr T piMax(const T & f, const T & s, const T & t) {return ((f > s && f > t) ? f : ((s > t) ? s : t));} //! \~\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 "short" //! - \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 inline constexpr T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));} //! \~\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*)data)[size - i - 1], ((uchar*)data)[i]); } //! \~\brief //! \~english Function for compare two numeric values 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 inline bool piCompare(const T & a, const T & b, const T & epsilon = std::numeric_limits::epsilon()) { return piAbs(a - b) <= epsilon; } //! \~\brief //! \~english Templated function that inverse byte order of value "v" //! \~russian Шаблонный метод, меняющий порядок байт в переменной "v" template inline void piLetobe(T * v) {piLetobe(v, sizeof(T));} //! \~\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 inline T piLetobe(const T & v) {T tv(v); piLetobe(&tv, sizeof(T)); return tv;} // specialization template<> inline uint16_t piLetobe(const uint16_t & v) {return (v << 8) | (v >> 8);} template<> inline uint32_t piLetobe(const uint32_t & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);} template<> inline float piLetobe(const float & v) { union _pletobe_f { _pletobe_f(const float &f_) {f = f_;} float f; uint32_t v; }; _pletobe_f a(v); a.v = (a.v >> 24) | ((a.v >> 8) & 0xFF00) | ((a.v << 8) & 0xFF0000) | ((a.v << 24) & 0xFF000000); return a.f; } //! \~\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; if (len > 3) { uint i = len >> 2; do { uint k; memcpy(&k, data, sizeof(uint)); data += sizeof(uint); k *= 0xcc9e2d51; k = (k << 15) | (k >> 17); k *= 0x1b873593; h ^= k; h = (h << 13) | (h >> 19); h = h * 5 + 0xe6546b64; } while (--i); } if (len & 3) { uint i = len & 3; uint k = 0; do { k <<= 8; k |= data[i - 1]; } while (--i); k *= 0xcc9e2d51; k = (k << 15) | (k >> 17); k *= 0x1b873593; h ^= k; } h ^= len; h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } template inline uint piHash(const T & v) { return 0; } template<> inline uint piHash(const char & v) {return (uint)v;} template<> inline uint piHash(const uchar & v) {return (uint)v;} template<> inline uint piHash(const short & v) {return (uint)v;} template<> inline uint piHash(const ushort & v) {return (uint)v;} template<> inline uint piHash(const int & v) {return (uint)v;} template<> inline uint piHash(const uint & v) {return (uint)v;} template<> inline uint piHash(const llong & v) {return piHashData((const uchar *)&v, sizeof(v));} template<> inline uint piHash(const ullong & v) {return piHashData((const uchar *)&v, sizeof(v));} template<> inline uint piHash(const float & v) {return (uint)v;} template<> inline uint piHash(const double & v) {return piHashData((const uchar *)&v, sizeof(v));} template<> inline uint piHash(const ldouble & v) {return piHashData((const uchar *)&v, sizeof(v));} #define piRoundf piRound #define piRoundd piRound #define piComparef piCompare #define piCompared piCompare #define piFloorf piFloor #define piFloord piFloor #define piCeilf piCeil #define piCeild piCeil #define piAbss piAbs #define piAbsi piAbs #define piAbsl piAbs #define piAbsll piAbs #define piAbsf piAbs #define piAbsd piAbs #define piMins piMin #define piMini piMin #define piMinl piMin #define piMinll piMin #define piMinf piMin #define piMind piMin #define piMaxs piMax #define piMaxi piMax #define piMaxl piMax #define piMaxll piMax #define piMaxf piMax #define piMaxd piMax #define piClamps piClamp #define piClampi piClamp #define piClampl piClamp #define piClampll piClamp #define piClampf piClamp #define piClampd piClamp #define piLetobes piLetobe #define piLetobei piLetobe #define piLetobel piLetobe #define piLetobell piLetobe #define piLetobef piLetobe #endif // PIBASE_H