diff options
Diffstat (limited to 'zen')
-rwxr-xr-x | zen/format_unit.cpp | 21 | ||||
-rwxr-xr-x | zen/format_unit.h | 26 | ||||
-rwxr-xr-x | zen/globals.h | 18 | ||||
-rwxr-xr-x | zen/guid.h | 2 | ||||
-rwxr-xr-x | zen/optional.h | 16 | ||||
-rwxr-xr-x | zen/perf.h | 7 | ||||
-rwxr-xr-x | zen/process_priority.cpp | 2 | ||||
-rwxr-xr-x | zen/scope_guard.h | 4 | ||||
-rwxr-xr-x | zen/sys_error.h | 6 | ||||
-rwxr-xr-x | zen/thread.h | 13 | ||||
-rwxr-xr-x | zen/time.h | 6 | ||||
-rwxr-xr-x | zen/zstring.h | 1 |
12 files changed, 66 insertions, 56 deletions
diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp index 09134c07..931a29be 100755 --- a/zen/format_unit.cpp +++ b/zen/format_unit.cpp @@ -161,38 +161,39 @@ std::wstring zen::formatFraction(double fraction) -std::wstring zen::impl::includeNumberSeparator(const std::wstring& number) +std::wstring zen::formatNumber(int64_t n) { //we have to include thousands separator ourselves; this doesn't work for all countries (e.g india), but is better than nothing //::setlocale (LC_ALL, ""); -> implicitly called by wxLocale - const lconv* localInfo = ::localeconv(); //always bound according to doc - const std::wstring& thousandSep = zen::utfTo<std::wstring>(localInfo->thousands_sep); + const lconv& localInfo = *::localeconv(); //always bound according to doc + const std::wstring& thousandSep = utfTo<std::wstring>(localInfo.thousands_sep); // THOUSANDS_SEPARATOR = std::use_facet<std::numpunct<wchar_t>>(std::locale("")).thousands_sep(); - why not working? // DECIMAL_POINT = std::use_facet<std::numpunct<wchar_t>>(std::locale("")).decimal_point(); - std::wstring output(number); - size_t i = output.size(); + std::wstring number = numberTo<std::wstring>(n); + + size_t i = number.size(); for (;;) { if (i <= 3) break; i -= 3; - if (!isDigit(output[i - 1])) //stop on +, - signs + if (!isDigit(number[i - 1])) //stop on +, - signs break; - output.insert(i, thousandSep); + number.insert(i, thousandSep); } - return output; + return number; } -std::wstring zen::formatUtcToLocalTime(int64_t utcTime) +std::wstring zen::formatUtcToLocalTime(time_t utcTime) { auto errorMsg = [&] { return _("Error") + L" (time_t: " + numberTo<std::wstring>(utcTime) + L")"; }; TimeComp loc = getLocalTime(utcTime); - + std::wstring dateString = formatTime<std::wstring>(L"%x %X", loc); return !dateString.empty() ? dateString : errorMsg(); } diff --git a/zen/format_unit.h b/zen/format_unit.h index 9c6a4690..23ab33fb 100755 --- a/zen/format_unit.h +++ b/zen/format_unit.h @@ -18,36 +18,14 @@ namespace zen std::wstring formatFilesizeShort(int64_t filesize); std::wstring formatRemainingTime(double timeInSec); std::wstring formatFraction(double fraction); //within [0, 1] -std::wstring formatUtcToLocalTime(int64_t utcTime); //like Windows Explorer would... +std::wstring formatUtcToLocalTime(time_t utcTime); //like Windows Explorer would... std::wstring formatTwoDigitPrecision (double value); //format with fixed number of digits std::wstring formatThreeDigitPrecision(double value); //(unless value is too large) -template <class NumberType> -std::wstring formatNumber(NumberType number); //format integer number including thousands separator +std::wstring formatNumber(int64_t n); //format integer number including thousands separator - - - - - - - - - -//--------------- inline impelementation ------------------------------------------- -namespace impl -{ -std::wstring includeNumberSeparator(const std::wstring& number); -} - -template <class NumberType> inline -std::wstring formatNumber(NumberType number) -{ - static_assert(IsInteger<NumberType>::value, ""); - return impl::includeNumberSeparator(zen::numberTo<std::wstring>(number)); -} } #endif diff --git a/zen/globals.h b/zen/globals.h index c57d97ff..2066c380 100755 --- a/zen/globals.h +++ b/zen/globals.h @@ -22,17 +22,17 @@ public: Global() { static_assert(std::is_trivially_destructible<Pod>::value, "this memory needs to live forever"); - assert(!pod.inst && !pod.spinLock); //we depend on static zero-initialization! + assert(!pod_.inst && !pod_.spinLock); //we depend on static zero-initialization! } explicit Global(std::unique_ptr<T>&& newInst) { set(std::move(newInst)); } ~Global() { set(nullptr); } std::shared_ptr<T> get() //=> return std::shared_ptr to let instance life time be handled by caller (MT usage!) { - while (pod.spinLock.exchange(true)) ; - ZEN_ON_SCOPE_EXIT(pod.spinLock = false); - if (pod.inst) - return *pod.inst; + while (pod_.spinLock.exchange(true)) ; + ZEN_ON_SCOPE_EXIT(pod_.spinLock = false); + if (pod_.inst) + return *pod_.inst; return nullptr; } @@ -42,9 +42,9 @@ public: if (newInst) tmpInst = new std::shared_ptr<T>(std::move(newInst)); { - while (pod.spinLock.exchange(true)) ; - ZEN_ON_SCOPE_EXIT(pod.spinLock = false); - std::swap(pod.inst, tmpInst); + while (pod_.spinLock.exchange(true)) ; + ZEN_ON_SCOPE_EXIT(pod_.spinLock = false); + std::swap(pod_.inst, tmpInst); } delete tmpInst; } @@ -58,7 +58,7 @@ private: std::shared_ptr<T>* inst; // = nullptr; std::atomic<bool> spinLock; // { false }; rely entirely on static zero-initialization! => avoid potential contention with worker thread during Global<> construction! //serialize access; can't use std::mutex: has non-trival destructor - } pod; + } pod_; }; } @@ -21,7 +21,7 @@ inline std::string generateGUID() //creates a 16-byte GUID { //perf: generator: 0.38ms per creation; - // retrieve GUID: 0.13µs per call + // retrieve GUID: 0.13µs per call //generator is only thread-safe like an int => keep thread-local thread_local boost::uuids::random_generator gen; const boost::uuids::uuid nativeRep = gen(); diff --git a/zen/optional.h b/zen/optional.h index 0ef5f1db..88928ac0 100755 --- a/zen/optional.h +++ b/zen/optional.h @@ -7,7 +7,7 @@ #ifndef OPTIONAL_H_2857428578342203589 #define OPTIONAL_H_2857428578342203589 -#include <cassert> +//#include <cassert> #include <type_traits> @@ -96,6 +96,20 @@ private: std::aligned_storage_t<sizeof(T), alignof(T)> rawMem_; //don't require T to be default-constructible! bool valid_ = false; }; + + +template <class T> inline +bool operator==(const Opt<T>& lhs, const Opt<T>& rhs) +{ + if (static_cast<bool>(lhs) != static_cast<bool>(rhs)) + return false; + if (!lhs) + return true; + return *lhs == *rhs; +} +template <class T> inline +bool operator!=(const Opt<T>& lhs, const Opt<T>& rhs) { return !(lhs == rhs); } + } #endif //OPTIONAL_H_2857428578342203589 @@ -19,6 +19,13 @@ #define PERF_STOP perfTest.showResult(); //########################################################################### +/* Example: Aggregated function call time: + + static zen::PerfTimer timer; + timer.resume(); + ZEN_ON_SCOPE_EXIT(timer.pause()); +*/ + namespace zen { class PerfTimer diff --git a/zen/process_priority.cpp b/zen/process_priority.cpp index e925f142..c2a7ed20 100755 --- a/zen/process_priority.cpp +++ b/zen/process_priority.cpp @@ -11,6 +11,8 @@ using namespace zen; +//wxPowerResourceBlocker? http://docs.wxwidgets.org/trunk/classwx_power_resource_blocker.html +//nah, "currently the power events are only available under Windows" struct PreventStandby::Impl {}; PreventStandby::PreventStandby() {} PreventStandby::~PreventStandby() {} diff --git a/zen/scope_guard.h b/zen/scope_guard.h index 6945b011..328e2caa 100755 --- a/zen/scope_guard.h +++ b/zen/scope_guard.h @@ -115,6 +115,10 @@ auto makeGuard(F&& fun) { return ScopeGuard<runMode, std::decay_t<F>>(std::forwa #define ZEN_CONCAT_SUB(X, Y) X ## Y #define ZEN_CONCAT(X, Y) ZEN_CONCAT_SUB(X, Y) +#define ZEN_CHECK_CASE_FOR_CONSTANT(X) case X: return ZEN_CHECK_CASE_FOR_CONSTANT_IMPL(#X) +#define ZEN_CHECK_CASE_FOR_CONSTANT_IMPL(X) L ## X + + #define ZEN_ON_SCOPE_EXIT(X) auto ZEN_CONCAT(dummy, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_EXIT >([&]{ X; }); (void)ZEN_CONCAT(dummy, __LINE__); #define ZEN_ON_SCOPE_FAIL(X) auto ZEN_CONCAT(dummy, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_FAIL >([&]{ X; }); (void)ZEN_CONCAT(dummy, __LINE__); #define ZEN_ON_SCOPE_SUCCESS(X) auto ZEN_CONCAT(dummy, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_SUCCESS>([&]{ X; }); (void)ZEN_CONCAT(dummy, __LINE__); diff --git a/zen/sys_error.h b/zen/sys_error.h index 31eb8209..c179ec8a 100755 --- a/zen/sys_error.h +++ b/zen/sys_error.h @@ -81,7 +81,11 @@ std::wstring formatSystemError(const std::wstring& functionName, long long lastE inline std::wstring formatSystemError(const std::wstring& functionName, ErrorCode ec) { - return formatSystemError(functionName, replaceCpy(_("Error Code %x"), L"%x", numberTo<std::wstring>(ec)), formatSystemErrorRaw(ec)); + //static_assert(sizeof(ec) == sizeof(int), ""); + //const std::wstring errorCode = printNumber<std::wstring>(L"0x%08x", static_cast<int>(ec)); + const std::wstring errorCode = numberTo<std::wstring>(ec); + + return formatSystemError(functionName, replaceCpy(_("Error Code %x"), L"%x", errorCode), formatSystemErrorRaw(ec)); } diff --git a/zen/thread.h b/zen/thread.h index bfb66c31..3721b3c7 100755 --- a/zen/thread.h +++ b/zen/thread.h @@ -37,12 +37,11 @@ public: template <class Rep, class Period> bool tryJoinFor(const std::chrono::duration<Rep, Period>& relTime) { - if (threadCompleted_.wait_for(relTime) == std::future_status::ready) - { - stdThread_.join(); //runs thread-local destructors => this better be fast!!! - return true; - } - return false; + if (threadCompleted_.wait_for(relTime) != std::future_status::ready) + return false; + + stdThread_.join(); //runs thread-local destructors => this better be fast!!! + return true; } private: @@ -297,7 +296,7 @@ public: setConditionVar(&cv); ZEN_ON_SCOPE_EXIT(setConditionVar(nullptr)); - //"interrupted" is not protected by cv's mutex => signal may get lost!!! => add artifical time out to mitigate! CPU: 0.25% vs 0% for longer time out! + //"interrupted_" is not protected by cv's mutex => signal may get lost!!! => add artifical time out to mitigate! CPU: 0.25% vs 0% for longer time out! while (!cv.wait_for(lock, std::chrono::milliseconds(1), [&] { return this->interrupted_ || pred(); })) ; @@ -48,9 +48,9 @@ template <class String, class String2> String formatTime(const String2& format, const TimeComp& tc = getLocalTime()); //format as specified by "std::strftime", returns empty string on failure //the "format" parameter of formatTime() is partially specialized with the following type tags: -const struct FormatDateTag {} FORMAT_DATE = {}; //%x - locale dependent date representation: e.g. 08/23/01 -const struct FormatTimeTag {} FORMAT_TIME = {}; //%X - locale dependent time representation: e.g. 14:55:02 -const struct FormatDateTimeTag {} FORMAT_DATE_TIME = {}; //%c - locale dependent date and time: e.g. Thu Aug 23 14:55:02 2001 +const struct FormatDateTag {} FORMAT_DATE = {}; //%x - locale dependent date representation: e.g. 8/23/2001 +const struct FormatTimeTag {} FORMAT_TIME = {}; //%X - locale dependent time representation: e.g. 2:55:02 PM +const struct FormatDateTimeTag {} FORMAT_DATE_TIME = {}; //%c - locale dependent date and time: e.g. 8/23/2001 2:55:02 PM const struct FormatIsoDateTag {} FORMAT_ISO_DATE = {}; //%Y-%m-%d - e.g. 2001-08-23 const struct FormatIsoTimeTag {} FORMAT_ISO_TIME = {}; //%H:%M:%S - e.g. 14:55:02 diff --git a/zen/zstring.h b/zen/zstring.h index b96842b5..258603dc 100755 --- a/zen/zstring.h +++ b/zen/zstring.h @@ -79,6 +79,7 @@ const wchar_t* const SPACED_DASH = L" \u2013 "; //using 'EN DASH' const wchar_t LTR_MARK = L'\u200E'; //UTF-8: E2 80 8E const wchar_t RTL_MARK = L'\u200F'; //UTF-8: E2 80 8F const wchar_t ELLIPSIS = L'\u2026'; //"..." +const wchar_t MULT_SIGN = L'\u00D7'; //fancy "x" |