diff --git a/libs/main/core/pibase.h b/libs/main/core/pibase.h index ed2cfb17..4da1ba6a 100644 --- a/libs/main/core/pibase.h +++ b/libs/main/core/pibase.h @@ -534,18 +534,41 @@ inline uint piHash(const ldouble & v) { return piHashData((const uchar *)&v, sizeof(v)); } +//! \~\brief +//! \~english Call \b delete on each "container" element. +//! \~russian Вызывает \b delete на каждый элемент "container". template inline void piDeleteAll(const T & container) { for (auto i: container) { delete i; } } + +//! \~\brief +//! \~english Call \b delete on each element of +//! [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list). +//! \~russian Вызывает \b delete на каждый элемент +//! [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list). +template +inline void piDeleteAll(std::initializer_list container) { + for (auto i: container) { + delete i; + } +} + +//! \~\brief +//! \~english Call \b delete on each "container" element and clear container. +//! \~russian Вызывает \b delete на каждый элемент "container" и очищает контейнер. template inline void piDeleteAllAndClear(T & container) { piDeleteAll(container); container.clear(); } + +//! \~\brief +//! \~english Call \b delete if "pointer" is not null and set it to null. Returns if deleted. +//! \~russian Вызывает \b delete на "pointer" если он не нулевой и устанавливает его в ноль. Возвращает было ли удаление. template inline bool piDeleteSafety(T *& pointer) { if (!pointer) return false; @@ -593,12 +616,48 @@ inline bool piDeleteSafety(T *& pointer) { #define piLetobef piLetobe +//! \~\brief +//! \~english Class for executing a function upon scope exit +//! \~russian Класс для выполнения функции при выходе из области видимости +//! \~\details +//! \~english Example +//! \~russian Пример +//! \~\code +//! bool yourFunc() { +//! PIScopeExitCall error_call([]() { piCout << "Error!"; }); +//! ... +//! if (!good0) { +//! ... +//! return false; +//! } +//! if (!good1) { +//! ... +//! return false; +//! } +//! ... +//! error_call.cancel(); +//! return true; +//! } +//! \endcode +//! \~english In this example "Error!" will be printed on every \b false function return. +//! \~russian В данном примере будет выведен "Error!" при каждом \b false возврате из функции. class PIP_EXPORT PIScopeExitCall { public: + //! \~\brief + //! \~english Constructor that takes a function to execute + //! \~russian Конструктор, который принимает функцию для выполнения explicit PIScopeExitCall(std::function f): func(f) {} + + //! \~\brief + //! \~english Destructor that executes the function if it exists + //! \~russian Деструктор, который выполняет функцию, если она существует ~PIScopeExitCall() { if (func) func(); } + + //! \~\brief + //! \~english Method for canceling the function + //! \~russian Метод для отмены функции void cancel() { func = nullptr; } private: diff --git a/libs/main/core/piincludes.h b/libs/main/core/piincludes.h index 08342a8a..a7eef0fa 100644 --- a/libs/main/core/piincludes.h +++ b/libs/main/core/piincludes.h @@ -54,18 +54,14 @@ extern PIP_EXPORT lconv * currentLocale; //! \ingroup Core //! \brief -//! \~english -//! Return readable error description in format "code - " -//! \~russian -//! Возвращает читаемое описание ошибки в формате "code <номер> - <описание>" +//! \~english Return readable error description in format "code - " +//! \~russian Возвращает читаемое описание ошибки в формате "code <номер> - <описание>" PIP_EXPORT PIString errorString(); //! \ingroup Core //! \brief -//! \~english -//! Reset last error -//! \~russian -//! Сброс последней ошибки +//! \~english Reset last error +//! \~russian Сброс последней ошибки PIP_EXPORT void errorClear(); PIP_EXPORT void randomize(); diff --git a/libs/main/core/piinit.cpp b/libs/main/core/piinit.cpp index 07e5b326..dd8fcb53 100644 --- a/libs/main/core/piinit.cpp +++ b/libs/main/core/piinit.cpp @@ -92,10 +92,8 @@ void __sighandler__(PISignals::Signal s) { PIInit::PIInit() { - file_charset = 0; PISystemInfo * sinfo = PISystemInfo::instance(); sinfo->execDateTime = PIDateTime::current(); - setFileCharset("UTF-8"); # ifndef ANDROID PISignals::setSlot(__sighandler__); PISignals::grabSignals(PISignals::UserDefined1); @@ -266,8 +264,6 @@ PIInit::PIInit() { PIInit::~PIInit() { - if (file_charset) delete[] file_charset; - file_charset = 0; PIResourcesStorage::instance()->clear(); # ifdef WINDOWS WSACleanup(); @@ -365,17 +361,6 @@ PIStringList PIInit::buildOptions() { } -void PIInit::setFileCharset(const char * charset) { - if (file_charset) delete file_charset; - file_charset = 0; - if (charset) { - file_charset = new char[1024]; - memset(file_charset, 0, 1024); - strcpy(file_charset, charset); - } -} - - bool PIInit::fileExists(const PIString & p) { FILE * f = fopen(p.data(), "r"); if (f == 0) return false; diff --git a/libs/main/core/piinit.h b/libs/main/core/piinit.h index efbab863..b1ba9c2e 100644 --- a/libs/main/core/piinit.h +++ b/libs/main/core/piinit.h @@ -82,10 +82,8 @@ public: private: explicit PIInit(); - void setFileCharset(const char * charset); bool fileExists(const PIString & p); PRIVATE_DECLARATION(PIP_EXPORT) - char * file_charset; }; diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index 049fb583..705c420b 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -41,7 +41,7 @@ class PIP_EXPORT PIObject { #ifndef MICRO_PIP friend class PIObjectManager; - friend void dumpApplication(bool); + friend PIP_EXPORT void dumpApplication(bool); friend class PIIntrospection; #endif typedef PIObject __PIObject__; diff --git a/libs/main/text/pistring.cpp b/libs/main/text/pistring.cpp index 715c50df..f91303ea 100644 --- a/libs/main/text/pistring.cpp +++ b/libs/main/text/pistring.cpp @@ -20,6 +20,7 @@ #include "pistring.h" #include "piincludes_p.h" +#include "piliterals.h" #include "pimathbase.h" #include "pistringlist.h" #ifdef PIP_ICU @@ -254,7 +255,7 @@ PIString PIString::fromNumberBaseU(const ullong value, int base, bool * ok) { llong PIString::toNumberBase(const PIString & value, int base, bool * ok) { - static const PIString s_0x = PIStringAscii("0x"); + static const PIString s_0x = "0x"_a; PIString v = value.trimmed(); if (base < 0) { int ind = v.find(s_0x); @@ -430,11 +431,11 @@ PIString PIString::fromCodepage(const char * s, const char * c) { //! Пример: //! \~\code //! piCout << PIString::readableSize(512); // 512 B -//! piCout << PIString::readableSize(5120); // 5.0 kB -//! piCout << PIString::readableSize(512000); // 500.0 kB -//! piCout << PIString::readableSize(5120000); // 4.8 MB -//! piCout << PIString::readableSize(512000000); // 488.2 MB -//! piCout << PIString::readableSize(51200000000); // 47.6 GB +//! piCout << PIString::readableSize(5120); // 5.0 KiB +//! piCout << PIString::readableSize(512000); // 500.0 KiB +//! piCout << PIString::readableSize(5120000); // 4.8 MiB +//! piCout << PIString::readableSize(512000000); // 488.2 MiB +//! piCout << PIString::readableSize(51200000000); // 47.6 GiB //! \endcode PIString PIString::readableSize(llong bytes) { PIString s; @@ -894,7 +895,7 @@ PIString & PIString::insert(int index, const PIString & str) { PIString & PIString::elide(int size, float pos) { - static const PIString s_dotdot = PIStringAscii(".."); + static const PIString s_dotdot = ".."_a; if (length() <= size) return *this; if (length() <= 2) { fill('.'); @@ -1185,10 +1186,10 @@ bool PIString::endsWith(const PIString & str) const { //! piCout << PIString("").toBool(); // false //! \endcode bool PIString::toBool() const { - static const PIString s_true = PIStringAscii("true"); - static const PIString s_yes = PIStringAscii("yes"); - static const PIString s_on = PIStringAscii("on"); - static const PIString s_ok = PIStringAscii("ok"); + static const PIString s_true = "true"_a; + static const PIString s_yes = "yes"_a; + static const PIString s_on = "on"_a; + static const PIString s_ok = "ok"_a; PIString s(*this); s = s.trimmed().toLowerCase(); if (s == s_true || s == s_yes || s == s_on || s == s_ok) return true; @@ -1662,59 +1663,59 @@ ldouble PIString::toLDouble() const { //! s.setReadableSize(512); //! piCout << s; // 512 B //! s.setReadableSize(5120); -//! piCout << s; // 5.0 kB +//! piCout << s; // 5.0 KiB //! s.setReadableSize(512000); -//! piCout << s; // 500.0 kB +//! piCout << s; // 500.0 KiB //! s.setReadableSize(5120000); -//! piCout << s; // 4.8 MB +//! piCout << s; // 4.8 MiB //! s.setReadableSize(512000000); -//! piCout << s; // 488.2 MB +//! piCout << s; // 488.2 MiB //! s.setReadableSize(51200000000); -//! piCout << s; // 47.6 GB +//! piCout << s; // 47.6 GiB //! \endcode PIString & PIString::setReadableSize(llong bytes) { clear(); if (bytes < 1024) { - *this += (PIString::fromNumber(bytes) + PIStringAscii(" B")); + *this += (PIString::fromNumber(bytes) + " B"_a); return *this; } double fres = bytes / 1024.; llong res = bytes / 1024; fres -= res; if (res < 1024) { - *this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" kB")); + *this += (PIString::fromNumber(res) + "."_a + PIString::fromNumber(llong(fres * 10)).left(1) + " KiB"_a); return *this; } fres = res / 1024.; res /= 1024; fres -= res; if (res < 1024) { - *this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" MB")); + *this += (PIString::fromNumber(res) + "."_a + PIString::fromNumber(llong(fres * 10)).left(1) + " MiB"_a); return *this; } fres = res / 1024.; res /= 1024; fres -= res; if (res < 1024) { - *this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" GB")); + *this += (PIString::fromNumber(res) + "."_a + PIString::fromNumber(llong(fres * 10)).left(1) + " GiB"_a); return *this; } fres = res / 1024.; res /= 1024; fres -= res; if (res < 1024) { - *this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" TB")); + *this += (PIString::fromNumber(res) + "."_a + PIString::fromNumber(llong(fres * 10)).left(1) + " TiB"_a); return *this; } fres = res / 1024.; res /= 1024; fres -= res; - *this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" PB")); + *this += (PIString::fromNumber(res) + "."_a + PIString::fromNumber(llong(fres * 10)).left(1) + " PiB"_a); return *this; } -const static PIString _versionDelims_ = PIStringAscii("._-+"); +const static PIString _versionDelims_ = "._-+"_a; void parseVersion(PIString s, PIVector & codes, PIStringList & strs) { @@ -1731,7 +1732,7 @@ void parseVersion(PIString s, PIVector & codes, PIStringList & strs) { if (ind > s.size_s() - 1) break; } for (int i = 0; i < mccnt; ++i) { - s.insert(ind, PIStringAscii(".0")); + s.insert(ind, ".0"_a); } } PIStringList comps; @@ -1762,20 +1763,20 @@ void parseVersion(PIString s, PIVector & codes, PIStringList & strs) { int versionLabelValue(PIString s) { int ret = -10000; if (s.isEmpty()) return 0; - if (s.startsWith(PIStringAscii("pre"))) { + if (s.startsWith("pre"_a)) { s.cutLeft(3); ret -= 1; } - if (s.startsWith(PIStringAscii("rc"))) { + if (s.startsWith("rc"_a)) { s.cutLeft(2); ret += s.toInt(); } - if (s.startsWith(PIStringAscii("r"))) { + if (s.startsWith("r"_a)) { s.cutLeft(1); ret += 10000 + s.toInt(); } - if (s == PIStringAscii("alpha")) ret -= 4; - if (s == PIStringAscii("beta")) ret -= 2; + if (s == "alpha"_a) ret -= 4; + if (s == "beta"_a) ret -= 2; return ret; } diff --git a/libs/main/text/pistring.h b/libs/main/text/pistring.h index 2a3f7d28..d96e12b5 100644 --- a/libs/main/text/pistring.h +++ b/libs/main/text/pistring.h @@ -1565,8 +1565,8 @@ public: return *this; } - //! \~english Set string content to human readable size in B/kB/MB/GB/TB/PB. - //! \~russian Устанавливает содержимое в строку с читаемым размером B/kB/MB/GB/TB/PB. + //! \~english Set string content to human readable size in B/KiB/MiB/GiB/TiB/PiB. + //! \~russian Устанавливает содержимое в строку с читаемым размером B/KiB/MiB/GiB/TiB/PiB. //! \~\sa PIString::readableSize() PIString & setReadableSize(llong bytes); @@ -1718,8 +1718,8 @@ public: //! \~russian Возвращает строку созданную из кодировки "cp". static PIString fromCodepage(const char * s, const char * cp); - //! \~english Returns string contains human readable size in B/kB/MB/GB/TB/PB. - //! \~russian Возвращает строку с читаемым размером B/kB/MB/GB/TB/PB. + //! \~english Returns string contains human readable size in B/KiB/MiB/GiB/TiB/PiB. + //! \~russian Возвращает строку с читаемым размером B/KiB/MiB/GiB/TiB/PiB. //! \~\sa PIString::setReadableSize() static PIString readableSize(llong bytes); diff --git a/libs/main/thread/pitimer.cpp b/libs/main/thread/pitimer.cpp index c8a7b30f..16cb36a0 100644 --- a/libs/main/thread/pitimer.cpp +++ b/libs/main/thread/pitimer.cpp @@ -21,6 +21,7 @@ #include "piconditionvar.h" #include "piincludes_p.h" +#include "piliterals.h" #ifdef PIP_TIMER_RT # include #endif @@ -242,7 +243,7 @@ private: _PITimerImp_Thread::_PITimerImp_Thread() { - thread_.setName("__S__PITimerImp_Thread::thread"); + thread_.setName("__S__PITimerImp_Thread::thread"_a); wait_dt = 1000; wait_dd = 2000; wait_tick = 1000; @@ -259,7 +260,7 @@ void _PITimerImp_Thread::prepareStart(double interval_ms) { } st_inc = PISystemTime::fromMilliseconds(interval_ms); st_odt = st_inc * 5; - if (st_odt.toSeconds() < 1.) st_odt = PISystemTime::fromSeconds(1.); + if (st_odt.toSeconds() < 1.) st_odt = 1_s; if (deferred_) { if (!deferred_mode) st_time = PISystemTime::current(true) + PISystemTime::fromMilliseconds(deferred_delay); st_time -= st_inc; @@ -452,7 +453,7 @@ _PITimerImp_Pool::_PITimerImp_Pool(): _PITimerImp_Thread() { _PITimerImp_Pool::Pool::Pool(): PIThread() { - setName("__S__PITimerImp_Pool::Pool"); + setName("__S__PITimerImp_Pool::Pool"_a); needLockRun(true); #ifndef FREERTOS timers.reserve(64); diff --git a/libs/main/thread/pitimer.h b/libs/main/thread/pitimer.h index d2bef27a..1f74cba7 100644 --- a/libs/main/thread/pitimer.h +++ b/libs/main/thread/pitimer.h @@ -267,10 +267,10 @@ public: //! \~english Stop and start timer with \a interval() loop delay //! \~russian Остановить и запустить таймер с интервалом \a interval() - //! \fn bool stop(bool wait = true) + //! \fn bool stop() //! \brief - //! \~english Stop timer and wait for it finish if "wait" - //! \~russian Остановить таймер и если "wait" то дождаться остановки + //! \~english Stop timer and wait for it finish + //! \~russian Остановить таймер и дождаться остановки //! \fn void clearDelimiters() //! \brief diff --git a/main.cpp b/main.cpp index f46f22a9..c06b4200 100644 --- a/main.cpp +++ b/main.cpp @@ -28,10 +28,6 @@ REGISTER_VARIANT_CAST(PIString, SomeType) { #include "piliterals.h" int main(int argc, char * argv[]) { - // clang-format off - piCout << 0.5_s; - // clang-format on - return 0; /*PIValueTree root; root.addChild({"bool", PIVariant(false)}); root.addChild({"integer", PIVariant(256)}); @@ -72,6 +68,7 @@ int main(int argc, char * argv[]) { // piCout << e.toString(); // piCout << PIVariantTypes::Enum::fromString(e.toString()).toString(); // piCout << PIVariantTypes::Enum::fromString("\"MyEnum\"(\"Null\":10105 \"Sec\":20 \"Fir\":100) 20").toString(); + { PIScopeExitCall ec([]() { piCout << "exit"; }); ec.cancel();