diff options
author | B Stack <bgstack15@gmail.com> | 2018-09-09 18:53:23 -0400 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2018-09-09 18:53:23 -0400 |
commit | eb5d3e5df99de2c3d8da2e8bc7b12ed427465dba (patch) | |
tree | 0f0441755ff0e6d65e12222d4502c648bffd6a7c /zen | |
parent | 10.3 (diff) | |
download | FreeFileSync-eb5d3e5df99de2c3d8da2e8bc7b12ed427465dba.tar.gz FreeFileSync-eb5d3e5df99de2c3d8da2e8bc7b12ed427465dba.tar.bz2 FreeFileSync-eb5d3e5df99de2c3d8da2e8bc7b12ed427465dba.zip |
pull in latest 10.4 from upstream
Diffstat (limited to 'zen')
-rwxr-xr-x | zen/file_access.cpp | 24 | ||||
-rwxr-xr-x | zen/file_access.h | 8 | ||||
-rwxr-xr-x | zen/format_unit.h | 1 | ||||
-rwxr-xr-x | zen/legacy_compiler.h | 71 | ||||
-rwxr-xr-x | zen/optional.h | 114 | ||||
-rwxr-xr-x | zen/recycler.cpp | 2 | ||||
-rwxr-xr-x | zen/ring_buffer.h | 2 | ||||
-rwxr-xr-x | zen/shell_execute.h | 2 | ||||
-rwxr-xr-x | zen/socket.h | 2 | ||||
-rwxr-xr-x | zen/stl_tools.h | 30 | ||||
-rwxr-xr-x | zen/thread.h | 15 | ||||
-rwxr-xr-x | zen/utf.h | 23 | ||||
-rwxr-xr-x | zen/zstring.cpp | 4 | ||||
-rwxr-xr-x | zen/zstring.h | 2 |
14 files changed, 67 insertions, 233 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp index 9c351e25..a81fdae0 100755 --- a/zen/file_access.cpp +++ b/zen/file_access.cpp @@ -30,9 +30,9 @@ using namespace zen; -Opt<PathComponents> zen::parsePathComponents(const Zstring& itemPath) +std::optional<PathComponents> zen::parsePathComponents(const Zstring& itemPath) { - auto doParse = [&](int sepCountVolumeRoot, bool rootWithSep) -> Opt<PathComponents> + auto doParse = [&](int sepCountVolumeRoot, bool rootWithSep) -> std::optional<PathComponents> { const Zstring itemPathFmt = appendSeparator(itemPath); //simplify analysis of root without separator, e.g. \\server-name\share int sepCount = 0; @@ -47,7 +47,7 @@ Opt<PathComponents> zen::parsePathComponents(const Zstring& itemPath) return PathComponents({ rootPath, relPath }); } - return NoValue(); + return {}; }; if (startsWith(itemPath, "/")) @@ -72,17 +72,17 @@ Opt<PathComponents> zen::parsePathComponents(const Zstring& itemPath) } //we do NOT support relative paths! - return NoValue(); + return {}; } -Opt<Zstring> zen::getParentFolderPath(const Zstring& itemPath) +std::optional<Zstring> zen::getParentFolderPath(const Zstring& itemPath) { - if (const Opt<PathComponents> comp = parsePathComponents(itemPath)) + if (const std::optional<PathComponents> comp = parsePathComponents(itemPath)) { if (comp->relPath.empty()) - return NoValue(); + return {}; const Zstring parentRelPath = beforeLast(comp->relPath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_NONE); if (parentRelPath.empty()) @@ -90,7 +90,7 @@ Opt<Zstring> zen::getParentFolderPath(const Zstring& itemPath) return appendSeparator(comp->rootPath) + parentRelPath; } assert(false); - return NoValue(); + return {}; } @@ -110,7 +110,7 @@ ItemType zen::getItemType(const Zstring& itemPath) //throw FileError PathStatus zen::getPathStatus(const Zstring& itemPath) //throw FileError { - const Opt<Zstring> parentPath = getParentFolderPath(itemPath); + const std::optional<Zstring> parentPath = getParentFolderPath(itemPath); try { return { getItemType(itemPath), itemPath, {} }; //throw FileError @@ -145,12 +145,12 @@ PathStatus zen::getPathStatus(const Zstring& itemPath) //throw FileError } -Opt<ItemType> zen::getItemTypeIfExists(const Zstring& itemPath) //throw FileError +std::optional<ItemType> zen::getItemTypeIfExists(const Zstring& itemPath) //throw FileError { const PathStatus ps = getPathStatus(itemPath); //throw FileError if (ps.relPath.empty()) return ps.existingType; - return NoValue(); + return {}; } @@ -672,7 +672,7 @@ FileCopyResult copyFileOsSpecific(const Zstring& sourceFile, //throw FileError, //close output file handle before setting file time; also good place to catch errors when closing stream! fileOut.finalize(); //throw FileError, (X) essentially a close() since buffers were already flushed - Opt<FileError> errorModTime; + std::optional<FileError> errorModTime; try { //we cannot set the target file times (::futimes) while the file descriptor is still open after a write operation: diff --git a/zen/file_access.h b/zen/file_access.h index c62ddc98..916f23f5 100755 --- a/zen/file_access.h +++ b/zen/file_access.h @@ -23,9 +23,9 @@ struct PathComponents Zstring rootPath; //itemPath = rootPath + (FILE_NAME_SEPARATOR?) + relPath Zstring relPath; // }; -Opt<PathComponents> parsePathComponents(const Zstring& itemPath); //no value on failure +std::optional<PathComponents> parsePathComponents(const Zstring& itemPath); //no value on failure -Opt<Zstring> getParentFolderPath(const Zstring& itemPath); +std::optional<Zstring> getParentFolderPath(const Zstring& itemPath); //POSITIVE existence checks; if false: 1. item not existing 2. different type 3.device access error or similar bool fileAvailable(const Zstring& filePath); //noexcept @@ -42,7 +42,7 @@ enum class ItemType //(hopefully) fast: does not distinguish between error/not existing ItemType getItemType (const Zstring& itemPath); //throw FileError //execute potentially SLOW folder traversal but distinguish error/not existing -Opt<ItemType> getItemTypeIfExists(const Zstring& itemPath); //throw FileError +std::optional<ItemType> getItemTypeIfExists(const Zstring& itemPath); //throw FileError struct PathStatus { @@ -97,7 +97,7 @@ struct FileCopyResult time_t modTime = 0; //number of seconds since Jan. 1st 1970 UTC FileId sourceFileId; FileId targetFileId; - Opt<FileError> errorModTime; //failure to set modification time + std::optional<FileError> errorModTime; //failure to set modification time }; FileCopyResult copyNewFile(const Zstring& sourceFile, const Zstring& targetFile, bool copyFilePermissions, //throw FileError, ErrorTargetExisting, ErrorFileLocked diff --git a/zen/format_unit.h b/zen/format_unit.h index 23ab33fb..3686f39c 100755 --- a/zen/format_unit.h +++ b/zen/format_unit.h @@ -9,7 +9,6 @@ #include <string> #include <cstdint> -#include "optional.h" #include "string_tools.h" diff --git a/zen/legacy_compiler.h b/zen/legacy_compiler.h index 5a0013b3..e9d50b97 100755 --- a/zen/legacy_compiler.h +++ b/zen/legacy_compiler.h @@ -7,82 +7,13 @@ #ifndef LEGACY_COMPILER_H_839567308565656789 #define LEGACY_COMPILER_H_839567308565656789 - #include <memory> - #include <cstddef> //std::byte - + #include <optional> namespace std { //https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html //https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations -#ifndef __cpp_lib_type_trait_variable_templates //GCC 7.1 - template<class T, class U> constexpr bool is_same_v = is_same<T, U>::value; - template<class T> constexpr bool is_const_v = is_const<T>::value; - template<class T> constexpr bool is_signed_v = is_signed<T>::value; - template<class T> constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value; -#endif - -#if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 1) //GCC doesn't define __cpp_lib_raw_memory_algorithms -template<class T> void destroy_at(T* p) { p->~T(); } - -template< class ForwardIt > -void destroy(ForwardIt first, ForwardIt last) -{ - for (; first != last; ++first) - std::destroy_at(std::addressof(*first)); -} - -template<class InputIt, class ForwardIt> -ForwardIt uninitialized_move(InputIt first, InputIt last, ForwardIt trg_first) -{ - typedef typename std::iterator_traits<ForwardIt>::value_type Value; - ForwardIt current = trg_first; - try - { - for (; first != last; ++first, ++current) - ::new (static_cast<void*>(std::addressof(*current))) Value(std::move(*first)); - return current; - } - catch (...) - { - for (; trg_first != current; ++trg_first) - trg_first->~Value(); - throw; - } -} -#endif - -#ifndef __cpp_lib_apply //GCC 7.1 -template <class F, class T0, class T1, class T2> -constexpr decltype(auto) apply(F&& f, std::tuple<T0, T1, T2>& t) { return f(std::get<0>(t), std::get<1>(t), std::get<2>(t)); } -#endif - -#if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 1) //__cpp_lib_byte not defined before GCC 7.3 but supported earlier - typedef unsigned char byte; -#endif - -#ifndef __cpp_lib_bool_constant //GCC 6.1 - template<bool B> using bool_constant = integral_constant<bool, B>; -#endif - -//================================================================================ - -} -namespace __cxxabiv1 -{ -struct __cxa_eh_globals; -extern "C" __cxa_eh_globals* __cxa_get_globals() noexcept; -} -namespace std -{ -inline int uncaught_exceptions_legacy_hack() noexcept -{ - return *(reinterpret_cast<unsigned int*>(static_cast<char*>(static_cast<void*>(__cxxabiv1::__cxa_get_globals())) + sizeof(void*))); -} -#ifndef __cpp_lib_uncaught_exceptions //GCC 6.1 -inline int uncaught_exceptions() noexcept { return uncaught_exceptions_legacy_hack(); } -#endif } diff --git a/zen/optional.h b/zen/optional.h deleted file mode 100755 index e4605c5f..00000000 --- a/zen/optional.h +++ /dev/null @@ -1,114 +0,0 @@ -// ***************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0 * -// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * -// ***************************************************************************** - -#ifndef OPTIONAL_H_2857428578342203589 -#define OPTIONAL_H_2857428578342203589 - -#include <type_traits> - - -namespace zen -{ -/* -Optional return value without heap memory allocation! - -> interface like a pointer, performance like a value - - Usage: - ------ - Opt<MyEnum> someFunction(); -{ - if (allIsWell) - return enumVal; - else - return NoValue(); -} - - Opt<MyEnum> optValue = someFunction(); - if (optValue) - ... use *optValue ... -*/ - -struct NoValue {}; - -template <class T> -class Opt -{ -public: - Opt() {} - Opt(NoValue) {} - Opt(const T& val) : valid_(true) { new (&rawMem_) T(val); } //throw X - Opt( T&& tmp) : valid_(true) { new (&rawMem_) T(std::move(tmp)); } - - Opt(const Opt& other) : valid_(other.valid_) - { - if (const T* val = other.get()) - new (&rawMem_) T(*val); //throw X - } - - ~Opt() { if (T* val = get()) val->~T(); } - - Opt& operator=(const Opt& other) //strong exception-safety iff T::operator=() is strongly exception-safe - { - if (T* val = get()) - { - if (const T* valOther = other.get()) - *val = *valOther; //throw X - else - { - valid_ = false; - val->~T(); - } - } - else if (const T* valOther = other.get()) - { - new (&rawMem_) T(*valOther); //throw X - valid_ = true; - } - return *this; - } - - Opt& operator=(NoValue) //support assignment to Opt<const T> - { - if (T* val = get()) - { - valid_ = false; - val->~T(); - } - return *this; - } - - explicit operator bool() const { return valid_; } //thank you, C++11!!! - - const T* get() const { return valid_ ? reinterpret_cast<const T*>(&rawMem_) : nullptr; } - T* get() { return valid_ ? reinterpret_cast< T*>(&rawMem_) : nullptr; } - - const T& operator*() const { return *get(); } - /**/ T& operator*() { return *get(); } - - const T* operator->() const { return get(); } - /**/ T* operator->() { return get(); } - -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 diff --git a/zen/recycler.cpp b/zen/recycler.cpp index 30b37cb2..8b4389a7 100755 --- a/zen/recycler.cpp +++ b/zen/recycler.cpp @@ -27,7 +27,7 @@ bool zen::recycleOrDeleteIfExists(const Zstring& itemPath) //throw FileError if (!::g_file_trash(file, nullptr, &error)) { - const Opt<ItemType> type = getItemTypeIfExists(itemPath); //throw FileError + const std::optional<ItemType> type = getItemTypeIfExists(itemPath); //throw FileError if (!type) return false; diff --git a/zen/ring_buffer.h b/zen/ring_buffer.h index 6debd84e..232e17da 100755 --- a/zen/ring_buffer.h +++ b/zen/ring_buffer.h @@ -10,8 +10,8 @@ #include <cassert> #include <vector> #include <stdexcept> -#include "type_traits.h" #include "scope_guard.h" +#include "string_tools.h" namespace zen diff --git a/zen/shell_execute.h b/zen/shell_execute.h index a0e5634b..0802fbcb 100755 --- a/zen/shell_execute.h +++ b/zen/shell_execute.h @@ -73,7 +73,7 @@ void shellExecute(const Zstring& command, ExecutionType type) //throw FileError inline void openWithDefaultApplication(const Zstring& itemPath) //throw FileError { - shellExecute("xdg-open \"" + itemPath + "\"", ExecutionType::ASYNC); // + shellExecute("xdg-open \"" + itemPath + "\"", ExecutionType::ASYNC); // } } diff --git a/zen/socket.h b/zen/socket.h index c92071e2..e551a5ba 100755 --- a/zen/socket.h +++ b/zen/socket.h @@ -53,7 +53,7 @@ public: return testSocket; }; - Opt<SysError> firstError; + std::optional<SysError> firstError; for (const auto* /*::addrinfo*/ si = servinfo; si; si = si->ai_next) try { diff --git a/zen/stl_tools.h b/zen/stl_tools.h index 7365392f..be9bf710 100755 --- a/zen/stl_tools.h +++ b/zen/stl_tools.h @@ -12,7 +12,7 @@ #include <vector> #include <memory> #include <algorithm> -#include "type_traits.h" +#include "string_traits.h" #include "build_info.h" @@ -42,8 +42,11 @@ void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c); template <class T, class Alloc> void removeDuplicates(std::vector<T, Alloc>& v); +template <class T, class Alloc, class CompLess> +void removeDuplicates(std::vector<T, Alloc>& v, CompLess less); + //binary search returning an iterator -template <class Iterator, class T, typename CompLess> +template <class Iterator, class T, class CompLess> Iterator binary_search(Iterator first, Iterator last, const T& value, CompLess less); template <class BidirectionalIterator, class T> @@ -70,6 +73,9 @@ struct StringHash }; +//why, oh wy is there no std::optional<T>::get()??? +template <class T> inline T* get( std::optional<T>& opt) { return opt ? &*opt : nullptr; } +template <class T> inline const T* get(const std::optional<T>& opt) { return opt ? &*opt : nullptr; } @@ -117,15 +123,29 @@ template <class KeyType, class ValueType, class LessType, class Alloc, class C> void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c) { m.insert(c.begin(), c.end()); } +template <class T, class Alloc, class CompLess, class CompEqual> inline +void removeDuplicates(std::vector<T, Alloc>& v, CompLess less, CompEqual eq) +{ + std::sort(v.begin(), v.end(), less); + v.erase(std::unique(v.begin(), v.end(), eq), v.end()); +} + + +template <class T, class Alloc, class CompLess> inline +void removeDuplicates(std::vector<T, Alloc>& v, CompLess less) +{ + removeDuplicates(v, less, [&](const auto& lhs, const auto& rhs) { return !less(lhs, rhs) && !less(rhs, lhs); }); +} + + template <class T, class Alloc> inline void removeDuplicates(std::vector<T, Alloc>& v) { - std::sort(v.begin(), v.end()); - v.erase(std::unique(v.begin(), v.end()), v.end()); + removeDuplicates(v, std::less<T>(), std::equal_to<T>()); } -template <class Iterator, class T, typename CompLess> inline +template <class Iterator, class T, class CompLess> inline Iterator binary_search(Iterator first, Iterator last, const T& value, CompLess less) { static_assert(std::is_same_v<typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>); diff --git a/zen/thread.h b/zen/thread.h index 5828d07a..7f3d216c 100755 --- a/zen/thread.h +++ b/zen/thread.h @@ -11,7 +11,6 @@ #include <future> #include "scope_guard.h" #include "ring_buffer.h" -#include "optional.h" #include "string_tools.h" @@ -97,13 +96,13 @@ public: GetFirstResult(); template <class Fun> - void addJob(Fun&& f); //f must return a zen::Opt<T> containing a value if successful + void addJob(Fun&& f); //f must return a std::optional<T> containing a value if successful template <class Duration> bool timedWait(const Duration& duration) const; //true: "get()" is ready, false: time elapsed //return first value or none if all jobs failed; blocks until result is ready! - Opt<T> get() const; //may be called only once! + std::optional<T> get() const; //may be called only once! private: class AsyncResult; @@ -323,7 +322,7 @@ class GetFirstResult<T>::AsyncResult { public: //context: worker threads - void reportFinished(Opt<T>&& result) + void reportFinished(std::optional<T>&& result) { { std::lock_guard<std::mutex> dummy(lockResult_); @@ -342,7 +341,7 @@ public: return conditionJobDone_.wait_for(dummy, duration, [&] { return this->jobDone(jobsTotal); }); } - Opt<T> getResult(size_t jobsTotal) + std::optional<T> getResult(size_t jobsTotal) { std::unique_lock<std::mutex> dummy(lockResult_); conditionJobDone_.wait(dummy, [&] { return this->jobDone(jobsTotal); }); @@ -355,7 +354,7 @@ private: std::mutex lockResult_; size_t jobsFinished_ = 0; // - Opt<T> result_; //our condition is: "have result" or "jobsFinished_ == jobsTotal" + std::optional<T> result_; //our condition is: "have result" or "jobsFinished_ == jobsTotal" std::condition_variable conditionJobDone_; }; @@ -367,7 +366,7 @@ GetFirstResult<T>::GetFirstResult() : asyncResult_(std::make_shared<AsyncResult> template <class T> template <class Fun> inline -void GetFirstResult<T>::addJob(Fun&& f) //f must return a zen::Opt<T> containing a value on success +void GetFirstResult<T>::addJob(Fun&& f) //f must return a std::optional<T> containing a value on success { std::thread t([asyncResult = this->asyncResult_, f = std::forward<Fun>(f)] { asyncResult->reportFinished(f()); }); ++jobsTotal_; @@ -381,7 +380,7 @@ bool GetFirstResult<T>::timedWait(const Duration& duration) const { return async template <class T> inline -Opt<T> GetFirstResult<T>::get() const { return asyncResult_->getResult(jobsTotal_); } +std::optional<T> GetFirstResult<T>::get() const { return asyncResult_->getResult(jobsTotal_); } //------------------------------------------------------------------------------------------ @@ -10,7 +10,6 @@ #include <cstdint> #include <iterator> #include "string_tools.h" //copyStringTo -#include "optional.h" namespace zen @@ -96,10 +95,10 @@ class Utf16Decoder public: Utf16Decoder(const Char16* str, size_t len) : it_(str), last_(str + len) {} - Opt<CodePoint> getNext() + std::optional<CodePoint> getNext() { if (it_ == last_) - return NoValue(); + return {}; const Char16 ch = *it_++; CodePoint cp = ch; @@ -190,10 +189,10 @@ class Utf8Decoder public: Utf8Decoder(const Char8* str, size_t len) : it_(str), last_(str + len) {} - Opt<CodePoint> getNext() + std::optional<CodePoint> getNext() { if (it_ == last_) - return NoValue(); + return std::nullopt; //GCC 8.2 bug: -Wmaybe-uninitialized for "return {};" const Char8 ch = *it_++; CodePoint cp = ch; @@ -268,7 +267,7 @@ class UtfDecoderImpl<CharType, 1> //UTF8-char { public: UtfDecoderImpl(const CharType* str, size_t len) : decoder_(reinterpret_cast<const Char8*>(str), len) {} - Opt<CodePoint> getNext() { return decoder_.getNext(); } + std::optional<CodePoint> getNext() { return decoder_.getNext(); } private: Utf8Decoder decoder_; }; @@ -279,7 +278,7 @@ class UtfDecoderImpl<CharType, 2> //Windows: UTF16-wchar_t { public: UtfDecoderImpl(const CharType* str, size_t len) : decoder_(reinterpret_cast<const Char16*>(str), len) {} - Opt<CodePoint> getNext() { return decoder_.getNext(); } + std::optional<CodePoint> getNext() { return decoder_.getNext(); } private: Utf16Decoder decoder_; }; @@ -290,10 +289,10 @@ class UtfDecoderImpl<CharType, 4> //other OS: UTF32-wchar_t { public: UtfDecoderImpl(const CharType* str, size_t len) : it_(reinterpret_cast<const CodePoint*>(str)), last_(it_ + len) {} - Opt<CodePoint> getNext() + std::optional<CodePoint> getNext() { if (it_ == last_) - return NoValue(); + return {}; return *it_++; } private: @@ -314,7 +313,7 @@ bool isValidUtf(const UtfString& str) using namespace impl; UtfDecoder<GetCharTypeT<UtfString>> decoder(strBegin(str), strLength(str)); - while (Opt<CodePoint> cp = decoder.getNext()) + while (std::optional<CodePoint> cp = decoder.getNext()) if (*cp == REPLACEMENT_CHAR) return false; @@ -344,7 +343,7 @@ UtfString getUnicodeSubstring(const UtfString& str, size_t uniPosFirst, size_t u return output; UtfDecoder<CharType> decoder(strBegin(str), strLength(str)); - for (size_t uniPos = 0; Opt<CodePoint> cp = decoder.getNext(); ++uniPos) //[!] declaration in condition part of the for-loop + for (size_t uniPos = 0; std::optional<CodePoint> cp = decoder.getNext(); ++uniPos) //[!] declaration in condition part of the for-loop if (uniPosFirst <= uniPos) { if (uniPos >= uniPosLast) @@ -368,7 +367,7 @@ TargetString utfTo(const SourceString& str, std::false_type) TargetString output; UtfDecoder<CharSrc> decoder(strBegin(str), strLength(str)); - while (Opt<CodePoint> cp = decoder.getNext()) + while (std::optional<CodePoint> cp = decoder.getNext()) codePointToUtf<CharTrg>(*cp, [&](CharTrg c) { output += c; }); return output; diff --git a/zen/zstring.cpp b/zen/zstring.cpp index 1fe31eaf..8bf77a0b 100755 --- a/zen/zstring.cpp +++ b/zen/zstring.cpp @@ -49,8 +49,8 @@ int compareNoCaseUtf8(const char* lhs, size_t lhsLen, const char* rhs, size_t rh impl::UtfDecoder<char> decR(rhs, rhsLen); for (;;) { - const Opt<impl::CodePoint> cpL = decL.getNext(); - const Opt<impl::CodePoint> cpR = decR.getNext(); + const std::optional<impl::CodePoint> cpL = decL.getNext(); + const std::optional<impl::CodePoint> cpR = decR.getNext(); if (!cpL || !cpR) return static_cast<int>(!cpR) - static_cast<int>(!cpL); diff --git a/zen/zstring.h b/zen/zstring.h index 3938cef1..7fa21335 100755 --- a/zen/zstring.h +++ b/zen/zstring.h @@ -95,7 +95,7 @@ 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" - +//const wchar_t NOBREAK_SPACE = L'\u00A0'; |