From a98326eb2954ac1e79f5eac28dbeab3ec15e047f Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Sat, 30 Jun 2018 12:43:08 +0200 Subject: 10.1 --- zen/string_tools.h | 95 ++++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 50 deletions(-) (limited to 'zen/string_tools.h') diff --git a/zen/string_tools.h b/zen/string_tools.h index 7734b6f0..58cb6ea6 100755 --- a/zen/string_tools.h +++ b/zen/string_tools.h @@ -127,7 +127,7 @@ bool isWhiteSpace(wchar_t c) template inline bool isDigit(Char c) //similar to implmenetation of std::isdigit()! { - static_assert(IsSameType::value || IsSameType::value, ""); + static_assert(std::is_same_v || std::is_same_v); return static_cast('0') <= c && c <= static_cast('9'); } @@ -135,7 +135,7 @@ bool isDigit(Char c) //similar to implmenetation of std::isdigit()! template inline bool isHexDigit(Char c) { - static_assert(IsSameType::value || IsSameType::value, ""); + static_assert(std::is_same_v || std::is_same_v); return (static_cast('0') <= c && c <= static_cast('9')) || (static_cast('A') <= c && c <= static_cast('F')) || (static_cast('a') <= c && c <= static_cast('f')); @@ -145,7 +145,7 @@ bool isHexDigit(Char c) template inline bool isAsciiAlpha(Char c) { - static_assert(IsSameType::value || IsSameType::value, ""); + static_assert(std::is_same_v || std::is_same_v); return (static_cast('A') <= c && c <= static_cast('Z')) || (static_cast('a') <= c && c <= static_cast('z')); } @@ -209,7 +209,7 @@ template inline bool strEqual (const S& lhs, const T& rhs template inline bool contains(const S& str, const T& term) { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); + static_assert(std::is_same_v, GetCharTypeT>); const size_t strLen = strLength(str); const size_t termLen = strLength(term); if (strLen < termLen) @@ -227,7 +227,7 @@ bool contains(const S& str, const T& term) template inline S afterLast(const S& str, const T& term, FailureReturnVal rv) { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); + static_assert(std::is_same_v, GetCharTypeT>); const size_t termLen = strLength(term); assert(termLen > 0); @@ -248,7 +248,7 @@ S afterLast(const S& str, const T& term, FailureReturnVal rv) template inline S beforeLast(const S& str, const T& term, FailureReturnVal rv) { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); + static_assert(std::is_same_v, GetCharTypeT>); const size_t termLen = strLength(term); assert(termLen > 0); @@ -268,7 +268,7 @@ S beforeLast(const S& str, const T& term, FailureReturnVal rv) template inline S afterFirst(const S& str, const T& term, FailureReturnVal rv) { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); + static_assert(std::is_same_v, GetCharTypeT>); const size_t termLen = strLength(term); assert(termLen > 0); @@ -289,7 +289,7 @@ S afterFirst(const S& str, const T& term, FailureReturnVal rv) template inline S beforeFirst(const S& str, const T& term, FailureReturnVal rv) { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); + static_assert(std::is_same_v, GetCharTypeT>); const size_t termLen = strLength(term); assert(termLen > 0); @@ -309,7 +309,7 @@ S beforeFirst(const S& str, const T& term, FailureReturnVal rv) template inline std::vector split(const S& str, const T& delimiter, SplitType st) { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); + static_assert(std::is_same_v, GetCharTypeT>); const size_t delimLen = strLength(delimiter); assert(delimLen > 0); if (delimLen == 0) @@ -346,18 +346,18 @@ ZEN_INIT_DETECT_MEMBER(append); //either call operator+=(S(str, len)) or append(str, len) template inline -typename EnableIf::value>::Type stringAppend(S& str, InputIterator first, InputIterator last) { str.append(first, last); } +std::enable_if_t::value> stringAppend(S& str, InputIterator first, InputIterator last) { str.append(first, last); } template inline -typename EnableIf::value>::Type stringAppend(S& str, InputIterator first, InputIterator last) { str += S(first, last); } +std::enable_if_t::value> stringAppend(S& str, InputIterator first, InputIterator last) { str += S(first, last); } } template inline S replaceCpy(const S& str, const T& oldTerm, const U& newTerm, bool replaceAll) { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); + static_assert(std::is_same_v, GetCharTypeT>); + static_assert(std::is_same_v, GetCharTypeT>); const size_t oldLen = strLength(oldTerm); if (oldLen == 0) return str; @@ -427,7 +427,7 @@ void trim(S& str, bool fromLeft, bool fromRight, Function trimThisChar) template inline void trim(S& str, bool fromLeft, bool fromRight) { - using CharType = typename GetCharType::Type; + using CharType = GetCharTypeT; trim(str, fromLeft, fromRight, [](CharType c) { return isWhiteSpace(c); }); } @@ -509,11 +509,10 @@ int saferPrintf(wchar_t* buffer, size_t bufferSize, const wchar_t* format, const template inline S printNumber(const T& format, const Num& number) //format a single number using ::sprintf { - static_assert(IsSameType::Type, typename GetCharType::Type>::value, ""); - using CharType = typename GetCharType::Type; + static_assert(std::is_same_v, GetCharTypeT>); const int BUFFER_SIZE = 128; - CharType buffer[BUFFER_SIZE]; //zero-initialize? + GetCharTypeT buffer[BUFFER_SIZE]; //zero-initialize? const int charsWritten = impl::saferPrintf(buffer, BUFFER_SIZE, strBegin(format), number); return 0 < charsWritten && charsWritten < BUFFER_SIZE ? S(buffer, charsWritten) : S(); @@ -522,21 +521,19 @@ S printNumber(const T& format, const Num& number) //format a single number using namespace impl { -enum NumberType +enum class NumberType { - NUM_TYPE_SIGNED_INT, - NUM_TYPE_UNSIGNED_INT, - NUM_TYPE_FLOATING_POINT, - NUM_TYPE_OTHER, + SIGNED_INT, + UNSIGNED_INT, + FLOATING_POINT, + OTHER, }; template inline -S numberTo(const Num& number, Int2Type) //default number to string conversion using streams: convenient, but SLOW, SLOW, SLOW!!!! (~ factor of 20) +S numberTo(const Num& number, std::integral_constant) //default number to string conversion using streams: convenient, but SLOW, SLOW, SLOW!!!! (~ factor of 20) { - using CharType = typename GetCharType::Type; - - std::basic_ostringstream ss; + std::basic_ostringstream> ss; ss << number; return copyStringTo(ss.str()); } @@ -546,9 +543,9 @@ template inline S floatToString(const Num& number, char ) template inline S floatToString(const Num& number, wchar_t) { return printNumber(L"%g", static_cast(number)); } template inline -S numberTo(const Num& number, Int2Type) +S numberTo(const Num& number, std::integral_constant) { - return floatToString(number, typename GetCharType::Type()); + return floatToString(number, GetCharTypeT()); } @@ -591,10 +588,9 @@ void formatPositiveInteger(Num n, OutputIterator& it) template inline -S numberTo(const Num& number, Int2Type) +S numberTo(const Num& number, std::integral_constant) { - using CharType = typename GetCharType::Type; - CharType buffer[2 + sizeof(Num) * 241 / 100]; //zero-initialize? + GetCharTypeT buffer[2 + sizeof(Num) * 241 / 100]; //zero-initialize? //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) @@ -612,10 +608,9 @@ S numberTo(const Num& number, Int2Type) template inline -S numberTo(const Num& number, Int2Type) +S numberTo(const Num& number, std::integral_constant) { - using CharType = typename GetCharType::Type; - CharType buffer[1 + sizeof(Num) * 241 / 100]; //zero-initialize? + GetCharTypeT 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) auto it = std::end(buffer); @@ -628,9 +623,9 @@ S numberTo(const Num& number, Int2Type) //-------------------------------------------------------------------------------- template inline -Num stringTo(const S& str, Int2Type) //default string to number conversion using streams: convenient, but SLOW +Num stringTo(const S& str, std::integral_constant) //default string to number conversion using streams: convenient, but SLOW { - using CharType = typename GetCharType::Type; + using CharType = GetCharTypeT; Num number = 0; std::basic_istringstream(copyStringTo>(str)) >> number; return number; @@ -641,7 +636,7 @@ template inline Num stringToFloat(const char* str) { return std:: template inline Num stringToFloat(const wchar_t* str) { return std::wcstod(str, nullptr); } template inline -Num stringTo(const S& str, Int2Type) +Num stringTo(const S& str, std::integral_constant) { return stringToFloat(strBegin(str)); } @@ -649,7 +644,7 @@ Num stringTo(const S& str, Int2Type) template 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::Type; + using CharType = GetCharTypeT; const CharType* first = strBegin(str); const CharType* last = first + strLength(str); @@ -687,7 +682,7 @@ Num extractInteger(const S& str, bool& hasMinusSign) //very fast conversion to i template inline -Num stringTo(const S& str, Int2Type) +Num stringTo(const S& str, std::integral_constant) { bool hasMinusSign = false; //handle minus sign const Num number = extractInteger(str, hasMinusSign); @@ -696,7 +691,7 @@ Num stringTo(const S& str, Int2Type) template inline -Num stringTo(const S& str, Int2Type) //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic +Num stringTo(const S& str, std::integral_constant) //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic { bool hasMinusSign = false; //handle minus sign const Num number = extractInteger(str, hasMinusSign); @@ -713,11 +708,11 @@ Num stringTo(const S& str, Int2Type) //very fast conversi template inline S numberTo(const Num& number) { - using TypeTag = Int2Type< - IsSignedInt ::value ? impl::NUM_TYPE_SIGNED_INT : - IsUnsignedInt::value ? impl::NUM_TYPE_UNSIGNED_INT : - IsFloat ::value ? impl::NUM_TYPE_FLOATING_POINT : - impl::NUM_TYPE_OTHER>; + using TypeTag = std::integral_constant::value ? impl::NumberType::SIGNED_INT : + IsUnsignedInt::value ? impl::NumberType::UNSIGNED_INT : + IsFloat ::value ? impl::NumberType::FLOATING_POINT : + impl::NumberType::OTHER>; return impl::numberTo(number, TypeTag()); } @@ -726,11 +721,11 @@ S numberTo(const Num& number) template inline Num stringTo(const S& str) { - using TypeTag = Int2Type< - IsSignedInt ::value ? impl::NUM_TYPE_SIGNED_INT : - IsUnsignedInt::value ? impl::NUM_TYPE_UNSIGNED_INT : - IsFloat ::value ? impl::NUM_TYPE_FLOATING_POINT : - impl::NUM_TYPE_OTHER>; + using TypeTag = std::integral_constant::value ? impl::NumberType::SIGNED_INT : + IsUnsignedInt::value ? impl::NumberType::UNSIGNED_INT : + IsFloat ::value ? impl::NumberType::FLOATING_POINT : + impl::NumberType::OTHER>; return impl::stringTo(str, TypeTag()); } -- cgit