summaryrefslogtreecommitdiff
path: root/zen/string_tools.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:24:59 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:24:59 +0200
commita1c91f4695e208d5a8f80dc37b1818169b7829ff (patch)
tree52f5134376d17c99b6c9e53133a2eb5cf171377c /zen/string_tools.h
parent5.16 (diff)
downloadFreeFileSync-a1c91f4695e208d5a8f80dc37b1818169b7829ff.tar.gz
FreeFileSync-a1c91f4695e208d5a8f80dc37b1818169b7829ff.tar.bz2
FreeFileSync-a1c91f4695e208d5a8f80dc37b1818169b7829ff.zip
5.17
Diffstat (limited to 'zen/string_tools.h')
-rw-r--r--zen/string_tools.h60
1 files changed, 44 insertions, 16 deletions
diff --git a/zen/string_tools.h b/zen/string_tools.h
index 990c823a..4639e1dd 100644
--- a/zen/string_tools.h
+++ b/zen/string_tools.h
@@ -1,5 +1,5 @@
// **************************************************************************
-// * This file is part of the zenXML project. It is distributed under the *
+// * This file is part of the zen::Xml project. It is distributed under the *
// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt *
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
@@ -463,41 +463,69 @@ perf: integer to string: (executed 10 mio. times)
formatInteger - 778 ms
*/
-template <class S, class Num> inline
-S formatInteger(Num n, bool hasMinus)
+template <class OutputIterator, class Num> inline
+void formatNegativeInteger(Num n, OutputIterator& it)
{
- assert(n >= 0);
- typedef typename GetCharType<S>::Type CharType;
- CharType buffer[2 + sizeof(Num) * 5 / 2]; //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))) =~ 1 + ceil(sizeof(n) * 2.4082) < 2 + floor(sizeof(n) * 2.5)
-
- auto iter = std::end(buffer);
+ assert(n < 0);
+ typedef typename std::iterator_traits<OutputIterator>::value_type CharType;
do
{
const Num tmp = n / 10;
- *--iter = static_cast<CharType>('0' + (n - tmp * 10)); //8% faster than using modulus operator!
+ *--it = static_cast<CharType>('0' + (tmp * 10 - n)); //8% faster than using modulus operator!
n = tmp;
}
while (n != 0);
- if (hasMinus)
- *--iter = static_cast<CharType>('-');
+ *--it = static_cast<CharType>('-');
+}
- return S(&*iter, std::end(buffer) - iter);
+template <class OutputIterator, class Num> inline
+void formatPositiveInteger(Num n, OutputIterator& it)
+{
+ assert(n >= 0);
+ typedef typename std::iterator_traits<OutputIterator>::value_type CharType;
+ do
+ {
+ const Num tmp = n / 10;
+ *--it = static_cast<CharType>('0' + (n - tmp * 10)); //8% faster than using modulus operator!
+ n = tmp;
+ }
+ while (n != 0);
}
+
template <class S, class Num> inline
S numberTo(const Num& number, Int2Type<NUM_TYPE_SIGNED_INT>)
{
- return formatInteger<S>(number < 0 ? -number : number, number < 0);
- //bug for "INT_MIN"! technically -INT_MIN == INT_MIN -> not worth the trouble
+ typedef typename GetCharType<S>::Type CharType;
+ CharType buffer[2 + sizeof(Num) * 241 / 100]; //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)
+
+ //caveat: consider INT_MIN: technically -INT_MIN == INT_MIN
+ auto it = std::end(buffer);
+ if (number < 0)
+ formatNegativeInteger(number, it);
+ else
+ formatPositiveInteger(number, it);
+ assert(it >= std::begin(buffer));
+
+ return S(&*it, std::end(buffer) - it);
}
template <class S, class Num> inline
S numberTo(const Num& number, Int2Type<NUM_TYPE_UNSIGNED_INT>)
{
- return formatInteger<S>(number, false);
+ typedef typename GetCharType<S>::Type CharType;
+ CharType buffer[1 + sizeof(Num) * 241 / 100];
+ //required chars: ceil(ln_10(256^sizeof(n))) =~ ceil(sizeof(n) * 2.4082) <= 1 + floor(sizeof(n) * 2.41)
+
+ auto it = std::end(buffer);
+ formatPositiveInteger(number, it);
+ assert(it >= std::begin(buffer));
+
+ return S(&*it, std::end(buffer) - it);
}
//--------------------------------------------------------------------------------
bgstack15