diff options
author | Russell Brenner <russellbrenner@google.com> | 2010-11-18 17:33:13 -0800 |
---|---|---|
committer | Russell Brenner <russellbrenner@google.com> | 2010-12-02 13:47:21 -0800 |
commit | 6b70adc33054f8aee8c54d0f460458a9df11b8a5 (patch) | |
tree | 103a13998c33944d6ab3b8318c509a037e639460 /JavaScriptCore/wtf/text | |
parent | bdf4ebc8e70b2d221b6ee7a65660918ecb1d33aa (diff) | |
download | external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.zip external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.gz external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.bz2 |
Merge WebKit at r72274: Initial merge by git.
Change-Id: Ie51f0b4a16da82942bd516dce59cfb79ebbe25fb
Diffstat (limited to 'JavaScriptCore/wtf/text')
-rw-r--r-- | JavaScriptCore/wtf/text/CString.cpp | 25 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/StringImpl.cpp | 81 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/TextPosition.h | 141 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/WTFString.cpp | 44 |
4 files changed, 232 insertions, 59 deletions
diff --git a/JavaScriptCore/wtf/text/CString.cpp b/JavaScriptCore/wtf/text/CString.cpp index c048a1b..db6443f 100644 --- a/JavaScriptCore/wtf/text/CString.cpp +++ b/JavaScriptCore/wtf/text/CString.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,12 +27,15 @@ #include "config.h" #include "CString.h" -using std::min; +using namespace std; namespace WTF { CString::CString(const char* str) { + if (!str) + return; + init(str, strlen(str)); } @@ -45,7 +48,10 @@ void CString::init(const char* str, size_t length) { if (!str) return; - + + if (length >= numeric_limits<size_t>::max()) + CRASH(); + m_buffer = CStringBuffer::create(length + 1); memcpy(m_buffer->mutableData(), str, length); m_buffer->mutableData()[length] = '\0'; @@ -61,6 +67,9 @@ char* CString::mutableData() CString CString::newUninitialized(size_t length, char*& characterBuffer) { + if (length >= numeric_limits<size_t>::max()) + CRASH(); + CString result; result.m_buffer = CStringBuffer::create(length + 1); char* bytes = result.m_buffer->mutableData(); @@ -73,11 +82,11 @@ void CString::copyBufferIfNeeded() { if (!m_buffer || m_buffer->hasOneRef()) return; - - int len = m_buffer->length(); - RefPtr<CStringBuffer> m_temp = m_buffer; - m_buffer = CStringBuffer::create(len); - memcpy(m_buffer->mutableData(), m_temp->data(), len); + + RefPtr<CStringBuffer> buffer = m_buffer.release(); + size_t length = buffer->length(); + m_buffer = CStringBuffer::create(length); + memcpy(m_buffer->mutableData(), buffer->data(), length); } bool operator==(const CString& a, const CString& b) diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp index f4b2f05..1c4de66 100644 --- a/JavaScriptCore/wtf/text/StringImpl.cpp +++ b/JavaScriptCore/wtf/text/StringImpl.cpp @@ -96,9 +96,9 @@ PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned leng return empty(); UChar* data; - PassRefPtr<StringImpl> string = createUninitialized(length, data); + RefPtr<StringImpl> string = createUninitialized(length, data); memcpy(data, characters, length * sizeof(UChar)); - return string; + return string.release(); } PassRefPtr<StringImpl> StringImpl::create(const char* characters, unsigned length) @@ -107,19 +107,22 @@ PassRefPtr<StringImpl> StringImpl::create(const char* characters, unsigned lengt return empty(); UChar* data; - PassRefPtr<StringImpl> string = createUninitialized(length, data); + RefPtr<StringImpl> string = createUninitialized(length, data); for (unsigned i = 0; i != length; ++i) { unsigned char c = characters[i]; data[i] = c; } - return string; + return string.release(); } PassRefPtr<StringImpl> StringImpl::create(const char* string) { if (!string) return empty(); - return create(string, strlen(string)); + size_t length = strlen(string); + if (length > numeric_limits<unsigned>::max()) + CRASH(); + return create(string, length); } PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) @@ -205,7 +208,10 @@ PassRefPtr<StringImpl> StringImpl::lower() if (noUpper && !(ored & ~0x7F)) return this; + if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) + CRASH(); int32_t length = m_length; + UChar* data; RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); @@ -236,7 +242,10 @@ PassRefPtr<StringImpl> StringImpl::upper() // but in empirical testing, few actual calls to upper() are no-ops, so // it wouldn't be worth the extra time for pre-scanning. UChar* data; - PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data); + RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); + + if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) + CRASH(); int32_t length = m_length; // Do a faster loop for the case where all the characters are ASCII. @@ -247,7 +256,7 @@ PassRefPtr<StringImpl> StringImpl::upper() data[i] = toASCIIUpper(c); } if (!(ored & ~0x7F)) - return newImpl; + return newImpl.release(); // Do a slower implementation for cases that include non-ASCII characters. bool error; @@ -258,45 +267,47 @@ PassRefPtr<StringImpl> StringImpl::upper() Unicode::toUpper(data, realLength, m_data, m_length, &error); if (error) return this; - return newImpl; + return newImpl.release(); } -PassRefPtr<StringImpl> StringImpl::secure(UChar aChar) +PassRefPtr<StringImpl> StringImpl::secure(UChar character) { UChar* data; - PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data); - int32_t length = m_length; - for (int i = 0; i < length; ++i) - data[i] = aChar; - return newImpl; + RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); + for (unsigned i = 0; i < m_length; ++i) + data[i] = character; + return newImpl.release(); } PassRefPtr<StringImpl> StringImpl::foldCase() { UChar* data; - PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data); + RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); + + if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) + CRASH(); int32_t length = m_length; // Do a faster loop for the case where all the characters are ASCII. UChar ored = 0; - for (int i = 0; i < length; i++) { + for (int32_t i = 0; i < length; i++) { UChar c = m_data[i]; ored |= c; data[i] = toASCIILower(c); } if (!(ored & ~0x7F)) - return newImpl; + return newImpl.release(); // Do a slower implementation for cases that include non-ASCII characters. bool error; int32_t realLength = Unicode::foldCase(data, length, m_data, m_length, &error); if (!error && realLength == length) - return newImpl; + return newImpl.release(); newImpl = createUninitialized(realLength, data); Unicode::foldCase(data, realLength, m_data, m_length, &error); if (error) return this; - return newImpl; + return newImpl.release(); } PassRefPtr<StringImpl> StringImpl::stripWhiteSpace() @@ -517,7 +528,10 @@ size_t StringImpl::find(const char* matchString, unsigned index) // Check for null or empty string to match against if (!matchString) return notFound; - unsigned matchLength = strlen(matchString); + size_t matchStringLength = strlen(matchString); + if (matchStringLength > numeric_limits<unsigned>::max()) + CRASH(); + unsigned matchLength = matchStringLength; if (!matchLength) return min(index, length()); @@ -563,7 +577,10 @@ size_t StringImpl::findIgnoringCase(const char* matchString, unsigned index) // Check for null or empty string to match against if (!matchString) return notFound; - unsigned matchLength = strlen(matchString); + size_t matchStringLength = strlen(matchString); + if (matchStringLength > numeric_limits<unsigned>::max()) + CRASH(); + unsigned matchLength = matchStringLength; if (!matchLength) return min(index, length()); @@ -761,7 +778,7 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) return this; UChar* data; - PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data); + RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); for (i = 0; i != m_length; ++i) { UChar ch = m_data[i]; @@ -769,7 +786,7 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) ch = newC; data[i] = ch; } - return newImpl; + return newImpl.release(); } PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, StringImpl* str) @@ -784,14 +801,14 @@ PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToR if ((length() - lengthToReplace) >= (numeric_limits<unsigned>::max() - lengthToInsert)) CRASH(); - PassRefPtr<StringImpl> newImpl = + RefPtr<StringImpl> newImpl = createUninitialized(length() - lengthToReplace + lengthToInsert, data); memcpy(data, characters(), position * sizeof(UChar)); if (str) memcpy(data + position, str->characters(), lengthToInsert * sizeof(UChar)); memcpy(data + position + lengthToInsert, characters() + position + lengthToReplace, (length() - position - lengthToReplace) * sizeof(UChar)); - return newImpl; + return newImpl.release(); } PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacement) @@ -824,7 +841,7 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen newSize += replaceSize; UChar* data; - PassRefPtr<StringImpl> newImpl = createUninitialized(newSize, data); + RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); // Construct the new data size_t srcSegmentEnd; @@ -846,7 +863,7 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen ASSERT(dstOffset + srcSegmentLength == newImpl->length()); - return newImpl; + return newImpl.release(); } PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* replacement) @@ -882,7 +899,7 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl newSize += matchCount * repStrLength; UChar* data; - PassRefPtr<StringImpl> newImpl = createUninitialized(newSize, data); + RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); // Construct the new data size_t srcSegmentEnd; @@ -904,7 +921,7 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl ASSERT(dstOffset + srcSegmentLength == newImpl->length()); - return newImpl; + return newImpl.release(); } bool equal(const StringImpl* a, const StringImpl* b) @@ -1020,9 +1037,11 @@ PassRefPtr<StringImpl> StringImpl::adopt(StringBuffer& buffer) PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string) { // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer - // get allocated in a single malloc block. + // get allocated in a single memory block. UChar* data; - int length = string.m_length; + unsigned length = string.m_length; + if (length >= numeric_limits<unsigned>::max()) + CRASH(); RefPtr<StringImpl> terminatedString = createUninitialized(length + 1, data); memcpy(data, string.m_data, length * sizeof(UChar)); data[length] = 0; diff --git a/JavaScriptCore/wtf/text/TextPosition.h b/JavaScriptCore/wtf/text/TextPosition.h new file mode 100644 index 0000000..63dc594 --- /dev/null +++ b/JavaScriptCore/wtf/text/TextPosition.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TextPosition_h +#define TextPosition_h + +#include <wtf/Assertions.h> + +namespace WTF { + +/* + * Text Position + * + * TextPosition structure specifies coordinates within an text resource. It is used mostly + * for saving script source position. + * + * Later TextPosition0 and TextPosition1 and both number types can be merged together quite easily. + * + * 0-based and 1-based + * + * Line and column numbers could be interpreted as zero-based or 1-based. Since + * both practices coexist in WebKit source base, 'int' type should be replaced with + * a dedicated wrapper types, so that compiler helped us with this ambiguity. + * + * Here we introduce 2 types of numbers: ZeroBasedNumber and OneBasedNumber and + * 2 corresponding types of TextPosition structure. While only one type ought to be enough, + * this is done to keep transition to the new types as transparent as possible: + * e.g. in areas where 0-based integers are used, TextPosition0 should be introduced. This + * way all changes will remain trackable. + * + * Later both number types can be merged in one type quite easily. + * + * For type safety and for the future type merge it is important that all operations in API + * that accept or return integer have a name explicitly defining base of integer. For this reason + * int-receiving constructors are hidden from API. + */ + +template<typename NUMBER> +class TextPosition { +public: + TextPosition(NUMBER line, NUMBER column) + : m_line(line) + , m_column(column) + { + } + TextPosition() {} + + // A 'minimum' value of position, used as a default value. + static TextPosition<NUMBER> minimumPosition() { return TextPosition<NUMBER>(NUMBER::base(), NUMBER::base()); } + + // A value with line value less than a minimum; used as an impossible position. + static TextPosition<NUMBER> belowRangePosition() { return TextPosition<NUMBER>(NUMBER::belowBase(), NUMBER::base()); } + + NUMBER m_line; + NUMBER m_column; +}; + +class OneBasedNumber; + +// An int wrapper that always reminds you that the number should be 0-based +class ZeroBasedNumber { +public: + static ZeroBasedNumber fromZeroBasedInt(int zeroBasedInt) { return ZeroBasedNumber(zeroBasedInt); } + + ZeroBasedNumber() {} + + int zeroBasedInt() const { return m_value; } + + OneBasedNumber convertToOneBased() const; + + static ZeroBasedNumber base() { return 0; } + static ZeroBasedNumber belowBase() { return -1; } + +private: + ZeroBasedNumber(int value) : m_value(value) {} + int m_value; +}; + +// An int wrapper that always reminds you that the number should be 1-based +class OneBasedNumber { +public: + static OneBasedNumber fromOneBasedInt(int oneBasedInt) { return OneBasedNumber(oneBasedInt); } + OneBasedNumber() {} + + int oneBasedInt() const { return m_value; } + int convertAsZeroBasedInt() const { return m_value - 1; } + ZeroBasedNumber convertToZeroBased() const { return ZeroBasedNumber::fromZeroBasedInt(m_value - 1); } + + static OneBasedNumber base() { return 1; } + static OneBasedNumber belowBase() { return 0; } + +private: + OneBasedNumber(int value) : m_value(value) {} + int m_value; +}; + +typedef TextPosition<ZeroBasedNumber> TextPosition0; +typedef TextPosition<OneBasedNumber> TextPosition1; + +inline TextPosition0 toZeroBasedTextPosition(const TextPosition1& position) +{ + return TextPosition0(position.m_line.convertToZeroBased(), position.m_column.convertToZeroBased()); +} + +inline TextPosition1 toOneBasedTextPosition(const TextPosition0& position) +{ + return TextPosition1(position.m_line.convertToOneBased(), position.m_column.convertToOneBased()); +} + +inline OneBasedNumber ZeroBasedNumber::convertToOneBased() const +{ + return OneBasedNumber::fromOneBasedInt(m_value + 1); +} + +} + +using WTF::TextPosition0; +using WTF::TextPosition1; + +#endif // TextPosition_h diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp index 5161477..6bb74f6 100644 --- a/JavaScriptCore/wtf/text/WTFString.cpp +++ b/JavaScriptCore/wtf/text/WTFString.cpp @@ -1,6 +1,6 @@ /* * (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. * Copyright (C) 2007-2009 Torch Mobile, Inc. * * This library is free software; you can redistribute it and/or @@ -22,7 +22,6 @@ #include "config.h" #include "WTFString.h" -#include <limits> #include <stdarg.h> #include <wtf/ASCIICType.h> #include <wtf/text/CString.h> @@ -32,9 +31,12 @@ #include <wtf/unicode/UTF8.h> #include <wtf/unicode/Unicode.h> +using namespace std; + namespace WTF { using namespace Unicode; +using namespace std; // Construct a string with UTF-16 data. String::String(const UChar* characters, unsigned length) @@ -52,7 +54,7 @@ String::String(const UChar* str) while (str[len] != UChar(0)) len++; - if (len > std::numeric_limits<unsigned>::max()) + if (len > numeric_limits<unsigned>::max()) CRASH(); m_impl = StringImpl::create(str, len); @@ -82,8 +84,9 @@ void String::append(const String& str) if (str.m_impl) { if (m_impl) { UChar* data; - RefPtr<StringImpl> newImpl = - StringImpl::createUninitialized(m_impl->length() + str.length(), data); + if (str.length() > numeric_limits<unsigned>::max() - m_impl->length()) + CRASH(); + RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + str.length(), data); memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar)); memcpy(data + m_impl->length(), str.characters(), str.length() * sizeof(UChar)); m_impl = newImpl.release(); @@ -100,8 +103,9 @@ void String::append(char c) // call to fastMalloc every single time. if (m_impl) { UChar* data; - RefPtr<StringImpl> newImpl = - StringImpl::createUninitialized(m_impl->length() + 1, data); + if (m_impl->length() >= numeric_limits<unsigned>::max()) + CRASH(); + RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + 1, data); memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar)); data[m_impl->length()] = c; m_impl = newImpl.release(); @@ -117,8 +121,9 @@ void String::append(UChar c) // call to fastMalloc every single time. if (m_impl) { UChar* data; - RefPtr<StringImpl> newImpl = - StringImpl::createUninitialized(m_impl->length() + 1, data); + if (m_impl->length() >= numeric_limits<unsigned>::max()) + CRASH(); + RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + 1, data); memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar)); data[m_impl->length()] = c; m_impl = newImpl.release(); @@ -178,10 +183,9 @@ void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) ASSERT(charactersToAppend); UChar* data; - if (lengthToAppend > std::numeric_limits<unsigned>::max() - length()) + if (lengthToAppend > numeric_limits<unsigned>::max() - length()) CRASH(); - RefPtr<StringImpl> newImpl = - StringImpl::createUninitialized(length() + lengthToAppend, data); + RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToAppend, data); memcpy(data, characters(), length() * sizeof(UChar)); memcpy(data + length(), charactersToAppend, lengthToAppend * sizeof(UChar)); m_impl = newImpl.release(); @@ -201,10 +205,9 @@ void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, un ASSERT(charactersToInsert); UChar* data; - if (lengthToInsert > std::numeric_limits<unsigned>::max() - length()) + if (lengthToInsert > numeric_limits<unsigned>::max() - length()) CRASH(); - RefPtr<StringImpl> newImpl = - StringImpl::createUninitialized(length() + lengthToInsert, data); + RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToInsert, data); memcpy(data, characters(), position * sizeof(UChar)); memcpy(data + position, charactersToInsert, lengthToInsert * sizeof(UChar)); memcpy(data + position + lengthToInsert, characters() + position, (length() - position) * sizeof(UChar)); @@ -237,8 +240,7 @@ void String::remove(unsigned position, int lengthToRemove) if (static_cast<unsigned>(lengthToRemove) > length() - position) lengthToRemove = length() - position; UChar* data; - RefPtr<StringImpl> newImpl = - StringImpl::createUninitialized(length() - lengthToRemove, data); + RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() - lengthToRemove, data); memcpy(data, characters(), position * sizeof(UChar)); memcpy(data + position, characters() + position + lengthToRemove, (length() - lengthToRemove - position) * sizeof(UChar)); @@ -695,6 +697,8 @@ CString String::utf8(bool strict) const // * We could allocate a CStringBuffer with an appropriate size to // have a good chance of being able to write the string into the // buffer without reallocing (say, 1.5 x length). + if (length > numeric_limits<unsigned>::max() / 3) + return CString(); Vector<char, 1024> bufferVector(length * 3); char* buffer = bufferVector.data(); @@ -725,7 +729,7 @@ CString String::utf8(bool strict) const String String::fromUTF8(const char* stringStart, size_t length) { - if (length > std::numeric_limits<unsigned>::max()) + if (length > numeric_limits<unsigned>::max()) CRASH(); if (!stringStart) @@ -787,8 +791,8 @@ static bool isCharacterAllowedInBase(UChar c, int base) template <typename IntegralType> static inline IntegralType toIntegralType(const UChar* data, size_t length, bool* ok, int base) { - static const IntegralType integralMax = std::numeric_limits<IntegralType>::max(); - static const bool isSigned = std::numeric_limits<IntegralType>::is_signed; + static const IntegralType integralMax = numeric_limits<IntegralType>::max(); + static const bool isSigned = numeric_limits<IntegralType>::is_signed; const IntegralType maxMultiplier = integralMax / base; IntegralType value = 0; |