summaryrefslogtreecommitdiff
path: root/zen/string_tools.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2016-03-16 21:34:59 +0100
committerDaniel Wilhelm <daniel@wili.li>2016-03-16 21:34:59 +0100
commit339ed7f63798fb5ccab05fa7fb9d0d95743c9c89 (patch)
tree214819f601b69bfd32507ca59047dd4d68ed5632 /zen/string_tools.h
parent7.9 (diff)
downloadFreeFileSync-339ed7f63798fb5ccab05fa7fb9d0d95743c9c89.tar.gz
FreeFileSync-339ed7f63798fb5ccab05fa7fb9d0d95743c9c89.tar.bz2
FreeFileSync-339ed7f63798fb5ccab05fa7fb9d0d95743c9c89.zip
8.0
Diffstat (limited to 'zen/string_tools.h')
-rw-r--r--zen/string_tools.h41
1 files changed, 23 insertions, 18 deletions
diff --git a/zen/string_tools.h b/zen/string_tools.h
index fc9fe806..92ca1654 100644
--- a/zen/string_tools.h
+++ b/zen/string_tools.h
@@ -77,6 +77,7 @@ template <class T, class S> T copyStringTo(S&& str);
template <> inline
bool isWhiteSpace(char ch)
{
+ assert(ch != 0); //std C++ does not consider 0 as white space
//caveat 1: std::isspace() takes an int, but expects an unsigned char
//caveat 2: some parts of UTF-8 chars are erroneously seen as whitespace, e.g. the a0 from "\xec\x8b\xa0" (MSVC)
return static_cast<unsigned char>(ch) < 128 &&
@@ -84,7 +85,11 @@ bool isWhiteSpace(char ch)
}
template <> inline
-bool isWhiteSpace(wchar_t ch) { return std::iswspace(ch) != 0; }
+bool isWhiteSpace(wchar_t ch)
+{
+ assert(ch != 0); //std C++ does not consider 0 as white space
+ return std::iswspace(ch) != 0;
+}
template <class Char> inline
@@ -402,7 +407,7 @@ template <class S, class T, class Num> inline
S printNumber(const T& format, const Num& number) //format a single number using ::sprintf
{
static_assert(IsSameType<typename GetCharType<S>::Type, typename GetCharType<T>::Type>::value, "");
- using CharType = typename GetCharType<S>::Type;
+ using CharType = typename GetCharType<S>::Type;
const int BUFFER_SIZE = 128;
CharType buffer[BUFFER_SIZE]; //zero-initialize?
@@ -426,7 +431,7 @@ enum NumberType
template <class S, class Num> inline
S numberTo(const Num& number, Int2Type<NUM_TYPE_OTHER>) //default number to string conversion using streams: convenient, but SLOW, SLOW, SLOW!!!! (~ factor of 20)
{
- using CharType = typename GetCharType<S>::Type;
+ using CharType = typename GetCharType<S>::Type;
std::basic_ostringstream<CharType> ss;
ss << number;
@@ -455,7 +460,7 @@ template <class OutputIterator, class Num> inline
void formatNegativeInteger(Num n, OutputIterator& it)
{
assert(n < 0);
- using CharType = typename std::iterator_traits<OutputIterator>::value_type;
+ using CharType = typename std::iterator_traits<OutputIterator>::value_type;
do
{
const Num tmp = n / 10;
@@ -471,7 +476,7 @@ template <class OutputIterator, class Num> inline
void formatPositiveInteger(Num n, OutputIterator& it)
{
assert(n >= 0);
- using CharType = typename std::iterator_traits<OutputIterator>::value_type;
+ using CharType = typename std::iterator_traits<OutputIterator>::value_type;
do
{
const Num tmp = n / 10;
@@ -487,7 +492,7 @@ S numberTo(const Num& number, Int2Type<NUM_TYPE_SIGNED_INT>)
{
using CharType = typename GetCharType<S>::Type;
CharType buffer[2 + sizeof(Num) * 241 / 100]; //zero-initialize?
- //it's generally faster to use a buffer than to rely on String::operator+=() (in)efficiency
+ //it's generally faster to use a buffer than to rely on String::operator+=() (in)efficiency
//required chars (+ sign char): 1 + ceil(ln_10(256^sizeof(n) / 2 + 1)) -> divide by 2 for signed half-range; second +1 since one half starts with 1!
// <= 1 + ceil(ln_10(256^sizeof(n))) =~ 1 + ceil(sizeof(n) * 2.4082) <= 2 + floor(sizeof(n) * 2.41)
@@ -506,7 +511,7 @@ S numberTo(const Num& number, Int2Type<NUM_TYPE_SIGNED_INT>)
template <class S, class Num> inline
S numberTo(const Num& number, Int2Type<NUM_TYPE_UNSIGNED_INT>)
{
- using CharType = typename GetCharType<S>::Type;
+ using CharType = typename GetCharType<S>::Type;
CharType buffer[1 + sizeof(Num) * 241 / 100]; //zero-initialize?
//required chars: ceil(ln_10(256^sizeof(n))) =~ ceil(sizeof(n) * 2.4082) <= 1 + floor(sizeof(n) * 2.41)
@@ -522,7 +527,7 @@ S numberTo(const Num& number, Int2Type<NUM_TYPE_UNSIGNED_INT>)
template <class Num, class S> inline
Num stringTo(const S& str, Int2Type<NUM_TYPE_OTHER>) //default string to number conversion using streams: convenient, but SLOW
{
- using CharType = typename GetCharType<S>::Type;
+ using CharType = typename GetCharType<S>::Type;
Num number = 0;
std::basic_istringstream<CharType>(copyStringTo<std::basic_string<CharType>>(str)) >> number;
return number;
@@ -541,8 +546,8 @@ Num stringTo(const S& str, Int2Type<NUM_TYPE_FLOATING_POINT>)
template <class Num, class S>
Num extractInteger(const S& str, bool& hasMinusSign) //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic
{
- using CharType = typename GetCharType<S>::Type;
-
+ using CharType = typename GetCharType<S>::Type;
+
const CharType* first = strBegin(str);
const CharType* last = first + strLength(str);
@@ -610,10 +615,10 @@ template <class S, class Num> inline
S numberTo(const Num& number)
{
using TypeTag = Int2Type<
- IsSignedInt <Num>::value ? impl::NUM_TYPE_SIGNED_INT :
- IsUnsignedInt<Num>::value ? impl::NUM_TYPE_UNSIGNED_INT :
- IsFloat <Num>::value ? impl::NUM_TYPE_FLOATING_POINT :
- impl::NUM_TYPE_OTHER>;
+ IsSignedInt <Num>::value ? impl::NUM_TYPE_SIGNED_INT :
+ IsUnsignedInt<Num>::value ? impl::NUM_TYPE_UNSIGNED_INT :
+ IsFloat <Num>::value ? impl::NUM_TYPE_FLOATING_POINT :
+ impl::NUM_TYPE_OTHER>;
return impl::numberTo<S>(number, TypeTag());
}
@@ -623,10 +628,10 @@ template <class Num, class S> inline
Num stringTo(const S& str)
{
using TypeTag = Int2Type<
- IsSignedInt <Num>::value ? impl::NUM_TYPE_SIGNED_INT :
- IsUnsignedInt<Num>::value ? impl::NUM_TYPE_UNSIGNED_INT :
- IsFloat <Num>::value ? impl::NUM_TYPE_FLOATING_POINT :
- impl::NUM_TYPE_OTHER>;
+ IsSignedInt <Num>::value ? impl::NUM_TYPE_SIGNED_INT :
+ IsUnsignedInt<Num>::value ? impl::NUM_TYPE_UNSIGNED_INT :
+ IsFloat <Num>::value ? impl::NUM_TYPE_FLOATING_POINT :
+ impl::NUM_TYPE_OTHER>;
return impl::stringTo<Num>(str, TypeTag());
}
bgstack15