fixed: Big::operator>> didn't correctly recognize values in scientific mode (with 'e' character)

added:   wide characters can be used simultaneously with ascii characters
         now we have two kind of methods: one for ascii characters and the other for wide characters
         e.g.
           void UInt::ToString(std::string & result)
           void UInt::ToString(std::wstring & result)
         previous was only one:
           void UInt::ToString(tt_string & result)
         and the 'tt_string' was a typedef to either std::string or std::wstring
         and it was a little misleading to a user (he has to know what the tt_string is)
added:   file: ttmathmisc.h some useful functions
changed: classes: ExceptionInfo, ReferenceError and RuntimeError are used only with ascii characters
removed: macros: TTMATH_USE_WCHAR,  TTMATH_TEXT()
removed: typedefs: tt_char, tt_string, tt_ostringstream, tt_ostream, tt_istream


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@193 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-09-13 19:16:42 +00:00
parent 9ccacd8817
commit da730d1c70
8 changed files with 1140 additions and 392 deletions

View File

@ -1,15 +1,7 @@
Version 0.9.0 prerelease (2009.09.11):
* added: support for wide characters (wchar_t)
wide characters are used when macro TTMATH_USE_WCHAR is defined
this macro is defined automatically when there is macro UNICODE or _UNICODE defined
some types have been changed
char -> tt_char
std::string -> tt_string
std::ostringstream -> tt_ostringstream
std::ostream -> tt_ostream
std::istream -> tt_istream
normally tt_char is equal char but when you are using wide characters then tt_char will be wchar_t (and so on)
(all typedef's are in ttmathtypes.h)
Version 0.9.0 prerelease (2009.09.13):
* fixed: Big::operator>>(std::istream&, Big<> &) didn't recognize values
in scientific mode (with 'e' character)
* added: support for wide characters (wchar_t, std::wstring)
* added: Big::IsInteger()
returns true if the value is integer (without fraction)
(NaN flag is not checked)

View File

@ -320,7 +320,7 @@ private:
// 3101 digits were taken from this website
// (later the digits were compared with:
// http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
// and they were set into Big<1,400> type (using operator=(const tt_char*) on a 32bit platform)
// and they were set into Big<1,400> type (using operator=(const char*) on a 32bit platform)
// and then the first 256 words were taken into this table
// (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
// and on 64bit platform value 128 (256/2=128))
@ -2799,6 +2799,7 @@ public:
}
/*!
a method for converting the value into a string with a base equal 'base'
@ -2837,27 +2838,59 @@ public:
1 - if there was a carry (shoudn't be in a normal situation - if is that means there
is somewhere an error in the library)
*/
uint ToString( tt_string & result,
uint ToString( std::string & result,
uint base = 10,
bool always_scientific = false,
sint when_scientific = 15,
sint max_digit_after_comma = -1,
bool remove_trailing_zeroes = true,
tt_char decimal_point = TTMATH_COMMA_CHARACTER_1 ) const
char decimal_point = TTMATH_COMMA_CHARACTER_1 ) const
{
static tt_char error_overflow_msg[] = TTMATH_TEXT("overflow");
static tt_char error_nan_msg[] = TTMATH_TEXT("NaN");
return ToStringBase(result, base, always_scientific, when_scientific,
max_digit_after_comma, remove_trailing_zeroes, decimal_point);
}
/*!
a method for converting the value into a string with a base equal 'base'
*/
uint ToString( std::wstring & result,
uint base = 10,
bool always_scientific = false,
sint when_scientific = 15,
sint max_digit_after_comma = -1,
bool remove_trailing_zeroes = true,
wchar_t decimal_point = TTMATH_COMMA_CHARACTER_1 ) const
{
return ToStringBase(result, base, always_scientific, when_scientific,
max_digit_after_comma, remove_trailing_zeroes, decimal_point);
}
private:
template<class string_type, class char_type>
uint ToStringBase( string_type & result,
uint base,
bool always_scientific,
sint when_scientific,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
char_type decimal_point) const
{
static char error_overflow_msg[] = "overflow";
static char error_nan_msg[] = "NaN";
result.erase();
if( IsNan() )
{
result = error_nan_msg;
Misc::AssignString(result, error_nan_msg);
return 0;
}
if( base<2 || base>16 )
{
result = error_overflow_msg;
Misc::AssignString(result, error_overflow_msg);
return 1;
}
@ -2887,7 +2920,7 @@ public:
if( ToString_CreateNewMantissaAndExponent(result, base, new_exp) )
{
result = error_overflow_msg;
Misc::AssignString(result, error_overflow_msg);
return 1;
}
@ -2898,7 +2931,7 @@ public:
if( base!=2 && base!=4 && base!=8 && base!=16 )
if( ToString_RoundMantissa(result, base, new_exp, decimal_point) )
{
result = error_overflow_msg;
Misc::AssignString(result, error_overflow_msg);
return 1;
}
@ -2906,7 +2939,7 @@ public:
when_scientific, max_digit_after_comma,
remove_trailing_zeroes, decimal_point ) )
{
result = error_overflow_msg;
Misc::AssignString(result, error_overflow_msg);
return 1;
}
@ -2988,7 +3021,8 @@ private:
but we need 'new'exp' as integer then we take:
new_exp = [log base (2^exponent)] + 1 <- where [x] means integer value from x
*/
uint ToString_CreateNewMantissaAndExponent( tt_string & new_man, uint base,
template<class string_type>
uint ToString_CreateNewMantissaAndExponent( string_type & new_man, uint base,
Int<exp+1> & new_exp) const
{
uint c = 0;
@ -3233,7 +3267,8 @@ private:
(we can make that speciality when the base is 4,8 or 16 as well
but maybe in further time)
*/
uint ToString_CreateNewMantissaAndExponent_Base2( tt_string & new_man,
template<class string_type>
uint ToString_CreateNewMantissaAndExponent_Base2( string_type & new_man,
Int<exp+1> & new_exp ) const
{
for( sint i=man-1 ; i>=0 ; --i )
@ -3263,13 +3298,14 @@ private:
this method roundes the last character from the new mantissa
(it's used in systems where the base is different from 2)
*/
uint ToString_RoundMantissa(tt_string & new_man, uint base, Int<exp+1> & new_exp, tt_char decimal_point) const
template<class string_type, class char_type>
uint ToString_RoundMantissa(string_type & new_man, uint base, Int<exp+1> & new_exp, char_type decimal_point) const
{
// we must have minimum two characters
if( new_man.length() < 2 )
return 0;
tt_string::size_type i = new_man.length() - 1;
typename string_type::size_type i = new_man.length() - 1;
// we're erasing the last character
uint digit = UInt<man>::CharToDigit( new_man[i] );
@ -3290,7 +3326,8 @@ private:
this method addes one into the new mantissa
*/
void ToString_RoundMantissa_AddOneIntoMantissa(tt_string & new_man, uint base, tt_char decimal_point) const
template<class string_type, class char_type>
void ToString_RoundMantissa_AddOneIntoMantissa(string_type & new_man, uint base, char_type decimal_point) const
{
if( new_man.empty() )
return;
@ -3314,7 +3351,7 @@ private:
else
was_carry = false;
new_man[i] = static_cast<tt_char>( UInt<man>::DigitToChar(digit) );
new_man[i] = static_cast<char_type>( UInt<man>::DigitToChar(digit) );
}
if( i<0 && was_carry )
@ -3328,13 +3365,14 @@ private:
this method sets the comma operator and/or puts the exponent
into the string
*/
uint ToString_SetCommaAndExponent( tt_string & new_man, uint base,
template<class string_type, class char_type>
uint ToString_SetCommaAndExponent( string_type & new_man, uint base,
Int<exp+1> & new_exp,
bool always_scientific,
sint when_scientific,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
tt_char decimal_point) const
char_type decimal_point) const
{
uint carry = 0;
@ -3373,13 +3411,14 @@ private:
/*!
an auxiliary method for converting into the string
*/
template<class string_type, class char_type>
void ToString_SetCommaAndExponent_Normal(
tt_string & new_man,
string_type & new_man,
uint base,
Int<exp+1> & new_exp,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
tt_char decimal_point) const
char_type decimal_point) const
{
if( !new_exp.IsSign() ) //if( new_exp >= 0 )
return ToString_SetCommaAndExponent_Normal_AddingZero(new_man, new_exp);
@ -3391,7 +3430,8 @@ private:
/*!
an auxiliary method for converting into the string
*/
void ToString_SetCommaAndExponent_Normal_AddingZero(tt_string & new_man,
template<class string_type>
void ToString_SetCommaAndExponent_Normal_AddingZero(string_type & new_man,
Int<exp+1> & new_exp) const
{
// we're adding zero characters at the end
@ -3410,13 +3450,14 @@ private:
/*!
an auxiliary method for converting into the string
*/
template<class string_type, class char_type>
void ToString_SetCommaAndExponent_Normal_SetCommaInside(
tt_string & new_man,
string_type & new_man,
uint base,
Int<exp+1> & new_exp,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
tt_char decimal_point) const
char_type decimal_point) const
{
// new_exp is < 0
@ -3435,7 +3476,7 @@ private:
// we're adding zero characters before the mantissa
uint how_many = e - new_man_len;
tt_string man_temp(how_many+1, '0');
string_type man_temp(how_many+1, '0');
man_temp.insert( man_temp.begin()+1, decimal_point);
new_man.insert(0, man_temp);
@ -3448,12 +3489,13 @@ private:
/*!
an auxiliary method for converting into the string
*/
void ToString_SetCommaAndExponent_Scientific( tt_string & new_man,
template<class string_type, class char_type>
void ToString_SetCommaAndExponent_Scientific( string_type & new_man,
uint base,
Int<exp+1> & scientific_exp,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
tt_char decimal_point) const
char_type decimal_point) const
{
if( new_man.empty() )
return;
@ -3473,10 +3515,10 @@ private:
{
// the 10 here is meant as the base 'base'
// (no matter which 'base' we're using there'll always be 10 here)
new_man += TTMATH_TEXT("*10^");
Misc::AddString(new_man, "*10^");
}
tt_string temp_exp;
string_type temp_exp;
scientific_exp.ToString( temp_exp, base );
new_man += temp_exp;
@ -3486,11 +3528,12 @@ private:
/*!
an auxiliary method for converting into the string
*/
void ToString_CorrectDigitsAfterComma( tt_string & new_man,
template<class string_type, class char_type>
void ToString_CorrectDigitsAfterComma( string_type & new_man,
uint base,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
tt_char decimal_point) const
char_type decimal_point) const
{
if( max_digit_after_comma >= 0 )
ToString_CorrectDigitsAfterComma_Round(new_man, base, max_digit_after_comma, decimal_point);
@ -3503,9 +3546,10 @@ private:
/*!
an auxiliary method for converting into the string
*/
template<class string_type, class char_type>
void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
tt_string & new_man,
tt_char decimal_point) const
string_type & new_man,
char_type decimal_point) const
{
// minimum two characters
if( new_man.length() < 2 )
@ -3523,7 +3567,7 @@ private:
// we must have a comma
// (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
// which is called before)
if( new_man.find_last_of(decimal_point, i) == tt_string::npos )
if( new_man.find_last_of(decimal_point, i) == string_type::npos )
return;
// if directly before the first zero is the comma operator
@ -3538,27 +3582,28 @@ private:
/*!
an auxiliary method for converting into the string
*/
template<class string_type, class char_type>
void ToString_CorrectDigitsAfterComma_Round(
tt_string & new_man,
string_type & new_man,
uint base,
sint max_digit_after_comma,
tt_char decimal_point) const
char_type decimal_point) const
{
// first we're looking for the comma operator
tt_string::size_type index = new_man.find(decimal_point, 0);
typename string_type::size_type index = new_man.find(decimal_point, 0);
if( index == tt_string::npos )
if( index == string_type::npos )
// nothing was found (actually there can't be this situation)
return;
// we're calculating how many digits there are at the end (after the comma)
// 'after_comma' will be greater than zero because at the end
// we have at least one digit
tt_string::size_type after_comma = new_man.length() - index - 1;
typename string_type::size_type after_comma = new_man.length() - index - 1;
// if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
// we don't have anything for cutting
if( tt_string::size_type(max_digit_after_comma) >= after_comma )
if( static_cast<typename string_type::size_type>(max_digit_after_comma) >= after_comma )
return;
uint last_digit = UInt<man>::CharToDigit( new_man[ index + max_digit_after_comma + 1 ], base );
@ -3581,31 +3626,13 @@ private:
public:
private:
/*!
a method for converting a string into its value
it returns 1 if the value will be too big -- we cannot pass it into the range
of our class Big<exp,man> (or if the base is incorrect)
that means only digits before the comma operator can make this value too big,
all digits after the comma we can ignore
'source' - pointer to the string for parsing
'const char*' or 'const wchar_t*'
if 'after_source' is set that when this method finishes
it sets the pointer to the new first character after parsed value
'value_read' - if the pointer is provided that means the value_read will be true
only when a value has been actually read, there can be situation where only such
a string '-' or '+' will be parsed -- 'after_source' will be different from 'source' but
no value has been read (there are no digits)
on other words if 'value_read' is true -- there is at least one digit in the string
an auxiliary method for converting from a string
*/
uint FromString(const tt_char * source, uint base = 10, const tt_char ** after_source = 0, bool * value_read = 0)
template<class char_type>
uint FromStringBase(const char_type * source, uint base = 10, const char_type ** after_source = 0, bool * value_read = 0)
{
bool is_sign;
bool value_read_temp = false;
@ -3648,15 +3675,54 @@ public:
private:
public:
/*!
a method for converting a string into its value
it returns 1 if the value will be too big -- we cannot pass it into the range
of our class Big<exp,man> (or if the base is incorrect)
that means only digits before the comma operator can make this value too big,
all digits after the comma we can ignore
'source' - pointer to the string for parsing
'const char*' or 'const wchar_t*'
if 'after_source' is set that when this method finishes
it sets the pointer to the new first character after parsed value
'value_read' - if the pointer is provided that means the value_read will be true
only when a value has been actually read, there can be situation where only such
a string '-' or '+' will be parsed -- 'after_source' will be different from 'source' but
no value has been read (there are no digits)
on other words if 'value_read' is true -- there is at least one digit in the string
*/
uint FromString(const char * source, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
{
return FromStringBase(source, base, after_source, value_read);
}
/*!
a method for converting a string into its value
*/
uint FromString(const wchar_t * source, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
{
return FromStringBase(source, base, after_source, value_read);
}
private:
/*!
we're testing whether the value is with the sign
(this method is used from 'FromString_ReadPartScientific' too)
*/
void FromString_TestSign( const tt_char * & source, bool & is_sign )
template<class char_type>
void FromString_TestSign( const char_type * & source, bool & is_sign )
{
UInt<man>::SkipWhiteCharacters(source);
@ -3678,7 +3744,8 @@ private:
/*!
we're testing whether there's a comma operator
*/
bool FromString_TestCommaOperator(const tt_char * & source)
template<class char_type>
bool FromString_TestCommaOperator(const char_type * & source)
{
if( (*source == TTMATH_COMMA_CHARACTER_1) ||
(*source == TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0 ) )
@ -3696,7 +3763,8 @@ private:
this method reads the first part of a string
(before the comma operator)
*/
uint FromString_ReadPartBeforeComma( const tt_char * & source, uint base, bool & value_read )
template<class char_type>
uint FromString_ReadPartBeforeComma( const char_type * & source, uint base, bool & value_read )
{
sint character;
Big<exp, man> temp;
@ -3725,7 +3793,8 @@ private:
this method reads the second part of a string
(after the comma operator)
*/
uint FromString_ReadPartAfterComma( const tt_char * & source, uint base, bool & value_read )
template<class char_type>
uint FromString_ReadPartAfterComma( const char_type * & source, uint base, bool & value_read )
{
sint character;
uint c = 0, index = 1;
@ -3783,12 +3852,13 @@ private:
it is called when the base is 10 and some digits were read before
*/
uint FromString_ReadScientificIfExists(const tt_char * & source)
template<class char_type>
uint FromString_ReadScientificIfExists(const char_type * & source)
{
uint c = 0;
bool scientific_read = false;
const tt_char * before_scientific = source;
const char_type * before_scientific = source;
if( FromString_TestScientific(source) )
c += FromString_ReadPartScientific( source, scientific_read );
@ -3806,7 +3876,8 @@ private:
this character is only allowed when we're using the base equals 10
*/
bool FromString_TestScientific(const tt_char * & source)
template<class char_type>
bool FromString_TestScientific(const char_type * & source)
{
UInt<man>::SkipWhiteCharacters(source);
@ -3825,7 +3896,8 @@ private:
this method reads the exponent (after 'e' character) when there's a scientific
format of value and only when we're using the base equals 10
*/
uint FromString_ReadPartScientific( const tt_char * & source, bool & scientific_read )
template<class char_type>
uint FromString_ReadPartScientific( const char_type * & source, bool & scientific_read )
{
uint c = 0;
Big<exp, man> new_exponent, temp;
@ -3852,7 +3924,8 @@ private:
this method reads the value of the extra exponent when scientific format is used
(only when base == 10)
*/
uint FromString_ReadPartScientific_ReadExponent( const tt_char * & source, Big<exp, man> & new_exponent, bool & scientific_read )
template<class char_type>
uint FromString_ReadPartScientific_ReadExponent( const char_type * & source, Big<exp, man> & new_exponent, bool & scientific_read )
{
sint character;
Big<exp, man> base, temp;
@ -3885,7 +3958,16 @@ public:
/*!
a method for converting a string into its value
*/
uint FromString(const tt_string & string, uint base = 10)
uint FromString(const std::string & string, uint base = 10)
{
return FromString( string.c_str(), base );
}
/*!
a method for converting a string into its value
*/
uint FromString(const std::wstring & string, uint base = 10)
{
return FromString( string.c_str(), base );
}
@ -3894,7 +3976,7 @@ public:
/*!
a constructor for converting a string into this class
*/
Big(const tt_char * string)
Big(const char * string)
{
FromString( string );
}
@ -3903,7 +3985,25 @@ public:
/*!
a constructor for converting a string into this class
*/
Big(const tt_string & string)
Big(const wchar_t * string)
{
FromString( string );
}
/*!
a constructor for converting a string into this class
*/
Big(const std::string & string)
{
FromString( string.c_str() );
}
/*!
a constructor for converting a string into this class
*/
Big(const std::wstring & string)
{
FromString( string.c_str() );
}
@ -3912,7 +4012,7 @@ public:
/*!
an operator= for converting a string into its value
*/
Big<exp, man> & operator=(const tt_char * string)
Big<exp, man> & operator=(const char * string)
{
FromString( string );
@ -3923,7 +4023,29 @@ public:
/*!
an operator= for converting a string into its value
*/
Big<exp, man> & operator=(const tt_string & string)
Big<exp, man> & operator=(const wchar_t * string)
{
FromString( string );
return *this;
}
/*!
an operator= for converting a string into its value
*/
Big<exp, man> & operator=(const std::string & string)
{
FromString( string.c_str() );
return *this;
}
/*!
an operator= for converting a string into its value
*/
Big<exp, man> & operator=(const std::wstring & string)
{
FromString( string.c_str() );
@ -4050,6 +4172,8 @@ public:
*/
bool AboutEqualWithoutSign(const Big<exp,man> & ss2, uint nBitsToIgnore) const
{
/* not finished, should be added testing then exponents are different about one */
// there is no sense to ignore the whole mantissas
TTMATH_ASSERT( nBitsToIgnore < man*TTMATH_BITS_PER_UINT )
@ -4444,14 +4568,15 @@ public:
*
*/
/*!
output for standard streams
private:
tt_ostream is either std::ostream or std::wostream
/*!
an auxiliary method for outputing to standard streams
*/
friend tt_ostream & operator<<(tt_ostream & s, const Big<exp,man> & l)
template<class ostream_type, class string_type>
static ostream_type & OutputToStream(ostream_type & s, const Big<exp,man> & l)
{
tt_string ss;
string_type ss;
l.ToString(ss);
s << ss;
@ -4460,18 +4585,42 @@ public:
}
/*!
input from standard streams
public:
tt_istream is either std::istream or std::wistream
/*!
output to standard streams
*/
friend tt_istream & operator>>(tt_istream & s, Big<exp,man> & l)
friend std::ostream & operator<<(std::ostream & s, const Big<exp,man> & l)
{
tt_string ss;
return OutputToStream<std::ostream, std::string>(s, l);
}
/*!
output to standard streams
*/
friend std::wostream & operator<<(std::wostream & s, const Big<exp,man> & l)
{
return OutputToStream<std::wostream, std::wstring>(s, l);
}
private:
/*!
an auxiliary method for converting from a string
*/
template<class istream_type, class string_type, class char_type>
static istream_type & InputFromStream(istream_type & s, Big<exp,man> & l)
{
string_type ss;
// 'tt_char' for operator>>
tt_char z;
// char or wchar_t for operator>>
char_type z, old_z;
bool was_comma = false;
bool was_e = false;
// operator>> omits white characters if they're set for ommiting
s >> z;
@ -4481,25 +4630,44 @@ public:
ss += z;
s >> z; // we're reading a next character (white characters can be ommited)
}
old_z = 0;
// we're reading only digits (base=10) and only one comma operator
for( ; s.good() ; z=static_cast<tt_char>(s.get()) )
for( ; s.good() ; z=static_cast<char_type>(s.get()) )
{
if( z == TTMATH_COMMA_CHARACTER_1 ||
( z == TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0 ) )
{
if( was_comma )
// second comma operator
if( was_comma || was_e )
// second comma operator or comma operator after 'e' character
break;
was_comma = true;
}
else
if( z == 'e' || z == 'E' )
{
if( was_e )
// second 'e' character
break;
was_e = true;
}
else
if( z == '+' || z == '-' )
{
if( old_z != 'e' && old_z != 'E' )
// '+' or '-' is allowed only after 'e' character
break;
}
else
if( UInt<man>::CharToDigit(z, 10) < 0 )
break;
ss += z;
ss += z;
old_z = z;
}
// we're leaving the last read character
@ -4511,6 +4679,27 @@ public:
return s;
}
public:
/*!
input from standard streams
*/
friend std::istream & operator>>(std::istream & s, Big<exp,man> & l)
{
return InputFromStream<std::istream, std::string, char>(s, l);
}
/*!
input from standard streams
*/
friend std::wistream & operator>>(std::wistream & s, Big<exp,man> & l)
{
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
}
};

View File

@ -821,7 +821,16 @@ public:
/*!
a constructor for converting string to this class (with the base=10)
*/
Int(const tt_char * s)
Int(const char * s)
{
FromString(s);
}
/*!
a constructor for converting string to this class (with the base=10)
*/
Int(const wchar_t * s)
{
FromString(s);
}
@ -830,7 +839,16 @@ public:
/*!
a constructor for converting a string to this class (with the base=10)
*/
Int(const tt_string & s)
Int(const std::string & s)
{
FromString( s.c_str() );
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
Int(const std::wstring & s)
{
FromString( s.c_str() );
}
@ -866,10 +884,13 @@ public:
}
private:
/*!
this method converts the value to a string with a base equal 'b'
an auxiliary method for converting to a string
*/
void ToString(tt_string & result, uint b = 10) const
template<class string_type>
void ToStringBase(string_type & result, uint b = 10) const
{
if( IsSign() )
{
@ -885,28 +906,33 @@ public:
}
}
public:
/*!
this method converts the value to a string with a base equal 'b'
*/
void ToString(std::string & result, uint b = 10) const
{
return ToStringBase(result, b);
}
/*!
this method converts the value to a string with a base equal 'b'
*/
void ToString(std::wstring & result, uint b = 10) const
{
return ToStringBase(result, b);
}
private:
/*!
this method converts a string into its value
string is given either as 'const char *' or 'const wchar_t *'
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
string is ended with a non-digit value, for example:
"-12" will be translated to -12
as well as:
"- 12foo" will be translated to -12 too
existing first white characters will be ommited
(between '-' and a first digit can be white characters too)
after_source (if exists) is pointing at the end of the parsed string
value_read (if exists) tells whether something has actually been read (at least one digit)
an auxiliary method for converting from a string
*/
uint FromString(const tt_char * s, uint b = 10, const tt_char ** after_source = 0, bool * value_read = 0)
template<class char_type>
uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
{
bool is_sign = false;
@ -959,11 +985,54 @@ public:
}
public:
/*!
this method converts a string into its value
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
string is ended with a non-digit value, for example:
"-12" will be translated to -12
as well as:
"- 12foo" will be translated to -12 too
existing first white characters will be ommited
(between '-' and a first digit can be white characters too)
after_source (if exists) is pointing at the end of the parsed string
value_read (if exists) tells whether something has actually been read (at least one digit)
*/
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
{
return FromStringBase(s, b, after_source, value_read);
}
/*!
this method converts a string into its value
*/
uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
{
return FromStringBase(s, b, after_source, value_read);
}
/*!
this method converts a string into its value
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
*/
uint FromString(const tt_string & s, uint b = 10)
uint FromString(const std::string & s, uint b = 10)
{
return FromString( s.c_str(), b );
}
/*!
this method converts a string into its value
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
*/
uint FromString(const std::wstring & s, uint b = 10)
{
return FromString( s.c_str(), b );
}
@ -972,7 +1041,7 @@ public:
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const tt_char * s)
Int<value_size> & operator=(const char * s)
{
FromString(s);
@ -983,7 +1052,18 @@ public:
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const tt_string & s)
Int<value_size> & operator=(const wchar_t * s)
{
FromString(s);
return *this;
}
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const std::string & s)
{
FromString( s.c_str() );
@ -991,6 +1071,15 @@ public:
}
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const std::wstring & s)
{
FromString( s.c_str() );
return *this;
}
/*!
@ -1270,14 +1359,15 @@ public:
*
*/
/*!
output for standard streams
private:
tt_ostream is either std::ostream or std::wostream
/*!
an auxiliary method for outputing to standard streams
*/
friend tt_ostream & operator<<(tt_ostream & s, const Int<value_size> & l)
template<class ostream_type, class string_type>
static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l)
{
tt_string ss;
string_type ss;
l.ToString(ss);
s << ss;
@ -1286,17 +1376,41 @@ public:
}
/*!
input from standard streams
tt_istream is either std::istream or std::wistream
public:
/*!
output to standard streams
*/
friend tt_istream & operator>>(tt_istream & s, Int<value_size> & l)
friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
{
tt_string ss;
return OutputToStream<std::ostream, std::string>(s, l);
}
/*!
output to standard streams
*/
friend std::wostream & operator<<(std::wostream & s, const Int<value_size> & l)
{
return OutputToStream<std::wostream, std::wstring>(s, l);
}
private:
/*!
an auxiliary method for converting from a string
*/
template<class istream_type, class string_type, class char_type>
static istream_type & InputFromStream(istream_type & s, Int<value_size> & l)
{
string_type ss;
// tt_char for operator>>
tt_char z;
// char or wchar_t for operator>>
char_type z;
// operator>> omits white characters if they're set for ommiting
s >> z;
@ -1311,7 +1425,7 @@ public:
while( s.good() && UInt<value_size>::CharToDigit(z, 10)>=0 )
{
ss += z;
z = static_cast<tt_char>(s.get());
z = static_cast<char_type>(s.get());
}
// we're leaving the last readed character
@ -1323,6 +1437,26 @@ public:
return s;
}
public:
/*!
input from standard streams
*/
friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
{
return InputFromStream<std::istream, std::string, char>(s, l);
}
/*!
input from standard streams
*/
friend std::wistream & operator>>(std::wistream & s, Int<value_size> & l)
{
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
}
};
} // namespace

155
ttmath/ttmathmisc.h Normal file
View File

@ -0,0 +1,155 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2006-2009, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * 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.
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER OR 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 headerfilettmathmisc
#define headerfilettmathmisc
/*!
\file ttmathmisc.h
\brief some helpful functions
*/
#include <string>
namespace ttmath
{
/*!
some helpful functions
*/
class Misc
{
public:
/*
*
* AssignString(result, str)
* result = str
*
*/
/*!
result = str
*/
static void AssignString(std::string & result, const char * str)
{
result = str;
}
/*!
result = str
*/
static void AssignString(std::wstring & result, const char * str)
{
result.clear();
for( ; *str ; ++str )
result += *str;
}
/*!
result = str
*/
static void AssignString(std::wstring & result, const std::string & str)
{
return AssignString(result, str.c_str());
}
/*!
result = str
*/
static void AssignString(std::string & result, const wchar_t * str)
{
result.clear();
for( ; *str ; ++str )
result += static_cast<char>(*str);
}
/*!
result = str
*/
static void AssignString(std::string & result, const std::wstring & str)
{
return AssignString(result, str.c_str());
}
/*
*
* AddString(result, str)
* result += str
*
*/
/*!
result += str
*/
static void AddString(std::string & result, const char * str)
{
result += str;
}
/*!
result += str
*/
static void AddString(std::wstring & result, const char * str)
{
for( ; *str ; ++str )
result += *str;
}
}; // struct Misc
}
#endif

View File

@ -44,13 +44,13 @@
\brief Mathematic functions.
*/
#include "ttmathtypes.h"
#include <string>
#include <vector>
#include <list>
#include <map>
#include "ttmathtypes.h"
#include "ttmathmisc.h"
namespace ttmath
@ -74,19 +74,19 @@ public:
struct Item
{
// name of a variable of a function
// (either std::string or std::wstring)
tt_string value;
// internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
std::string value;
// number of parameters required by the function
// (if there's a variable this 'param' is ignored)
int param;
Item() {}
Item(const tt_string & v, int p) : value(v), param(p) {}
Item(const std::string & v, int p) : value(v), param(p) {}
};
// 'Table' is the type of our table
typedef std::map<tt_string, Item> Table;
typedef std::map<std::string, Item> Table;
typedef Table::iterator Iterator;
typedef Table::const_iterator CIterator;
@ -99,7 +99,7 @@ public:
if 'can_be_digit' is true that means when the 'c' is a digit this
method returns true otherwise it returns false
*/
static bool CorrectCharacter(int c, bool can_be_digit)
static bool CorrectCharacter(wchar_t c, bool can_be_digit)
{
if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
return true;
@ -114,7 +114,8 @@ public:
/*!
this method returns true if the name can be as a name of an object
*/
static bool IsNameCorrect(const tt_string & name)
template<class string_type>
static bool IsNameCorrect(const string_type & name)
{
if( name.empty() )
return false;
@ -122,7 +123,7 @@ public:
if( !CorrectCharacter(name[0], false) )
return false;
tt_string::const_iterator i=name.begin();
typename string_type::const_iterator i = name.begin();
for(++i ; i!=name.end() ; ++i)
if( !CorrectCharacter(*i, true) )
@ -135,7 +136,7 @@ public:
/*!
this method returns true if such an object is defined (name exists)
*/
bool IsDefined(const tt_string & name)
bool IsDefined(const std::string & name)
{
Iterator i = table.find(name);
@ -147,10 +148,26 @@ public:
}
/*!
this method returns true if such an object is defined (name exists)
*/
bool IsDefined(const std::wstring & name)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return false;
Misc::AssignString(str_tmp1, name);
return IsDefined(str_tmp1);
}
/*!
this method adds one object (variable of function) into the table
*/
ErrorCode Add(const tt_string & name, const tt_string & value, int param = 0)
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -167,6 +184,23 @@ public:
}
/*!
this method adds one object (variable of function) into the table
*/
ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
Misc::AssignString(str_tmp2, value);
return Add(str_tmp1, str_tmp2, param);
}
/*!
this method returns 'true' if the table is empty
*/
@ -207,7 +241,7 @@ public:
/*!
this method changes the value and the number of parameters for a specific object
*/
ErrorCode EditValue(const tt_string & name, const tt_string & value, int param = 0)
ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -224,10 +258,27 @@ public:
}
/*!
this method changes the value and the number of parameters for a specific object
*/
ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
Misc::AssignString(str_tmp2, value);
return EditValue(str_tmp1, str_tmp2, param);
}
/*!
this method changes the name of a specific object
*/
ErrorCode EditName(const tt_string & old_name, const tt_string & new_name)
ErrorCode EditName(const std::string & old_name, const std::string & new_name)
{
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
return err_incorrect_name;
@ -255,10 +306,27 @@ public:
}
/*!
this method changes the name of a specific object
*/
ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, old_name);
Misc::AssignString(str_tmp2, new_name);
return EditName(str_tmp1, str_tmp2);
}
/*!
this method deletes an object
*/
ErrorCode Delete(const tt_string & name)
ErrorCode Delete(const std::string & name)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -274,10 +342,26 @@ public:
}
/*!
this method deletes an object
*/
ErrorCode Delete(const std::wstring & name)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
return Delete(str_tmp1);
}
/*!
this method gets the value of a specific object
*/
ErrorCode GetValue(const tt_string & name, tt_string & value) const
ErrorCode GetValue(const std::string & name, std::string & value) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -296,11 +380,29 @@ public:
}
/*!
this method gets the value of a specific object
*/
ErrorCode GetValue(const std::wstring & name, std::wstring & value)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
ErrorCode err = GetValue(str_tmp1, str_tmp2);
Misc::AssignString(value, str_tmp2);
return err;
}
/*!
this method gets the value of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValue(const tt_string & name, const tt_char ** value) const
ErrorCode GetValue(const std::string & name, const char ** value) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -319,11 +421,28 @@ public:
}
/*!
this method gets the value of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValue(const std::wstring & name, const char ** value)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
return GetValue(str_tmp1, value);
}
/*!
this method gets the value and the number of parameters
of a specific object
*/
ErrorCode GetValueAndParam(const tt_string & name, tt_string & value, int * param) const
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -344,12 +463,31 @@ public:
}
/*!
this method gets the value and the number of parameters
of a specific object
*/
ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param);
Misc::AssignString(value, str_tmp2);
return err;
}
/*!
this method sets the value and the number of parameters
of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValueAndParam(const tt_string & name, const tt_char ** value, int * param) const
ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -370,6 +508,25 @@ public:
}
/*!
this method sets the value and the number of parameters
of a specific object
(this version is used for not copying the whole string
but in fact we make one copying during AssignString())
*/
ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param)
{
// we should check whether the name (in wide characters) are correct
// before calling AssignString() function
if( !IsNameCorrect(name) )
return err_incorrect_name;
Misc::AssignString(str_tmp1, name);
return GetValueAndParam(str_tmp1, value, param);
}
/*!
this method returns a pointer into the table
*/
@ -382,6 +539,7 @@ public:
private:
Table table;
std::string str_tmp1, str_tmp2;
}; // end of class Objects

View File

@ -52,6 +52,7 @@
#include "ttmath.h"
#include "ttmathobjects.h"
#include "ttmathmisc.h"
@ -255,7 +256,7 @@ public:
bool function;
// if function is true
tt_string function_name;
std::string function_name;
/*
the sign of value
@ -314,7 +315,7 @@ ErrorCode error;
when an error has occured it may be used to count the index of the wrong character
*/
const tt_char * pstring;
const char * pstring;
/*!
@ -351,7 +352,7 @@ const Objects * puser_variables;
const Objects * puser_functions;
typedef std::map<tt_string, ValueType> FunctionLocalVariables;
typedef std::map<std::string, ValueType> FunctionLocalVariables;
/*!
a pointer to the local variables of a function
@ -362,13 +363,13 @@ const FunctionLocalVariables * pfunction_local_variables;
/*!
a temporary set using during parsing user defined variables
*/
std::set<tt_string> visited_variables;
std::set<std::string> visited_variables;
/*!
a temporary set using during parsing user defined functions
*/
std::set<tt_string> visited_functions;
std::set<std::string> visited_functions;
@ -396,10 +397,10 @@ typedef void (ValueType::*pfunction_var)();
table of mathematic functions
this map consists of:
tt_string - function's name
std::string - function's name
pfunction - pointer to specific function
*/
typedef std::map<tt_string, pfunction> FunctionsTable;
typedef std::map<std::string, pfunction> FunctionsTable;
FunctionsTable functions_table;
@ -407,10 +408,10 @@ FunctionsTable functions_table;
table of mathematic operators
this map consists of:
tt_string - operators's name
std::string - operators's name
MatOperator::Type - type of the operator
*/
typedef std::map<tt_string, typename MatOperator::Type> OperatorsTable;
typedef std::map<std::string, typename MatOperator::Type> OperatorsTable;
OperatorsTable operators_table;
@ -418,10 +419,10 @@ OperatorsTable operators_table;
table of mathematic variables
this map consists of:
tt_string - variable's name
std::string - variable's name
pfunction_var - pointer to specific function which returns value of variable
*/
typedef std::map<tt_string, pfunction_var> VariablesTable;
typedef std::map<std::string, pfunction_var> VariablesTable;
VariablesTable variables_table;
@ -455,7 +456,7 @@ void SkipWhiteCharacters()
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const tt_string & name)
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
{
if( variable )
{
@ -473,7 +474,7 @@ void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, cons
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const tt_string & name)
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
{
if( variable )
visited_variables.insert( name );
@ -485,7 +486,7 @@ void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const tt_string
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const tt_string & name)
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
{
if( variable )
visited_variables.erase( name );
@ -504,7 +505,7 @@ void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const tt_str
(there can be a recurrence here therefore we're using 'visited_variables'
and 'visited_functions' sets to make a stop condition)
*/
ValueType RecurrenceParsingVariablesOrFunction(bool variable, const tt_string & name, const tt_char * new_string,
ValueType RecurrenceParsingVariablesOrFunction(bool variable, const std::string & name, const char * new_string,
FunctionLocalVariables * local_variables = 0)
{
RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
@ -548,12 +549,12 @@ public:
/*!
this method returns the user-defined value of a variable
*/
bool GetValueOfUserDefinedVariable(const tt_string & variable_name,ValueType & result)
bool GetValueOfUserDefinedVariable(const std::string & variable_name,ValueType & result)
{
if( !puser_variables )
return false;
const tt_char * string_value;
const char * string_value;
if( puser_variables->GetValue(variable_name, &string_value) != err_ok )
return false;
@ -567,7 +568,7 @@ return true;
/*!
this method returns the value of a local variable of a function
*/
bool GetValueOfFunctionLocalVariable(const tt_string & variable_name, ValueType & result)
bool GetValueOfFunctionLocalVariable(const std::string & variable_name, ValueType & result)
{
if( !pfunction_local_variables )
return false;
@ -589,7 +590,7 @@ return true;
we make an object of type ValueType then call a method which
sets the correct value in it and finally we'll return the object
*/
ValueType GetValueOfVariable(const tt_string & variable_name)
ValueType GetValueOfVariable(const std::string & variable_name)
{
ValueType result;
@ -600,7 +601,7 @@ ValueType result;
return result;
typename std::map<tt_string, pfunction_var>::iterator i =
typename std::map<std::string, pfunction_var>::iterator i =
variables_table.find(variable_name);
if( i == variables_table.end() )
@ -1361,9 +1362,9 @@ void Avg(int sindex, int amount_of_args, ValueType & result)
/*!
we use such a method because 'wvsprintf' is not everywhere defined
*/
void Sprintf(tt_char * buffer, int par)
void Sprintf(char * buffer, int par)
{
char buf[30]; // char, not tt_char
char buf[30]; // char, not wchar_t etc.
int i;
#ifdef _MSC_VER
@ -1390,12 +1391,12 @@ int i;
(look at the description in 'CallFunction(...)')
*/
bool GetValueOfUserDefinedFunction(const tt_string & function_name, int amount_of_args, int sindex)
bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount_of_args, int sindex)
{
if( !puser_functions )
return false;
const tt_char * string_value;
const char * string_value;
int param;
if( puser_functions->GetValueAndParam(function_name, &string_value, &param) != err_ok )
@ -1409,7 +1410,7 @@ bool GetValueOfUserDefinedFunction(const tt_string & function_name, int amount_o
if( amount_of_args > 0 )
{
tt_char buffer[30];
char buffer[30];
// x = x1
buffer[0] = 'x';
@ -1443,7 +1444,7 @@ return true;
result will be stored in 'stack[sindex-1].value'
(we don't have to set the correct type of this element, it'll be set later)
*/
void CallFunction(const tt_string & function_name, int amount_of_args, int sindex)
void CallFunction(const std::string & function_name, int amount_of_args, int sindex)
{
if( GetValueOfUserDefinedFunction(function_name, amount_of_args, sindex) )
return;
@ -1469,12 +1470,16 @@ void CallFunction(const tt_string & function_name, int amount_of_args, int sinde
function_name - name of the function
pf - pointer to the function (to the wrapper)
*/
void InsertFunctionToTable(const tt_char * function_name, pfunction pf)
void InsertFunctionToTable(const char * function_name, pfunction pf)
{
functions_table.insert( std::make_pair(tt_string(function_name), pf));
std::string str;
Misc::AssignString(str, function_name);
functions_table.insert( std::make_pair(str, pf) );
}
/*!
inserting a function to the variables' table
(this function returns value of variable)
@ -1482,9 +1487,12 @@ void InsertFunctionToTable(const tt_char * function_name, pfunction pf)
variable_name - name of the function
pf - pointer to the function
*/
void InsertVariableToTable(const tt_char * variable_name, pfunction_var pf)
void InsertVariableToTable(const char * variable_name, pfunction_var pf)
{
variables_table.insert( std::make_pair(tt_string(variable_name), pf));
std::string str;
Misc::AssignString(str, variable_name);
variables_table.insert( std::make_pair(str, pf) );
}
@ -1493,65 +1501,65 @@ void InsertVariableToTable(const tt_char * variable_name, pfunction_var pf)
*/
void CreateFunctionsTable()
{
InsertFunctionToTable(TTMATH_TEXT("gamma"), &Parser<ValueType>::Gamma);
InsertFunctionToTable(TTMATH_TEXT("factorial"), &Parser<ValueType>::Factorial);
InsertFunctionToTable(TTMATH_TEXT("abs"), &Parser<ValueType>::Abs);
InsertFunctionToTable(TTMATH_TEXT("sin"), &Parser<ValueType>::Sin);
InsertFunctionToTable(TTMATH_TEXT("cos"), &Parser<ValueType>::Cos);
InsertFunctionToTable(TTMATH_TEXT("tan"), &Parser<ValueType>::Tan);
InsertFunctionToTable(TTMATH_TEXT("tg"), &Parser<ValueType>::Tan);
InsertFunctionToTable(TTMATH_TEXT("cot"), &Parser<ValueType>::Cot);
InsertFunctionToTable(TTMATH_TEXT("ctg"), &Parser<ValueType>::Cot);
InsertFunctionToTable(TTMATH_TEXT("int"), &Parser<ValueType>::Int);
InsertFunctionToTable(TTMATH_TEXT("round"), &Parser<ValueType>::Round);
InsertFunctionToTable(TTMATH_TEXT("ln"), &Parser<ValueType>::Ln);
InsertFunctionToTable(TTMATH_TEXT("log"), &Parser<ValueType>::Log);
InsertFunctionToTable(TTMATH_TEXT("exp"), &Parser<ValueType>::Exp);
InsertFunctionToTable(TTMATH_TEXT("max"), &Parser<ValueType>::Max);
InsertFunctionToTable(TTMATH_TEXT("min"), &Parser<ValueType>::Min);
InsertFunctionToTable(TTMATH_TEXT("asin"), &Parser<ValueType>::ASin);
InsertFunctionToTable(TTMATH_TEXT("acos"), &Parser<ValueType>::ACos);
InsertFunctionToTable(TTMATH_TEXT("atan"), &Parser<ValueType>::ATan);
InsertFunctionToTable(TTMATH_TEXT("atg"), &Parser<ValueType>::ATan);
InsertFunctionToTable(TTMATH_TEXT("acot"), &Parser<ValueType>::ACot);
InsertFunctionToTable(TTMATH_TEXT("actg"), &Parser<ValueType>::ACot);
InsertFunctionToTable(TTMATH_TEXT("sgn"), &Parser<ValueType>::Sgn);
InsertFunctionToTable(TTMATH_TEXT("mod"), &Parser<ValueType>::Mod);
InsertFunctionToTable(TTMATH_TEXT("if"), &Parser<ValueType>::If);
InsertFunctionToTable(TTMATH_TEXT("or"), &Parser<ValueType>::Or);
InsertFunctionToTable(TTMATH_TEXT("and"), &Parser<ValueType>::And);
InsertFunctionToTable(TTMATH_TEXT("not"), &Parser<ValueType>::Not);
InsertFunctionToTable(TTMATH_TEXT("degtorad"), &Parser<ValueType>::DegToRad);
InsertFunctionToTable(TTMATH_TEXT("radtodeg"), &Parser<ValueType>::RadToDeg);
InsertFunctionToTable(TTMATH_TEXT("degtodeg"), &Parser<ValueType>::DegToDeg);
InsertFunctionToTable(TTMATH_TEXT("gradtorad"), &Parser<ValueType>::GradToRad);
InsertFunctionToTable(TTMATH_TEXT("radtograd"), &Parser<ValueType>::RadToGrad);
InsertFunctionToTable(TTMATH_TEXT("degtograd"), &Parser<ValueType>::DegToGrad);
InsertFunctionToTable(TTMATH_TEXT("gradtodeg"), &Parser<ValueType>::GradToDeg);
InsertFunctionToTable(TTMATH_TEXT("ceil"), &Parser<ValueType>::Ceil);
InsertFunctionToTable(TTMATH_TEXT("floor"), &Parser<ValueType>::Floor);
InsertFunctionToTable(TTMATH_TEXT("sqrt"), &Parser<ValueType>::Sqrt);
InsertFunctionToTable(TTMATH_TEXT("sinh"), &Parser<ValueType>::Sinh);
InsertFunctionToTable(TTMATH_TEXT("cosh"), &Parser<ValueType>::Cosh);
InsertFunctionToTable(TTMATH_TEXT("tanh"), &Parser<ValueType>::Tanh);
InsertFunctionToTable(TTMATH_TEXT("tgh"), &Parser<ValueType>::Tanh);
InsertFunctionToTable(TTMATH_TEXT("coth"), &Parser<ValueType>::Coth);
InsertFunctionToTable(TTMATH_TEXT("ctgh"), &Parser<ValueType>::Coth);
InsertFunctionToTable(TTMATH_TEXT("root"), &Parser<ValueType>::Root);
InsertFunctionToTable(TTMATH_TEXT("asinh"), &Parser<ValueType>::ASinh);
InsertFunctionToTable(TTMATH_TEXT("acosh"), &Parser<ValueType>::ACosh);
InsertFunctionToTable(TTMATH_TEXT("atanh"), &Parser<ValueType>::ATanh);
InsertFunctionToTable(TTMATH_TEXT("atgh"), &Parser<ValueType>::ATanh);
InsertFunctionToTable(TTMATH_TEXT("acoth"), &Parser<ValueType>::ACoth);
InsertFunctionToTable(TTMATH_TEXT("actgh"), &Parser<ValueType>::ACoth);
InsertFunctionToTable(TTMATH_TEXT("bitand"), &Parser<ValueType>::BitAnd);
InsertFunctionToTable(TTMATH_TEXT("bitor"), &Parser<ValueType>::BitOr);
InsertFunctionToTable(TTMATH_TEXT("bitxor"), &Parser<ValueType>::BitXor);
InsertFunctionToTable(TTMATH_TEXT("band"), &Parser<ValueType>::BitAnd);
InsertFunctionToTable(TTMATH_TEXT("bor"), &Parser<ValueType>::BitOr);
InsertFunctionToTable(TTMATH_TEXT("bxor"), &Parser<ValueType>::BitXor);
InsertFunctionToTable(TTMATH_TEXT("sum"), &Parser<ValueType>::Sum);
InsertFunctionToTable(TTMATH_TEXT("avg"), &Parser<ValueType>::Avg);
InsertFunctionToTable("gamma", &Parser<ValueType>::Gamma);
InsertFunctionToTable("factorial", &Parser<ValueType>::Factorial);
InsertFunctionToTable("abs", &Parser<ValueType>::Abs);
InsertFunctionToTable("sin", &Parser<ValueType>::Sin);
InsertFunctionToTable("cos", &Parser<ValueType>::Cos);
InsertFunctionToTable("tan", &Parser<ValueType>::Tan);
InsertFunctionToTable("tg", &Parser<ValueType>::Tan);
InsertFunctionToTable("cot", &Parser<ValueType>::Cot);
InsertFunctionToTable("ctg", &Parser<ValueType>::Cot);
InsertFunctionToTable("int", &Parser<ValueType>::Int);
InsertFunctionToTable("round", &Parser<ValueType>::Round);
InsertFunctionToTable("ln", &Parser<ValueType>::Ln);
InsertFunctionToTable("log", &Parser<ValueType>::Log);
InsertFunctionToTable("exp", &Parser<ValueType>::Exp);
InsertFunctionToTable("max", &Parser<ValueType>::Max);
InsertFunctionToTable("min", &Parser<ValueType>::Min);
InsertFunctionToTable("asin", &Parser<ValueType>::ASin);
InsertFunctionToTable("acos", &Parser<ValueType>::ACos);
InsertFunctionToTable("atan", &Parser<ValueType>::ATan);
InsertFunctionToTable("atg", &Parser<ValueType>::ATan);
InsertFunctionToTable("acot", &Parser<ValueType>::ACot);
InsertFunctionToTable("actg", &Parser<ValueType>::ACot);
InsertFunctionToTable("sgn", &Parser<ValueType>::Sgn);
InsertFunctionToTable("mod", &Parser<ValueType>::Mod);
InsertFunctionToTable("if", &Parser<ValueType>::If);
InsertFunctionToTable("or", &Parser<ValueType>::Or);
InsertFunctionToTable("and", &Parser<ValueType>::And);
InsertFunctionToTable("not", &Parser<ValueType>::Not);
InsertFunctionToTable("degtorad", &Parser<ValueType>::DegToRad);
InsertFunctionToTable("radtodeg", &Parser<ValueType>::RadToDeg);
InsertFunctionToTable("degtodeg", &Parser<ValueType>::DegToDeg);
InsertFunctionToTable("gradtorad", &Parser<ValueType>::GradToRad);
InsertFunctionToTable("radtograd", &Parser<ValueType>::RadToGrad);
InsertFunctionToTable("degtograd", &Parser<ValueType>::DegToGrad);
InsertFunctionToTable("gradtodeg", &Parser<ValueType>::GradToDeg);
InsertFunctionToTable("ceil", &Parser<ValueType>::Ceil);
InsertFunctionToTable("floor", &Parser<ValueType>::Floor);
InsertFunctionToTable("sqrt", &Parser<ValueType>::Sqrt);
InsertFunctionToTable("sinh", &Parser<ValueType>::Sinh);
InsertFunctionToTable("cosh", &Parser<ValueType>::Cosh);
InsertFunctionToTable("tanh", &Parser<ValueType>::Tanh);
InsertFunctionToTable("tgh", &Parser<ValueType>::Tanh);
InsertFunctionToTable("coth", &Parser<ValueType>::Coth);
InsertFunctionToTable("ctgh", &Parser<ValueType>::Coth);
InsertFunctionToTable("root", &Parser<ValueType>::Root);
InsertFunctionToTable("asinh", &Parser<ValueType>::ASinh);
InsertFunctionToTable("acosh", &Parser<ValueType>::ACosh);
InsertFunctionToTable("atanh", &Parser<ValueType>::ATanh);
InsertFunctionToTable("atgh", &Parser<ValueType>::ATanh);
InsertFunctionToTable("acoth", &Parser<ValueType>::ACoth);
InsertFunctionToTable("actgh", &Parser<ValueType>::ACoth);
InsertFunctionToTable("bitand", &Parser<ValueType>::BitAnd);
InsertFunctionToTable("bitor", &Parser<ValueType>::BitOr);
InsertFunctionToTable("bitxor", &Parser<ValueType>::BitXor);
InsertFunctionToTable("band", &Parser<ValueType>::BitAnd);
InsertFunctionToTable("bor", &Parser<ValueType>::BitOr);
InsertFunctionToTable("bxor", &Parser<ValueType>::BitXor);
InsertFunctionToTable("sum", &Parser<ValueType>::Sum);
InsertFunctionToTable("avg", &Parser<ValueType>::Avg);
}
@ -1560,8 +1568,8 @@ void CreateFunctionsTable()
*/
void CreateVariablesTable()
{
InsertVariableToTable(TTMATH_TEXT("pi"), &ValueType::SetPi);
InsertVariableToTable(TTMATH_TEXT("e"), &ValueType::SetE);
InsertVariableToTable("pi", &ValueType::SetPi);
InsertVariableToTable("e", &ValueType::SetE);
}
@ -1587,7 +1595,7 @@ return c;
what should be returned is tested just by a '(' character that means if there's
a '(' character after a name that function returns 'true'
*/
bool ReadName(tt_string & result)
bool ReadName(std::string & result)
{
int character;
@ -1604,7 +1612,7 @@ int character;
do
{
result += static_cast<tt_char>( character );
result += static_cast<char>( character );
character = * ++pstring;
}
while( (character>='a' && character<='z') ||
@ -1659,7 +1667,7 @@ return false;
*/
bool ReadVariableOrFunction(Item & result)
{
tt_string name;
std::string name;
bool is_it_name_of_function = ReadName(name);
if( is_it_name_of_function )
@ -1688,7 +1696,7 @@ return is_it_name_of_function;
*/
void ReadValue(Item & result, int reading_base)
{
const tt_char * new_stack_pointer;
const char * new_stack_pointer;
bool value_read;
uint carry = result.value.FromString(pstring, reading_base, &new_stack_pointer, &value_read);
@ -1861,9 +1869,9 @@ return 0;
}
void InsertOperatorToTable(const tt_char * name, typename MatOperator::Type type)
void InsertOperatorToTable(const char * name, typename MatOperator::Type type)
{
operators_table.insert( std::make_pair(tt_string(name), type) );
operators_table.insert( std::make_pair(std::string(name), type) );
}
@ -1872,19 +1880,19 @@ void InsertOperatorToTable(const tt_char * name, typename MatOperator::Type type
*/
void CreateMathematicalOperatorsTable()
{
InsertOperatorToTable(TTMATH_TEXT("||"), MatOperator::lor);
InsertOperatorToTable(TTMATH_TEXT("&&"), MatOperator::land);
InsertOperatorToTable(TTMATH_TEXT("!="), MatOperator::neq);
InsertOperatorToTable(TTMATH_TEXT("=="), MatOperator::eq);
InsertOperatorToTable(TTMATH_TEXT(">="), MatOperator::get);
InsertOperatorToTable(TTMATH_TEXT("<="), MatOperator::let);
InsertOperatorToTable(TTMATH_TEXT(">"), MatOperator::gt);
InsertOperatorToTable(TTMATH_TEXT("<"), MatOperator::lt);
InsertOperatorToTable(TTMATH_TEXT("-"), MatOperator::sub);
InsertOperatorToTable(TTMATH_TEXT("+"), MatOperator::add);
InsertOperatorToTable(TTMATH_TEXT("/"), MatOperator::div);
InsertOperatorToTable(TTMATH_TEXT("*"), MatOperator::mul);
InsertOperatorToTable(TTMATH_TEXT("^"), MatOperator::pow);
InsertOperatorToTable("||", MatOperator::lor);
InsertOperatorToTable("&&", MatOperator::land);
InsertOperatorToTable("!=", MatOperator::neq);
InsertOperatorToTable("==", MatOperator::eq);
InsertOperatorToTable(">=", MatOperator::get);
InsertOperatorToTable("<=", MatOperator::let);
InsertOperatorToTable(">", MatOperator::gt);
InsertOperatorToTable("<", MatOperator::lt);
InsertOperatorToTable("-", MatOperator::sub);
InsertOperatorToTable("+", MatOperator::add);
InsertOperatorToTable("/", MatOperator::div);
InsertOperatorToTable("*", MatOperator::mul);
InsertOperatorToTable("^", MatOperator::pow);
}
@ -1894,12 +1902,12 @@ void CreateMathematicalOperatorsTable()
e.g.
true when str1="test" and str2="te"
*/
bool IsSubstring(const tt_string & str1, const tt_string & str2)
bool IsSubstring(const std::string & str1, const std::string & str2)
{
if( str2.length() > str1.length() )
return false;
for(tt_string::size_type i=0 ; i<str2.length() ; ++i)
for(typename std::string::size_type i=0 ; i<str2.length() ; ++i)
if( str1[i] != str2[i] )
return false;
@ -1912,7 +1920,7 @@ return true;
*/
void ReadMathematicalOperator(Item & result)
{
tt_string oper;
std::string oper;
typename OperatorsTable::iterator iter_old, iter_new;
iter_old = operators_table.end();
@ -2546,7 +2554,7 @@ void SetFunctions(const Objects * pf)
/*!
the main method using for parsing string
*/
ErrorCode Parse(const tt_char * str)
ErrorCode Parse(const char * str)
{
stack_index = 0;
pstring = str;
@ -2569,9 +2577,38 @@ return error;
}
};
/*!
the main method using for parsing string
*/
ErrorCode Parse(const std::string & str)
{
return Parse(str.c_str());
}
/*!
the main method using for parsing string
*/
ErrorCode Parse(const wchar_t * str)
{
std::string temp;
Misc::AssignString(temp, str);
return Parse(temp.c_str());
}
/*!
the main method using for parsing string
*/
ErrorCode Parse(const std::wstring & str)
{
return Parse(str.c_str());
}
};
} // namespace

View File

@ -207,34 +207,6 @@ namespace ttmath
}
#if defined(UNICODE) || defined(_UNICODE)
#define TTMATH_USE_WCHAR
#endif
#ifdef TTMATH_USE_WCHAR
typedef wchar_t tt_char;
typedef std::wstring tt_string;
typedef std::wostringstream tt_ostringstream;
typedef std::wostream tt_ostream;
typedef std::wistream tt_istream;
#define TTMATH_TEXT_HELPER(txt) L##txt
#else
typedef char tt_char;
typedef std::string tt_string;
typedef std::ostringstream tt_ostringstream;
typedef std::ostream tt_ostream;
typedef std::istream tt_istream;
#define TTMATH_TEXT_HELPER(txt) txt
#endif
#define TTMATH_TEXT(txt) TTMATH_TEXT_HELPER(txt)
#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
@ -370,20 +342,20 @@ namespace ttmath
*/
class ExceptionInfo
{
const tt_char * file;
const char * file;
int line;
public:
ExceptionInfo() : file(0), line(0) {}
ExceptionInfo(const tt_char * f, int l) : file(f), line(l) {}
ExceptionInfo(const char * f, int l) : file(f), line(l) {}
tt_string Where() const
std::string Where() const
{
if( !file )
return TTMATH_TEXT("unknown");
return "unknown";
tt_ostringstream result;
result << file << TTMATH_TEXT(":") << line;
std::ostringstream result;
result << file << ":" << line;
return result.str();
}
@ -397,7 +369,7 @@ namespace ttmath
can throw an exception of this type
If you compile with gcc you can get a small benefit
from using method Where() (it returns std::string (or std::wstring) with
from using method Where() (it returns std::string) with
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
was used)
@ -425,12 +397,12 @@ namespace ttmath
{
}
ReferenceError(const tt_char * f, int l) :
ReferenceError(const char * f, int l) :
std::logic_error("reference error"), ExceptionInfo(f,l)
{
}
tt_string Where() const
std::string Where() const
{
return ExceptionInfo::Where();
}
@ -445,7 +417,7 @@ namespace ttmath
of this type
if you compile with gcc you can get a small benefit
from using method Where() (it returns std::string (or std::wstring) with
from using method Where() (it returns std::string) with
the name and the line of a file where the macro TTMATH_ASSERT
was used)
*/
@ -457,12 +429,12 @@ namespace ttmath
{
}
RuntimeError(const tt_char * f, int l) :
RuntimeError(const char * f, int l) :
std::runtime_error("internal error"), ExceptionInfo(f,l)
{
}
tt_string Where() const
std::string Where() const
{
return ExceptionInfo::Where();
}
@ -477,19 +449,11 @@ namespace ttmath
#if defined(__FILE__) && defined(__LINE__)
#ifdef TTMATH_USE_WCHAR
#define TTMATH_FILE_HELPER2(arg) L##arg
#define TTMATH_FILE_HELPER(x) TTMATH_FILE_HELPER2(x)
#define TTMATH_FILE TTMATH_FILE_HELPER(__FILE__)
#else
#define TTMATH_FILE __FILE__
#endif
#define TTMATH_REFERENCE_ASSERT(expression) \
if( &(expression) == this ) throw ttmath::ReferenceError(TTMATH_FILE, __LINE__);
if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw ttmath::RuntimeError(TTMATH_FILE, __LINE__);
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
#else
@ -508,21 +472,9 @@ namespace ttmath
#ifdef TTMATH_DEBUG_LOG
#ifdef TTMATH_USE_WCHAR
#define TTMATH_LOG_HELPER(msg) \
PrintLog(L##msg, std::wcout);
#else
#define TTMATH_LOG_HELPER(msg) \
PrintLog(msg, std::cout);
#endif
#define TTMATH_LOG(msg) TTMATH_LOG_HELPER(msg)
#define TTMATH_LOG(msg) PrintLog(msg, std::cout);
#else
#define TTMATH_LOG(msg)
#endif

View File

@ -51,6 +51,7 @@
#include "ttmathtypes.h"
#include "ttmathmisc.h"
@ -86,10 +87,8 @@ public:
it prints the table in a nice form of several columns
*/
#ifndef TTMATH_USE_WCHAR
// gcc has a problem with std::setfill when wchar_t is used
void PrintTable(tt_ostream & output) const
template<class ostream_type>
void PrintTable(ostream_type & output) const
{
// how many columns there'll be
const int columns = 8;
@ -97,7 +96,7 @@ public:
int c = 1;
for(int i=value_size-1 ; i>=0 ; --i)
{
output << TTMATH_TEXT("0x") << std::setfill('0');
output << "0x" << std::setfill('0');
#ifdef TTMATH_PLATFORM32
output << std::setw(8);
@ -109,7 +108,7 @@ public:
if( i>0 )
{
output << TTMATH_TEXT(", ");
output << ", ";
if( ++c > columns )
{
@ -121,14 +120,15 @@ public:
output << std::dec << std::endl;
}
#endif
void PrintLog(const tt_char * msg, tt_ostream & output) const
template<class char_type, class ostream_type>
void PrintLog(const char_type * msg, ostream_type & output) const
{
output << msg << std::endl;
for(uint i=0 ; i<value_size ; ++i)
output << TTMATH_TEXT(" table[") << i << TTMATH_TEXT("]: ") << table[i] << std::endl;
output << " table[" << i << "]: " << table[i] << std::endl;
}
@ -2503,10 +2503,10 @@ public:
the programmer do that:
UInt<..> type = 10;
this constant 10 has the int type (signed int), if we don't give such
above "10" constant has the int type (signed int), if we don't give such
operators and constructors the compiler will not compile the program,
because it has to make a conversion and doesn't know into which type
(the UInt class has operator=(const tt_char*), operator=(uint) etc.)
(the UInt class has operator=(const char*), operator=(uint) etc.)
*/
UInt<value_size> & operator=(sint i)
{
@ -2621,18 +2621,38 @@ public:
/*!
a constructor for converting a string to this class (with the base=10)
*/
UInt(const tt_char * s)
UInt(const char * s)
{
FromString(s);
TTMATH_LOG("UInt::UInt(const tt_char *)")
TTMATH_LOG("UInt::UInt(const char *)")
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
UInt(const tt_string & s)
UInt(const wchar_t * s)
{
FromString(s);
TTMATH_LOG("UInt::UInt(const wchar_t *)")
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
UInt(const std::string & s)
{
FromString( s.c_str() );
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
UInt(const std::wstring & s)
{
FromString( s.c_str() );
}
@ -2695,13 +2715,16 @@ public:
}
private:
/*!
this method converts the value to a string with a base equal 'b'
an auxiliary method for converting to a string
*/
void ToString(tt_string & result, uint b = 10) const
template<class string_type>
void ToStringBase(string_type & result, uint b = 10) const
{
UInt<value_size> temp( *this );
tt_char character;
char character;
uint rem;
result.clear();
@ -2712,7 +2735,7 @@ public:
do
{
temp.DivInt(b, &rem);
character = static_cast<tt_char>( DigitToChar(rem) );
character = static_cast<char>( DigitToChar(rem) );
result.insert(result.begin(), character);
}
while( !temp.IsZero() );
@ -2721,36 +2744,42 @@ public:
}
public:
/*!
this method converts the value to a string with a base equal 'b'
*/
void ToString(std::string & result, uint b = 10) const
{
return ToStringBase(result, b);
}
void ToString(std::wstring & result, uint b = 10) const
{
return ToStringBase(result, b);
}
/*
this method's ommiting any white characters from the string
char_type is char or wchar_t
*/
static void SkipWhiteCharacters(const tt_char * & c)
template<class char_type>
static void SkipWhiteCharacters(const char_type * & c)
{
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
++c;
}
private:
/*!
this method converts a string into its value
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
string is ended with a non-digit value, for example:
"12" will be translated to 12
as well as:
"12foo" will be translated to 12 too
existing first white characters will be ommited
if the value from s is too large the rest digits will be skipped
after_source (if exists) is pointing at the end of the parsed string
value_read (if exists) tells whether something has actually been read (at least one digit)
an auxiliary method for converting from a string
*/
uint FromString(const tt_char * s, uint b = 10, const tt_char ** after_source = 0, bool * value_read = 0)
template<class char_type>
uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
{
UInt<value_size> base( b );
UInt<value_size> temp;
@ -2794,28 +2823,70 @@ public:
}
public:
/*!
this method converts a string into its value
it returns carry=1 if the value will be too big or an incorrect base 'b' is given
string is ended with a non-digit value, for example:
"12" will be translated to 12
as well as:
"12foo" will be translated to 12 too
existing first white characters will be ommited
if the value from s is too large the rest digits will be skipped
after_source (if exists) is pointing at the end of the parsed string
value_read (if exists) tells whether something has actually been read (at least one digit)
*/
uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
{
return FromStringBase(s, b, after_source, value_read);
}
/*!
this method converts a string into its value
*/
uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
{
return FromStringBase(s, b, after_source, value_read);
}
/*!
this method converts a string into its value
(it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
*/
uint FromString(const tt_string & s, uint b = 10)
uint FromString(const std::string & s, uint b = 10)
{
return FromString( s.c_str(), b );
}
/*!
this method converts a string into its value
(it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
*/
uint FromString(const std::wstring & s, uint b = 10)
{
return FromString( s.c_str(), b );
}
/*!
this operator converts a string into its value (with base = 10)
*/
UInt<value_size> & operator=(const tt_char * s)
UInt<value_size> & operator=(const char * s)
{
FromString(s);
TTMATH_LOG("UInt::operator=(const tt_char *)")
return *this;
}
@ -2823,7 +2894,18 @@ public:
/*!
this operator converts a string into its value (with base = 10)
*/
UInt<value_size> & operator=(const tt_string & s)
UInt<value_size> & operator=(const wchar_t * s)
{
FromString(s);
return *this;
}
/*!
this operator converts a string into its value (with base = 10)
*/
UInt<value_size> & operator=(const std::string & s)
{
FromString( s.c_str() );
@ -2831,6 +2913,15 @@ public:
}
/*!
this operator converts a string into its value (with base = 10)
*/
UInt<value_size> & operator=(const std::wstring & s)
{
FromString( s.c_str() );
return *this;
}
/*!
@ -3192,14 +3283,16 @@ public:
*/
/*!
output for standard streams
private:
tt_ostream is either std::ostream or std::wostream
/*!
an auxiliary method for outputing to standard streams
*/
friend tt_ostream & operator<<(tt_ostream & s, const UInt<value_size> & l)
template<class ostream_type, class string_type>
static ostream_type & OutputToStream(ostream_type & s, const UInt<value_size> & l)
{
tt_string ss;
string_type ss;
l.ToString(ss);
s << ss;
@ -3208,18 +3301,39 @@ public:
}
public:
/*!
input from standard streams
tt_istream is either std::istream or std::wistream
output to standard streams
*/
friend tt_istream & operator>>(tt_istream & s, UInt<value_size> & l)
friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
{
tt_string ss;
return OutputToStream<std::ostream, std::string>(s, l);
}
/*!
output to standard streams
*/
friend std::wostream & operator<<(std::wostream & s, const UInt<value_size> & l)
{
return OutputToStream<std::wostream, std::wstring>(s, l);
}
private:
/*!
an auxiliary method for reading from standard streams
*/
template<class istream_type, class string_type, class char_type>
static istream_type & InputFromStream(istream_type & s, UInt<value_size> & l)
{
string_type ss;
// tt_char for operator>>
tt_char z;
// char or wchar_t for operator>>
char_type z;
// operator>> omits white characters if they're set for ommiting
s >> z;
@ -3228,7 +3342,7 @@ public:
while( s.good() && CharToDigit(z, 10)>=0 )
{
ss += z;
z = static_cast<tt_char>(s.get());
z = static_cast<char_type>(s.get());
}
// we're leaving the last read character
@ -3237,11 +3351,28 @@ public:
l.FromString(ss);
TTMATH_LOG("UInt::operator>>")
return s;
}
public:
/*!
input from standard streams
*/
friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
{
return InputFromStream<std::istream, std::string, char>(s, l);
}
/*!
input from standard streams
*/
friend std::wistream & operator>>(std::wistream & s, UInt<value_size> & l)
{
return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
}
/*