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)


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@177 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-07-02 01:04:25 +00:00
parent c70a947c07
commit d3a64b79ca
10 changed files with 375 additions and 283 deletions

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -50,12 +50,9 @@
#pragma warning( disable: 4127 )
#endif
#include "ttmathbig.h"
#include "ttmathobjects.h"
#include <string>
namespace ttmath
{
@ -2282,7 +2279,6 @@ namespace ttmath
}
} // namespace

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -267,7 +267,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 char*) on a 32bit platform)
// and they were set into Big<1,400> type (using operator=(const tt_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))
@ -2705,20 +2705,20 @@ public:
output:
return value:
0 - ok and 'result' will be an object of type std::string which holds the value
0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
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( std::string & result,
uint ToString( tt_string & result,
uint base = 10,
bool always_scientific = false,
sint when_scientific = 15,
sint max_digit_after_comma = -1,
bool remove_trailing_zeroes = true,
char decimal_point = TTMATH_COMMA_CHARACTER_1 ) const
tt_char decimal_point = TTMATH_COMMA_CHARACTER_1 ) const
{
static char error_overflow_msg[] = "overflow";
static char error_nan_msg[] = "NaN";
static tt_char error_overflow_msg[] = TTMATH_TEXT("overflow");
static tt_char error_nan_msg[] = TTMATH_TEXT("NaN");
result.erase();
if( IsNan() )
@ -2735,7 +2735,7 @@ public:
if( IsZero() )
{
result = "0";
result = '0';
return 0;
}
@ -2860,7 +2860,7 @@ 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( std::string & new_man, uint base,
uint ToString_CreateNewMantissaAndExponent( tt_string & new_man, uint base,
Int<exp+1> & new_exp) const
{
uint c = 0;
@ -3043,7 +3043,7 @@ 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( std::string & new_man,
uint ToString_CreateNewMantissaAndExponent_Base2( tt_string & new_man,
Int<exp+1> & new_exp ) const
{
for( sint i=man-1 ; i>=0 ; --i )
@ -3073,13 +3073,13 @@ 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(std::string & new_man, uint base, Int<exp+1> & new_exp, char decimal_point) const
uint ToString_RoundMantissa(tt_string & new_man, uint base, Int<exp+1> & new_exp, tt_char decimal_point) const
{
// we must have minimum two characters
if( new_man.length() < 2 )
return 0;
std::string::size_type i = new_man.length() - 1;
tt_string::size_type i = new_man.length() - 1;
// we're erasing the last character
uint digit = UInt<man>::CharToDigit( new_man[i] );
@ -3100,7 +3100,7 @@ private:
this method addes one into the new mantissa
*/
void ToString_RoundMantissa_AddOneIntoMantissa(std::string & new_man, uint base, char decimal_point) const
void ToString_RoundMantissa_AddOneIntoMantissa(tt_string & new_man, uint base, tt_char decimal_point) const
{
if( new_man.empty() )
return;
@ -3124,7 +3124,7 @@ private:
else
was_carry = false;
new_man[i] = static_cast<char>( UInt<man>::DigitToChar(digit) );
new_man[i] = static_cast<tt_char>( UInt<man>::DigitToChar(digit) );
}
if( i<0 && was_carry )
@ -3138,13 +3138,13 @@ private:
this method sets the comma operator and/or puts the exponent
into the string
*/
uint ToString_SetCommaAndExponent( std::string & new_man, uint base,
uint ToString_SetCommaAndExponent( tt_string & new_man, uint base,
Int<exp+1> & new_exp,
bool always_scientific,
sint when_scientific,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
char decimal_point) const
tt_char decimal_point) const
{
uint carry = 0;
@ -3184,12 +3184,12 @@ private:
an auxiliary method for converting into the string
*/
void ToString_SetCommaAndExponent_Normal(
std::string & new_man,
tt_string & new_man,
uint base,
Int<exp+1> & new_exp,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
char decimal_point) const
tt_char decimal_point) const
{
if( !new_exp.IsSign() ) //if( new_exp >= 0 )
return ToString_SetCommaAndExponent_Normal_AddingZero(new_man, new_exp);
@ -3201,8 +3201,8 @@ private:
/*!
an auxiliary method for converting into the string
*/
void ToString_SetCommaAndExponent_Normal_AddingZero(std::string & new_man,
Int<exp+1> & new_exp) const
void ToString_SetCommaAndExponent_Normal_AddingZero(tt_string & new_man,
Int<exp+1> & new_exp) const
{
// we're adding zero characters at the end
// 'i' will be smaller than 'when_scientific' (or equal)
@ -3221,12 +3221,12 @@ private:
an auxiliary method for converting into the string
*/
void ToString_SetCommaAndExponent_Normal_SetCommaInside(
std::string & new_man,
tt_string & new_man,
uint base,
Int<exp+1> & new_exp,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
char decimal_point) const
tt_char decimal_point) const
{
// new_exp is < 0
@ -3245,7 +3245,7 @@ private:
// we're adding zero characters before the mantissa
uint how_many = e - new_man_len;
std::string man_temp(how_many+1, '0');
tt_string man_temp(how_many+1, '0');
man_temp.insert( man_temp.begin()+1, decimal_point);
new_man.insert(0, man_temp);
@ -3258,12 +3258,12 @@ private:
/*!
an auxiliary method for converting into the string
*/
void ToString_SetCommaAndExponent_Scientific( std::string & new_man,
void ToString_SetCommaAndExponent_Scientific( tt_string & new_man,
uint base,
Int<exp+1> & scientific_exp,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
char decimal_point) const
tt_char decimal_point) const
{
if( new_man.empty() )
return;
@ -3277,16 +3277,16 @@ private:
new_man += 'e';
if( !scientific_exp.IsSign() )
new_man += "+";
new_man += '+';
}
else
{
// the 10 here is meant as the base 'base'
// (no matter which 'base' we're using there'll always be 10 here)
new_man += "*10^";
new_man += TTMATH_TEXT("*10^");
}
std::string temp_exp;
tt_string temp_exp;
scientific_exp.ToString( temp_exp, base );
new_man += temp_exp;
@ -3296,11 +3296,11 @@ private:
/*!
an auxiliary method for converting into the string
*/
void ToString_CorrectDigitsAfterComma( std::string & new_man,
void ToString_CorrectDigitsAfterComma( tt_string & new_man,
uint base,
sint max_digit_after_comma,
bool remove_trailing_zeroes,
char decimal_point) const
tt_char decimal_point) const
{
if( max_digit_after_comma >= 0 )
ToString_CorrectDigitsAfterComma_Round(new_man, base, max_digit_after_comma, decimal_point);
@ -3314,8 +3314,8 @@ private:
an auxiliary method for converting into the string
*/
void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
std::string & new_man,
char decimal_point) const
tt_string & new_man,
tt_char decimal_point) const
{
// minimum two characters
if( new_man.length() < 2 )
@ -3333,7 +3333,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) == std::string::npos )
if( new_man.find_last_of(decimal_point, i) == tt_string::npos )
return;
// if directly before the first zero is the comma operator
@ -3349,26 +3349,26 @@ private:
an auxiliary method for converting into the string
*/
void ToString_CorrectDigitsAfterComma_Round(
std::string & new_man,
tt_string & new_man,
uint base,
sint max_digit_after_comma,
char decimal_point) const
tt_char decimal_point) const
{
// first we're looking for the comma operator
std::string::size_type index = new_man.find(decimal_point, 0);
tt_string::size_type index = new_man.find(decimal_point, 0);
if( index == std::string::npos )
if( index == tt_string::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
std::string::size_type after_comma = new_man.length() - index - 1;
tt_string::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( std::string::size_type(max_digit_after_comma) >= after_comma )
if( tt_string::size_type(max_digit_after_comma) >= after_comma )
return;
uint last_digit = UInt<man>::CharToDigit( new_man[ index + max_digit_after_comma + 1 ], base );
@ -3404,6 +3404,7 @@ public:
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
@ -3414,7 +3415,7 @@ public:
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)
uint FromString(const tt_char * source, uint base = 10, const tt_char ** after_source = 0, bool * value_read = 0)
{
bool is_sign;
bool value_read_temp = false;
@ -3465,7 +3466,7 @@ private:
(this method is used from 'FromString_ReadPartScientific' too)
*/
void FromString_TestSign( const char * & source, bool & is_sign )
void FromString_TestSign( const tt_char * & source, bool & is_sign )
{
UInt<man>::SkipWhiteCharacters(source);
@ -3487,7 +3488,7 @@ private:
/*!
we're testing whether there's a comma operator
*/
bool FromString_TestCommaOperator(const char * & source)
bool FromString_TestCommaOperator(const tt_char * & source)
{
if( (*source == TTMATH_COMMA_CHARACTER_1) ||
(*source == TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0 ) )
@ -3505,7 +3506,7 @@ private:
this method reads the first part of a string
(before the comma operator)
*/
uint FromString_ReadPartBeforeComma( const char * & source, uint base, bool & value_read )
uint FromString_ReadPartBeforeComma( const tt_char * & source, uint base, bool & value_read )
{
sint character;
Big<exp, man> temp;
@ -3534,7 +3535,7 @@ private:
this method reads the second part of a string
(after the comma operator)
*/
uint FromString_ReadPartAfterComma( const char * & source, uint base, bool & value_read )
uint FromString_ReadPartAfterComma( const tt_char * & source, uint base, bool & value_read )
{
sint character;
uint c = 0, index = 1;
@ -3592,12 +3593,12 @@ private:
it is called when the base is 10 and some digits were read before
*/
uint FromString_ReadScientificIfExists(const char * & source)
uint FromString_ReadScientificIfExists(const tt_char * & source)
{
uint c = 0;
bool scientific_read = false;
const char * before_scientific = source;
const tt_char * before_scientific = source;
if( FromString_TestScientific(source) )
c += FromString_ReadPartScientific( source, scientific_read );
@ -3615,7 +3616,7 @@ private:
this character is only allowed when we're using the base equals 10
*/
bool FromString_TestScientific(const char * & source)
bool FromString_TestScientific(const tt_char * & source)
{
UInt<man>::SkipWhiteCharacters(source);
@ -3634,7 +3635,7 @@ 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 char * & source, bool & scientific_read )
uint FromString_ReadPartScientific( const tt_char * & source, bool & scientific_read )
{
uint c = 0;
Big<exp, man> new_exponent, temp;
@ -3661,7 +3662,7 @@ private:
this method reads the value of the extra exponent when scientific format is used
(only when base == 10)
*/
uint FromString_ReadPartScientific_ReadExponent( const char * & source, Big<exp, man> & new_exponent, bool & scientific_read )
uint FromString_ReadPartScientific_ReadExponent( const tt_char * & source, Big<exp, man> & new_exponent, bool & scientific_read )
{
sint character;
Big<exp, man> base, temp;
@ -3694,7 +3695,7 @@ public:
/*!
a method for converting a string into its value
*/
uint FromString(const std::string & string, uint base = 10)
uint FromString(const tt_string & string, uint base = 10)
{
return FromString( string.c_str(), base );
}
@ -3703,7 +3704,7 @@ public:
/*!
a constructor for converting a string into this class
*/
Big(const char * string)
Big(const tt_char * string)
{
FromString( string );
}
@ -3712,7 +3713,7 @@ public:
/*!
a constructor for converting a string into this class
*/
Big(const std::string & string)
Big(const tt_string & string)
{
FromString( string.c_str() );
}
@ -3721,7 +3722,7 @@ public:
/*!
an operator= for converting a string into its value
*/
Big<exp, man> & operator=(const char * string)
Big<exp, man> & operator=(const tt_char * string)
{
FromString( string );
@ -3732,7 +3733,7 @@ public:
/*!
an operator= for converting a string into its value
*/
Big<exp, man> & operator=(const std::string & string)
Big<exp, man> & operator=(const tt_string & string)
{
FromString( string.c_str() );
@ -4145,9 +4146,14 @@ public:
*
*/
friend std::ostream & operator<<(std::ostream & s, const Big<exp,man> & l)
/*!
output for standard streams
tt_ostream is either std::ostream or std::wostream
*/
friend tt_ostream & operator<<(tt_ostream & s, const Big<exp,man> & l)
{
std::string ss;
tt_string ss;
l.ToString(ss);
s << ss;
@ -4156,12 +4162,17 @@ public:
}
friend std::istream & operator>>(std::istream & s, Big<exp,man> & l)
/*!
input from standard streams
tt_istream is either std::istream or std::wistream
*/
friend tt_istream & operator>>(tt_istream & s, Big<exp,man> & l)
{
std::string ss;
tt_string ss;
// 'char' for operator>>
unsigned char z;
// 'tt_char' for operator>>
tt_char z;
bool was_comma = false;
// operator>> omits white characters if they're set for ommiting
@ -4174,7 +4185,7 @@ public:
}
// we're reading only digits (base=10) and only one comma operator
for( ; s.good() ; z=s.get() )
for( ; s.good() ; z=static_cast<tt_char>(s.get()) )
{
if( z == TTMATH_COMMA_CHARACTER_1 ||
( z == TTMATH_COMMA_CHARACTER_2 && TTMATH_COMMA_CHARACTER_2 != 0 ) )

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -821,7 +821,7 @@ public:
/*!
a constructor for converting string to this class (with the base=10)
*/
Int(const char * s)
Int(const tt_char * s)
{
FromString(s);
}
@ -830,7 +830,7 @@ public:
/*!
a constructor for converting a string to this class (with the base=10)
*/
Int(const std::string & s)
Int(const tt_string & s)
{
FromString( s.c_str() );
}
@ -869,7 +869,7 @@ public:
/*!
this method converts the value to a string with a base equal 'b'
*/
void ToString(std::string & result, uint b = 10) const
void ToString(tt_string & result, uint b = 10) const
{
if( IsSign() )
{
@ -890,12 +890,14 @@ public:
/*!
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
"- 12foo" will be translated to -12 too
existing first white characters will be ommited
(between '-' and a first digit can be white characters too)
@ -904,7 +906,7 @@ public:
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)
uint FromString(const tt_char * s, uint b = 10, const tt_char ** after_source = 0, bool * value_read = 0)
{
bool is_sign = false;
@ -961,16 +963,16 @@ 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
*/
uint FromString(const std::string & s, uint b = 10)
uint FromString(const tt_string & s, uint b = 10)
{
return FromString( s.c_str() );
return FromString( s.c_str(), b );
}
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const char * s)
Int<value_size> & operator=(const tt_char * s)
{
FromString(s);
@ -981,7 +983,7 @@ public:
/*!
this operator converts a string into its value (with base = 10)
*/
Int<value_size> & operator=(const std::string & s)
Int<value_size> & operator=(const tt_string & s)
{
FromString( s.c_str() );
@ -1268,9 +1270,14 @@ public:
*
*/
friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
/*!
output for standard streams
tt_ostream is either std::ostream or std::wostream
*/
friend tt_ostream & operator<<(tt_ostream & s, const Int<value_size> & l)
{
std::string ss;
tt_string ss;
l.ToString(ss);
s << ss;
@ -1279,13 +1286,17 @@ public:
}
/*!
input from standard streams
friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
tt_istream is either std::istream or std::wistream
*/
friend tt_istream & operator>>(tt_istream & s, Int<value_size> & l)
{
std::string ss;
tt_string ss;
// char for operator>>
unsigned char z;
// tt_char for operator>>
tt_char z;
// operator>> omits white characters if they're set for ommiting
s >> z;
@ -1300,7 +1311,7 @@ public:
while( s.good() && UInt<value_size>::CharToDigit(z, 10)>=0 )
{
ss += z;
z = s.get();
z = static_cast<tt_char>(s.get());
}
// we're leaving the last readed character

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Mathematical Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -73,18 +73,19 @@ public:
struct Item
{
// name of a variable of a function
std::string value;
// (either std::string or std::wstring)
tt_string value;
// number of parameters required by the function
// (if there's a variable this 'param' is ignored)
int param;
Item() {}
Item(const std::string & v, int p) : value(v), param(p) {}
Item(const tt_string & v, int p) : value(v), param(p) {}
};
// 'Table' is the type of our table
typedef std::map<std::string, Item> Table;
typedef std::map<tt_string, Item> Table;
typedef Table::iterator Iterator;
typedef Table::const_iterator CIterator;
@ -112,7 +113,7 @@ public:
/*!
this method returns true if the name can be as a name of an object
*/
static bool IsNameCorrect(const std::string & name)
static bool IsNameCorrect(const tt_string & name)
{
if( name.empty() )
return false;
@ -120,7 +121,7 @@ public:
if( !CorrectCharacter(name[0], false) )
return false;
std::string::const_iterator i=name.begin();
tt_string::const_iterator i=name.begin();
for(++i ; i!=name.end() ; ++i)
if( !CorrectCharacter(*i, true) )
@ -133,7 +134,7 @@ public:
/*!
this method returns true if such an object is defined (name exists)
*/
bool IsDefined(const std::string & name)
bool IsDefined(const tt_string & name)
{
Iterator i = table.find(name);
@ -148,7 +149,7 @@ public:
/*!
this method adds one object (variable of function) into the table
*/
ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
ErrorCode Add(const tt_string & name, const tt_string & value, int param = 0)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -205,7 +206,7 @@ public:
/*!
this method changes the value and the number of parameters for a specific object
*/
ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0)
ErrorCode EditValue(const tt_string & name, const tt_string & value, int param = 0)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -225,7 +226,7 @@ public:
/*!
this method changes the name of a specific object
*/
ErrorCode EditName(const std::string & old_name, const std::string & new_name)
ErrorCode EditName(const tt_string & old_name, const tt_string & new_name)
{
if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
return err_incorrect_name;
@ -256,7 +257,7 @@ public:
/*!
this method deletes an object
*/
ErrorCode Delete(const std::string & name)
ErrorCode Delete(const tt_string & name)
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -275,7 +276,7 @@ public:
/*!
this method gets the value of a specific object
*/
ErrorCode GetValue(const std::string & name, std::string & value) const
ErrorCode GetValue(const tt_string & name, tt_string & value) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -298,7 +299,7 @@ public:
this method gets the value of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValue(const std::string & name, const char ** value) const
ErrorCode GetValue(const tt_string & name, const tt_char ** value) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -321,7 +322,7 @@ public:
this method gets the value and the number of parameters
of a specific object
*/
ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
ErrorCode GetValueAndParam(const tt_string & name, tt_string & value, int * param) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;
@ -347,7 +348,7 @@ public:
of a specific object
(this version is used for not copying the whole string)
*/
ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const
ErrorCode GetValueAndParam(const tt_string & name, const tt_char ** value, int * param) const
{
if( !IsNameCorrect(name) )
return err_incorrect_name;

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -45,7 +45,7 @@
\brief A mathematical parser
*/
#include <fstream>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
@ -256,7 +256,7 @@ public:
bool function;
// if function is true
std::string function_name;
tt_string function_name;
/*
the sign of value
@ -311,10 +311,11 @@ ErrorCode error;
/*!
pointer to the currently reading char
it's either char* or wchar_t*
when an error has occured it may be used to count the index of the wrong character
*/
const char * pstring;
const tt_char * pstring;
/*!
@ -351,7 +352,7 @@ const Objects * puser_variables;
const Objects * puser_functions;
typedef std::map<std::string, ValueType> FunctionLocalVariables;
typedef std::map<tt_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<std::string> visited_variables;
std::set<tt_string> visited_variables;
/*!
a temporary set using during parsing user defined functions
*/
std::set<std::string> visited_functions;
std::set<tt_string> visited_functions;
@ -396,10 +397,10 @@ typedef void (ValueType::*pfunction_var)();
table of mathematic functions
this map consists of:
std::string - function's name
pfunction - pointer to specific function
tt_string - function's name
pfunction - pointer to specific function
*/
typedef std::map<std::string, pfunction> FunctionsTable;
typedef std::map<tt_string, pfunction> FunctionsTable;
FunctionsTable functions_table;
@ -407,10 +408,10 @@ FunctionsTable functions_table;
table of mathematic operators
this map consists of:
std::string - operators's name
tt_string - operators's name
MatOperator::Type - type of the operator
*/
typedef std::map<std::string, typename MatOperator::Type> OperatorsTable;
typedef std::map<tt_string, typename MatOperator::Type> OperatorsTable;
OperatorsTable operators_table;
@ -418,10 +419,10 @@ OperatorsTable operators_table;
table of mathematic variables
this map consists of:
std::string - variable's name
tt_string - variable's name
pfunction_var - pointer to specific function which returns value of variable
*/
typedef std::map<std::string, pfunction_var> VariablesTable;
typedef std::map<tt_string, pfunction_var> VariablesTable;
VariablesTable variables_table;
@ -456,7 +457,7 @@ void SkipWhiteCharacters()
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const tt_string & name)
{
if( variable )
{
@ -474,7 +475,7 @@ void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, cons
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const tt_string & name)
{
if( variable )
visited_variables.insert( name );
@ -486,7 +487,7 @@ void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::stri
/*!
an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
*/
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const tt_string & name)
{
if( variable )
visited_variables.erase( name );
@ -505,7 +506,8 @@ void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::s
(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 std::string & name, const char * new_string, FunctionLocalVariables * local_variables = 0)
ValueType RecurrenceParsingVariablesOrFunction(bool variable, const tt_string & name, const tt_char * new_string,
FunctionLocalVariables * local_variables = 0)
{
RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
RecurrenceParsingVariablesOrFunction_AddName(variable, name);
@ -548,12 +550,12 @@ public:
/*!
this method returns the user-defined value of a variable
*/
bool GetValueOfUserDefinedVariable(const std::string & variable_name,ValueType & result)
bool GetValueOfUserDefinedVariable(const tt_string & variable_name,ValueType & result)
{
if( !puser_variables )
return false;
const char * string_value;
const tt_char * string_value;
if( puser_variables->GetValue(variable_name, &string_value) != err_ok )
return false;
@ -567,7 +569,7 @@ return true;
/*!
this method returns the value of a local variable of a function
*/
bool GetValueOfFunctionLocalVariable(const std::string & variable_name, ValueType & result)
bool GetValueOfFunctionLocalVariable(const tt_string & variable_name, ValueType & result)
{
if( !pfunction_local_variables )
return false;
@ -589,7 +591,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 std::string & variable_name)
ValueType GetValueOfVariable(const tt_string & variable_name)
{
ValueType result;
@ -600,7 +602,7 @@ ValueType result;
return result;
typename std::map<std::string, pfunction_var>::iterator i =
typename std::map<tt_string, pfunction_var>::iterator i =
variables_table.find(variable_name);
if( i == variables_table.end() )
@ -1344,17 +1346,34 @@ 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)
{
char buf[30]; // char, not tt_char
int i;
sprintf(buf, "%d", par);
for(i=0 ; buf[i] != 0 ; ++i)
buffer[i] = buf[i];
buffer[i] = 0;
}
/*!
this method returns the value from a user-defined function
(look at the description in 'CallFunction(...)')
*/
bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount_of_args, int sindex)
bool GetValueOfUserDefinedFunction(const tt_string & function_name, int amount_of_args, int sindex)
{
if( !puser_functions )
return false;
const char * string_value;
const tt_char * string_value;
int param;
if( puser_functions->GetValueAndParam(function_name, &string_value, &param) != err_ok )
@ -1368,15 +1387,17 @@ bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount
if( amount_of_args > 0 )
{
char buffer[20];
tt_char buffer[30];
// x = x1
sprintf(buffer,"x");
buffer[0] = 'x';
buffer[1] = 0;
local_variables.insert( std::make_pair(buffer, stack[sindex].value) );
for(int i=0 ; i<amount_of_args ; ++i)
{
sprintf(buffer,"x%d",i+1);
buffer[0] = 'x';
Sprintf(buffer+1, i+1);
local_variables.insert( std::make_pair(buffer, stack[sindex + i*2].value) );
}
}
@ -1400,7 +1421,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 std::string & function_name, int amount_of_args, int sindex)
void CallFunction(const tt_string & function_name, int amount_of_args, int sindex)
{
if( GetValueOfUserDefinedFunction(function_name, amount_of_args, sindex) )
return;
@ -1426,9 +1447,9 @@ void CallFunction(const std::string & function_name, int amount_of_args, int sin
function_name - name of the function
pf - pointer to the function (to the wrapper)
*/
void InsertFunctionToTable(const char * function_name, pfunction pf)
void InsertFunctionToTable(const tt_char * function_name, pfunction pf)
{
functions_table.insert( std::make_pair(std::string(function_name), pf));
functions_table.insert( std::make_pair(tt_string(function_name), pf));
}
@ -1439,9 +1460,9 @@ void InsertFunctionToTable(const char * function_name, pfunction pf)
variable_name - name of the function
pf - pointer to the function
*/
void InsertVariableToTable(const char * variable_name, pfunction_var pf)
void InsertVariableToTable(const tt_char * variable_name, pfunction_var pf)
{
variables_table.insert( std::make_pair(std::string(variable_name), pf));
variables_table.insert( std::make_pair(tt_string(variable_name), pf));
}
@ -1450,67 +1471,64 @@ void InsertVariableToTable(const char * variable_name, pfunction_var pf)
*/
void CreateFunctionsTable()
{
/*
names of functions should consist of small letters
*/
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);
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);
}
@ -1519,11 +1537,8 @@ void CreateFunctionsTable()
*/
void CreateVariablesTable()
{
/*
names of variables should consist of small letters
*/
InsertVariableToTable("pi", &ValueType::SetPi);
InsertVariableToTable("e", &ValueType::SetE);
InsertVariableToTable(TTMATH_TEXT("pi"), &ValueType::SetPi);
InsertVariableToTable(TTMATH_TEXT("e"), &ValueType::SetE);
}
@ -1549,7 +1564,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(std::string & result)
bool ReadName(tt_string & result)
{
int character;
@ -1566,7 +1581,7 @@ int character;
do
{
result += static_cast<char>( character );
result += static_cast<tt_char>( character );
character = * ++pstring;
}
while( (character>='a' && character<='z') ||
@ -1621,7 +1636,7 @@ return false;
*/
bool ReadVariableOrFunction(Item & result)
{
std::string name;
tt_string name;
bool is_it_name_of_function = ReadName(name);
if( is_it_name_of_function )
@ -1650,7 +1665,7 @@ return is_it_name_of_function;
*/
void ReadValue(Item & result, int reading_base)
{
const char * new_stack_pointer;
const tt_char * new_stack_pointer;
bool value_read;
int carry = result.value.FromString(pstring, reading_base, &new_stack_pointer, &value_read);
@ -1823,9 +1838,9 @@ return 0;
}
void InsertOperatorToTable(const std::string & name, typename MatOperator::Type type)
void InsertOperatorToTable(const tt_char * name, typename MatOperator::Type type)
{
operators_table.insert( std::make_pair(name, type) );
operators_table.insert( std::make_pair(tt_string(name), type) );
}
@ -1834,19 +1849,19 @@ void InsertOperatorToTable(const std::string & name, typename MatOperator::Type
*/
void CreateMathematicalOperatorsTable()
{
InsertOperatorToTable(std::string("||"), MatOperator::lor);
InsertOperatorToTable(std::string("&&"), MatOperator::land);
InsertOperatorToTable(std::string("!="), MatOperator::neq);
InsertOperatorToTable(std::string("=="), MatOperator::eq);
InsertOperatorToTable(std::string(">="), MatOperator::get);
InsertOperatorToTable(std::string("<="), MatOperator::let);
InsertOperatorToTable(std::string(">"), MatOperator::gt);
InsertOperatorToTable(std::string("<"), MatOperator::lt);
InsertOperatorToTable(std::string("-"), MatOperator::sub);
InsertOperatorToTable(std::string("+"), MatOperator::add);
InsertOperatorToTable(std::string("/"), MatOperator::div);
InsertOperatorToTable(std::string("*"), MatOperator::mul);
InsertOperatorToTable(std::string("^"), MatOperator::pow);
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);
}
@ -1856,12 +1871,12 @@ void CreateMathematicalOperatorsTable()
e.g.
true when str1="test" and str2="te"
*/
bool IsSubstring(const std::string & str1, const std::string & str2)
bool IsSubstring(const tt_string & str1, const tt_string & str2)
{
if( str2.length() > str1.length() )
return false;
for(std::string::size_type i=0 ; i<str2.length() ; ++i)
for(tt_string::size_type i=0 ; i<str2.length() ; ++i)
if( str1[i] != str2[i] )
return false;
@ -1874,7 +1889,7 @@ return true;
*/
void ReadMathematicalOperator(Item & result)
{
std::string oper;
tt_string oper;
typename OperatorsTable::iterator iter_old, iter_new;
iter_old = operators_table.end();
@ -2421,10 +2436,10 @@ Parser<ValueType> & operator=(const Parser<ValueType> & p)
puser_variables = p.puser_variables;
puser_functions = p.puser_functions;
pfunction_local_variables = 0;
base = p.base;
deg_rad_grad = p.deg_rad_grad;
error = err_ok;
factorial_max = p.factorial_max;
base = p.base;
deg_rad_grad = p.deg_rad_grad;
error = err_ok;
factorial_max = p.factorial_max;
/*
we don't have to call 'CreateFunctionsTable()' etc.
@ -2521,7 +2536,7 @@ void SetFactorialMax(const ValueType & m)
/*!
the main method using for parsing string
*/
ErrorCode Parse(const char * str)
ErrorCode Parse(const tt_char * str)
{
stack_index = 0;
pstring = str;

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -63,9 +63,9 @@
if zero that means this is the release version of the library
*/
#define TTMATH_MAJOR_VER 0
#define TTMATH_MINOR_VER 8
#define TTMATH_REVISION_VER 5
#define TTMATH_PRERELEASE_VER 0
#define TTMATH_MINOR_VER 9
#define TTMATH_REVISION_VER 0
#define TTMATH_PRERELEASE_VER 1
/*!
@ -201,6 +201,36 @@ 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)
/*!
characters which represent the comma operator
@ -313,20 +343,20 @@ namespace ttmath
*/
class ExceptionInfo
{
const char * file;
const tt_char * file;
int line;
public:
ExceptionInfo() : file(0), line(0) {}
ExceptionInfo(const char * f, int l) : file(f), line(l) {}
ExceptionInfo(const tt_char * f, int l) : file(f), line(l) {}
std::string Where() const
tt_string Where() const
{
if( !file )
return "unknown";
return TTMATH_TEXT("unknown");
std::ostringstream result;
result << file << ":" << line;
tt_ostringstream result;
result << file << TTMATH_TEXT(":") << line;
return result.str();
}
@ -340,7 +370,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 with
from using method Where() (it returns std::string (or std::wstring) with
the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
was used)
@ -364,16 +394,16 @@ namespace ttmath
{
public:
ReferenceError() : std::logic_error ("reference error")
ReferenceError() : std::logic_error("reference error")
{
}
ReferenceError(const char * f, int l) :
std::logic_error ("reference error"), ExceptionInfo(f,l)
ReferenceError(const tt_char * f, int l) :
std::logic_error("reference error"), ExceptionInfo(f,l)
{
}
std::string Where() const
tt_string Where() const
{
return ExceptionInfo::Where();
}
@ -388,7 +418,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 with
from using method Where() (it returns std::string (or std::wstring) with
the name and the line of a file where the macro TTMATH_ASSERT
was used)
*/
@ -396,16 +426,16 @@ namespace ttmath
{
public:
RuntimeError() : std::runtime_error ("internal error")
RuntimeError() : std::runtime_error("internal error")
{
}
RuntimeError(const char * f, int l) :
std::runtime_error ("internal error"), ExceptionInfo(f,l)
RuntimeError(const tt_char * f, int l) :
std::runtime_error("internal error"), ExceptionInfo(f,l)
{
}
std::string Where() const
tt_string Where() const
{
return ExceptionInfo::Where();
}
@ -420,11 +450,19 @@ 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(__FILE__, __LINE__);
if( &(expression) == this ) throw ttmath::ReferenceError(TTMATH_FILE, __LINE__);
#define TTMATH_ASSERT(expression) \
if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
if( !(expression) ) throw ttmath::RuntimeError(TTMATH_FILE, __LINE__);
#else
@ -444,8 +482,15 @@ namespace ttmath
#ifdef TTMATH_DEBUG_LOG
#define TTMATH_LOG(msg) \
PrintLog(msg, std::cout);
#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(quote) TTMATH_LOG_HELPER(quote)
#else
@ -453,8 +498,10 @@ namespace ttmath
#endif
} // namespace
#endif

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -86,7 +86,10 @@ public:
it prints the table in a nice form of several columns
*/
void PrintTable(std::ostream & output) const
#ifndef TTMATH_USE_WCHAR
// gcc has a problem with std::setfill when wchar_t is used
void PrintTable(tt_ostream & output) const
{
// how many columns there'll be
const int columns = 8;
@ -94,7 +97,7 @@ public:
int c = 1;
for(int i=value_size-1 ; i>=0 ; --i)
{
output << "0x" << std::setfill('0');
output << TTMATH_TEXT("0x") << std::setfill('0');
#ifdef TTMATH_PLATFORM32
output << std::setw(8);
@ -106,7 +109,7 @@ public:
if( i>0 )
{
output << ", ";
output << TTMATH_TEXT(", ");
if( ++c > columns )
{
@ -118,14 +121,14 @@ public:
output << std::dec << std::endl;
}
#endif
void PrintLog(const char * msg, std::ostream & output) const
void PrintLog(const tt_char * msg, tt_ostream & output) const
{
output << msg << std::endl;
for(uint i=0 ; i<value_size ; ++i)
output << " table[" << i << "]: " << table[i] << std::endl;
output << TTMATH_TEXT(" table[") << i << TTMATH_TEXT("]: ") << table[i] << std::endl;
}
@ -2503,7 +2506,7 @@ public:
this constant 10 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 char*), operator=(uint) etc.)
(the UInt class has operator=(const tt_char*), operator=(uint) etc.)
*/
UInt<value_size> & operator=(sint i)
{
@ -2618,18 +2621,18 @@ public:
/*!
a constructor for converting a string to this class (with the base=10)
*/
UInt(const char * s)
UInt(const tt_char * s)
{
FromString(s);
TTMATH_LOG("UInt::UInt(const char *)")
TTMATH_LOG("UInt::UInt(const tt_char *)")
}
/*!
a constructor for converting a string to this class (with the base=10)
*/
UInt(const std::string & s)
UInt(const tt_string & s)
{
FromString( s.c_str() );
}
@ -2644,6 +2647,7 @@ public:
{
}
/*!
a copy constructor
*/
@ -2694,10 +2698,10 @@ public:
/*!
this method converts the value to a string with a base equal 'b'
*/
void ToString(std::string & result, uint b = 10) const
void ToString(tt_string & result, uint b = 10) const
{
UInt<value_size> temp( *this );
char character;
tt_char character;
uint rem;
result.clear();
@ -2708,7 +2712,7 @@ public:
do
{
temp.DivInt(b, &rem);
character = static_cast<char>( DigitToChar(rem) );
character = static_cast<tt_char>( DigitToChar(rem) );
result.insert(result.begin(), character);
}
while( !temp.IsZero() );
@ -2722,7 +2726,7 @@ public:
/*
this method's ommiting any white characters from the string
*/
static void SkipWhiteCharacters(const char * & c)
static void SkipWhiteCharacters(const tt_char * & c)
{
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
++c;
@ -2746,7 +2750,7 @@ public:
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)
uint FromString(const tt_char * s, uint b = 10, const tt_char ** after_source = 0, bool * value_read = 0)
{
UInt<value_size> base( b );
UInt<value_size> temp;
@ -2796,7 +2800,7 @@ public:
(it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
*/
uint FromString(const std::string & s, uint b = 10)
uint FromString(const tt_string & s, uint b = 10)
{
return FromString( s.c_str(), b );
}
@ -2806,11 +2810,11 @@ public:
/*!
this operator converts a string into its value (with base = 10)
*/
UInt<value_size> & operator=(const char * s)
UInt<value_size> & operator=(const tt_char * s)
{
FromString(s);
TTMATH_LOG("UInt::operator=(const char *)")
TTMATH_LOG("UInt::operator=(const tt_char *)")
return *this;
}
@ -2819,7 +2823,7 @@ public:
/*!
this operator converts a string into its value (with base = 10)
*/
UInt<value_size> & operator=(const std::string & s)
UInt<value_size> & operator=(const tt_string & s)
{
FromString( s.c_str() );
@ -3187,9 +3191,15 @@ public:
*
*/
friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
/*!
output for standard streams
tt_ostream is either std::ostream or std::wostream
*/
friend tt_ostream & operator<<(tt_ostream & s, const UInt<value_size> & l)
{
std::string ss;
tt_string ss;
l.ToString(ss);
s << ss;
@ -3199,12 +3209,17 @@ public:
friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
/*!
input from standard streams
tt_istream is either std::istream or std::wistream
*/
friend tt_istream & operator>>(tt_istream & s, UInt<value_size> & l)
{
std::string ss;
tt_string ss;
// char for operator>>
unsigned char z;
// tt_char for operator>>
tt_char z;
// operator>> omits white characters if they're set for ommiting
s >> z;
@ -3213,10 +3228,10 @@ public:
while( s.good() && CharToDigit(z, 10)>=0 )
{
ss += z;
z = s.get();
z = static_cast<tt_char>(s.get());
}
// we're leaving the last readed character
// we're leaving the last read character
// (it's not belonging to the value)
s.unget();

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
@ -506,8 +506,6 @@ namespace ttmath
#endif
TTMATH_LOG("UInt::AddVector")
return c;
}
@ -834,8 +832,6 @@ namespace ttmath
#endif
TTMATH_LOG("UInt::SubVector")
return c;
}

View File

@ -1,7 +1,7 @@
/*
* This file is a part of TTMath Bignum Library
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*