• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/Numeric.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #include <ctype.h>
00018 #include <stdio.h>
00019 
00020 #include <spl/types.h>
00021 
00022 #ifdef _WINDOWS
00023 #include <spl/configwin32.h>
00024 #else
00025 #include <spl/autoconf/config.h>
00026 #endif
00027 
00028 #ifdef HAVE_LIMITS_H
00029 #include <limits.h>
00030 #include <limits>
00031 #endif
00032 
00033 #include <spl/Char.h>
00034 #include <spl/Exception.h>
00035 #include <spl/Numeric.h>
00036 #include <spl/Double.h>
00037 #include <spl/IConvertable.h>
00038 #include <spl/Int32.h>
00039 #include <spl/Int64.h>
00040 #include <spl/math/Math.h>
00041 #include <spl/text/StringBuffer.h>
00042 #include <spl/UInt32.h>
00043 #include <spl/UInt64.h>
00044 
00045 char *int32toa( int32 i, char *buf, const int buflen )
00046 {
00047         int pos = 0;
00048         if ( 0 == i )
00049         {
00050                 buf[pos++] = '0';
00051         }
00052         else
00053         {
00054                 while ( i > 0 && pos < buflen-1 )
00055                 {
00056                         buf[pos++] = (char)((i % 10) + (int)'0');
00057                         i /= 10;
00058                 }
00059                 for ( i = 0; i < pos-1; i++ )
00060                 {
00061                         char ch = buf[i];
00062                         buf[i] = buf[pos-1-i];
00063                         buf[pos-1-i] = ch;
00064                 }
00065         }
00066         buf[pos] = '\0';
00067         return buf;
00068 }
00069 
00070 static char *int64toa( int64 i, char *buf, const int buflen )
00071 {
00072         int pos = 0;
00073         if ( 0 == i )
00074         {
00075                 buf[pos++] = '0';
00076         }
00077         else
00078         {
00079                 while ( i > 0 && pos < buflen-1 )
00080                 {
00081                         buf[pos++] = (char)((i % 10) + (int)'0');
00082                         i /= 10;
00083                 }
00084                 for ( i = 0; i < pos-1; i++ )
00085                 {
00086                         char ch = buf[i];
00087                         buf[i] = buf[pos-1-i];
00088                         buf[pos-1-i] = ch;
00089                 }
00090         }
00091         buf[pos] = '\0';
00092         return buf;
00093 }
00094 
00095 static bool isint( const char *cstr, const int len )
00096 {
00097         int x = 0;
00098         if ( cstr[0] == '-' || cstr[0] == '+' )
00099         {
00100                 x = 1;
00101         }
00102         for ( ; x < len; x++ )
00103         {
00104                 if ( ! isdigit( cstr[x] ) )
00105                 {
00106                         return false;
00107                 }
00108         }
00109         return true;
00110 }
00111 
00112 static const int base10 = 10;
00113 static char cHexa[] = { 'A', 'B', 'C', 'D', 'E', 'F' };
00114 static int iHexaNumeric[] = { 10, 11, 12, 13, 14, 15 };
00115 static int iHexaIndices[] = { 0, 1, 2, 3, 4, 5 };
00116 static const int asciiDiff = 48;
00117 
00118 static uint64 _baseToInt(const char *sbase, int numbase)
00119 {
00120         int i;
00121         uint64 dec = 0;
00122         int b;
00123         int iProduct = 1;
00124         int sbaselen = (int)strlen(sbase);
00125         int stopAt = 0;
00126         
00127         if ( sbase[0] == '0' && (sbase[1] == 'x' || sbase[1] == 'X') )
00128         {
00129                 stopAt = 2;
00130         }
00131 
00132         for ( i = sbaselen - 1; i >= stopAt; i--, iProduct *= numbase )
00133         {
00134                 char ch = sbase[i];
00135                 if ( numbase > base10 && isalpha(ch) )
00136                 {
00137                         ASSERT( 'A' > 'a' );
00138                         if ( ch >= 'A' )
00139                         {
00140                                 b = iHexaNumeric[ch-'A'];
00141                         }
00142                         else
00143                         {
00144                                 b = iHexaNumeric[ch-'a'];
00145                         }
00146                 }
00147                 else 
00148                 {
00149                         b = (int) sbase[i] - asciiDiff;
00150                 }
00151                 dec += (b * iProduct);
00152         } 
00153         return dec; 
00154 }
00155 
00156 static void FormatHex( byte b, char *buf )
00157 {
00158         int nibble = b & 0xF;
00159         if ( nibble > 9 )
00160         {
00161                 buf[1] = nibble - 10 + 'A';
00162         }
00163         else
00164         {
00165                 buf[1] = nibble + '0';
00166         }
00167         nibble = b >> 4;
00168         if ( nibble > 9 )
00169         {
00170                 buf[0] = nibble - 10 + 'A';
00171         }
00172         else
00173         {
00174                 buf[0] = nibble + '0';
00175         }
00176         buf[2] = '\0';
00177 }
00178 
00179 Numeric::Numeric()
00180 {
00181 }
00182 
00183 Numeric::~Numeric()
00184 {
00185 }
00186 
00187 bool Numeric::IsNumeric(const char *cp, const int cplen)
00188 {
00189         int x = 0;
00190         bool sawdot = false;
00191         bool sawe = false;
00192 
00193         if (cplen == 0)
00194         {
00195                 return false;
00196         }
00197         if ( cp[0] == '-' || cp[x] == '+' )
00198         {
00199                 x = 1;
00200         }
00201         for ( ; x < cplen && cp[x] != '\0'; x++ )
00202         {
00203                 if ( ! isdigit( cp[x] ) )
00204                 {
00205                         if ( cp[x] == '.' )
00206                         {
00207                                 if ( sawdot )
00208                                 {
00209                                         return false;
00210                                 }
00211                                 sawdot = true;
00212                         }
00213                         else if ( cp[x] == 'e' || cp[x] == 'E' )
00214                         {
00215                                 if ( sawe )
00216                                 {
00217                                         return false;
00218                                 }
00219                                 sawe = true;
00220                         }
00221                         else if ( cp[x] == '-' )
00222                         {
00223                                 if ( ! sawe )
00224                                 {
00225                                         return false;
00226                                 }
00227                                 if ( cp[x-1] != 'e' && cp[x] != 'E' )
00228                                 {
00229                                         return false;
00230                                 }
00231                         }
00232                         else
00233                         {
00234                                 return false;
00235                         }
00236                 }
00237         }
00238         if (sawdot && cplen == 1)
00239         {
00240                 return false;
00241         }
00242         return true;
00243 }
00244 
00245 Int32::~Int32()
00246 {
00247 }
00248 
00249 int32 Int32::HashCode() const
00250 {
00251         return Math::Hash(m_val);
00252 }
00253 
00254 bool Int32::Equals(const IComparable *a) const
00255 {
00256         if (a->MajicNumber() != MajicNumber())
00257         {
00258                 return false;
00259         }
00260         const Int32 *vp = static_cast<const Int32 *>(a);
00261         vp->ValidateMem();
00262         return m_val == vp->m_val;
00263 }
00264 
00265 int Int32::Compare(const IComparable *a) const
00266 {
00267         if (a->MajicNumber() != MajicNumber())
00268         {
00269                 return 1;
00270         }
00271         const Int32 *vp = static_cast<const Int32 *>(a);
00272         vp->ValidateMem();
00273         return m_val - vp->m_val;
00274 }
00275 
00276 bool Int32::Equals(const IComparable& a) const
00277 {
00278         if (a.MajicNumber() != MajicNumber())
00279         {
00280                 return false;
00281         }
00282         const Int32& vp = static_cast<const Int32&>(a);
00283         vp.ValidateMem();
00284         return m_val == vp.m_val;
00285 }
00286 
00287 int Int32::Compare(const IComparable& a) const
00288 {
00289         if (a.MajicNumber() != MajicNumber())
00290         {
00291                 return 1;
00292         }
00293         const Int32& vp = static_cast<const Int32&>(a);
00294         vp.ValidateMem();
00295         return m_val - vp.m_val;
00296 }
00297 
00298 int32 Int32::MajicNumber() const
00299 {
00300         return INT32_MAJIC;
00301 }
00302 
00303 int Int32::ToInt() const
00304 {
00305         return m_val;
00306 }
00307 
00308 double Int32::ToDouble() const
00309 {
00310         return (double)m_val;
00311 }
00312 
00313 StringPtr Int32::ToString() const
00314 {
00315         return ToString(m_val);
00316 }
00317 
00318 #ifdef DEBUG
00319 void Int32::ValidateMem() const
00320 {
00321 }
00322 
00323 void Int32::CheckMem() const
00324 {
00325 }
00326 #endif
00327 
00328 int32 Int32::Parse(const char *cp, const int cplen, int radix)
00329 {
00330         if (radix == 10)
00331         {
00332                 return atoi(cp);
00333         }
00334         return (int32)_baseToInt(cp, radix);
00335 }
00336 
00337 bool Int32::IsInt(const char *cp, const int cplen, int radix)
00338 {
00339         if (radix == 10)
00340         {
00341                 return isint(cp, cplen);
00342         }
00343         if (radix != 16)
00344         {
00345                 throw new InvalidArgumentException("Unsupported number base in Int32::IsInt().");
00346         }
00347         int pos = 0;
00348 
00349         if (cp[0] == '0' && (cp[1] == 'x' || cp[1] == 'X'))
00350         {
00351                 pos = 2;
00352         }
00353         char ch;
00354         for ( int x = pos; x < cplen && cp[x] != '\0'; x++ )
00355         {
00356                 ch = cp[x];
00357                 if (Char::IsDigit(ch))
00358                 {
00359                         continue;
00360                 }
00361                 if (!isalpha(ch))
00362                 {
00363                         return false;
00364                 }
00365                 if (!((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')))
00366                 {
00367                         return false;
00368                 }
00369         }
00370         return true;
00371 }
00372 
00373 StringPtr Int32::ToString(int32 i, int radix)
00374 {
00375         if (10 == radix)
00376         {
00377                 char buf[128];
00378                 bool neg = i < 0;
00379                 int bufpos = neg ? 1 : 0;
00380                 if (neg)
00381                 {
00382                         i *= -1;
00383                         buf[0] = '-';
00384                 }
00385 
00386                 int32toa(i, &buf[bufpos], 128);
00387 
00388                 return StringPtr(new String( buf ));
00389         }
00390         if (16 != radix)
00391         {
00392                 throw new InvalidArgumentException("Unsupported radix in Int32::IsInt().");
00393         }
00394 
00395         char buf[3];
00396         StringBuffer hex;
00397         FormatHex( ((byte *)&i)[3], &buf[0] );
00398         hex.Append(buf);
00399         FormatHex( ((byte *)&i)[2], &buf[0] );
00400         hex.Append(buf);
00401         FormatHex( ((byte *)&i)[1], &buf[0] );
00402         hex.Append(buf);
00403         FormatHex( ((byte *)&i)[0], &buf[0] );
00404         hex.Append(buf);
00405 
00406         return hex.ToString()->LTrim('0');
00407 }
00408 
00409 
00410 Int64::Int64()
00411 : m_val(0)
00412 {
00413 }
00414 
00415 Int64::Int64(const int64 i)
00416 : m_val(i)
00417 {
00418 }
00419 
00420 Int64::Int64(const Int64& i)
00421 : m_val(i.m_val)
00422 {
00423 }
00424 
00425 Int64::~Int64()
00426 {
00427 }
00428 
00429 int32 Int64::HashCode() const
00430 {
00431         return Math::Hash(m_val);
00432 }
00433 
00434 bool Int64::Equals(const IComparable *a) const
00435 {
00436         if (a->MajicNumber() != MajicNumber())
00437         {
00438                 return false;
00439         }
00440         const Int64 *vp = static_cast<const Int64 *>(a);
00441         vp->ValidateMem();
00442         return m_val == vp->m_val;
00443 }
00444 
00445 int Int64::Compare(const IComparable *a) const
00446 {
00447         if (a->MajicNumber() != MajicNumber())
00448         {
00449                 return 1;
00450         }
00451         const Int64 *vp = static_cast<const Int64 *>(a);
00452         vp->ValidateMem();
00453         return (int)(m_val - vp->m_val);
00454 }
00455 
00456 bool Int64::Equals(const IComparable& a) const
00457 {
00458         if (a.MajicNumber() != MajicNumber())
00459         {
00460                 return false;
00461         }
00462         const Int64& vp = static_cast<const Int64&>(a);
00463         vp.ValidateMem();
00464         return m_val == vp.m_val;
00465 }
00466 
00467 int Int64::Compare(const IComparable& a) const
00468 {
00469         if (a.MajicNumber() != MajicNumber())
00470         {
00471                 return 1;
00472         }
00473         const Int64& vp = static_cast<const Int64&>(a);
00474         vp.ValidateMem();
00475         return (int)(m_val - vp.m_val);
00476 }
00477 
00478 int32 Int64::MajicNumber() const
00479 {
00480         return INT64_MAJIC;
00481 }
00482 
00483 int Int64::ToInt() const
00484 {
00485         return (int)m_val;
00486 }
00487 
00488 double Int64::ToDouble() const
00489 {
00490         return (double)m_val;
00491 }
00492 
00493 StringPtr Int64::ToString() const
00494 {
00495         return ToString(m_val);
00496 }
00497 
00498 #ifdef DEBUG
00499 void Int64::ValidateMem() const
00500 {
00501 }
00502 
00503 void Int64::CheckMem() const
00504 {
00505 }
00506 #endif
00507 
00508 int64 Int64::Parse(const char *cp, const int cplen)
00509 {
00510         return atol(cp);
00511 }
00512 
00513 bool Int64::IsInt(const char *cp, const int cplen)
00514 {
00515         return isint(cp, cplen);
00516 }
00517 
00518 StringPtr Int64::ToString(int64 i, int radix)
00519 {
00520         if (10 == radix)
00521         {
00522                 char buf[128];
00523                 bool neg = i < 0;
00524                 int bufpos = neg ? 1 : 0;
00525                 if (neg)
00526                 {
00527                         i *= -1;
00528                         buf[0] = '-';
00529                 }
00530                 int64toa(i, &buf[bufpos], 128);
00531                 return StringPtr(new String( buf ));
00532         }
00533         if (16 != radix)
00534         {
00535                 throw new InvalidArgumentException("Unsupported radix in Int32::IsInt().");
00536         }
00537 
00538         char buf[3];
00539         StringBuffer hex;
00540         FormatHex( ((byte *)&i)[7], &buf[0] );
00541         hex.Append(buf);
00542         FormatHex( ((byte *)&i)[6], &buf[0] );
00543         hex.Append(buf);
00544         FormatHex( ((byte *)&i)[5], &buf[0] );
00545         hex.Append(buf);
00546         FormatHex( ((byte *)&i)[4], &buf[0] );
00547         hex.Append(buf);
00548         FormatHex( ((byte *)&i)[3], &buf[0] );
00549         hex.Append(buf);
00550         FormatHex( ((byte *)&i)[2], &buf[0] );
00551         hex.Append(buf);
00552         FormatHex( ((byte *)&i)[1], &buf[0] );
00553         hex.Append(buf);
00554         FormatHex( ((byte *)&i)[0], &buf[0] );
00555         hex.Append(buf);
00556 
00557         return hex.ToString()->LTrim('0');
00558 }
00559 
00560 
00561 UInt32::UInt32()
00562 : m_val(0)
00563 {
00564 }
00565 
00566 UInt32::UInt32(const uint32 i)
00567 : m_val(i)
00568 {
00569 }
00570 
00571 UInt32::UInt32(const UInt32& i)
00572 : m_val(i.m_val)
00573 {
00574 }
00575 
00576 UInt32::~UInt32()
00577 {
00578 }
00579 
00580 int32 UInt32::HashCode() const
00581 {
00582         return Math::Hash(m_val);
00583 }
00584 
00585 bool UInt32::Equals(const IComparable *a) const
00586 {
00587         if (a->MajicNumber() != MajicNumber())
00588         {
00589                 return false;
00590         }
00591         const UInt32 *vp = static_cast<const UInt32 *>(a);
00592         vp->ValidateMem();
00593         return m_val == vp->m_val;
00594 }
00595 
00596 int UInt32::Compare(const IComparable *a) const
00597 {
00598         if (a->MajicNumber() != MajicNumber())
00599         {
00600                 return 1;
00601         }
00602         const UInt32 *vp = static_cast<const UInt32 *>(a);
00603         vp->ValidateMem();
00604         return m_val - vp->m_val;
00605 }
00606 
00607 bool UInt32::Equals(const IComparable& a) const
00608 {
00609         if (a.MajicNumber() != MajicNumber())
00610         {
00611                 return false;
00612         }
00613         const UInt32& vp = static_cast<const UInt32&>(a);
00614         vp.ValidateMem();
00615         return m_val == vp.m_val;
00616 }
00617 
00618 int UInt32::Compare(const IComparable& a) const
00619 {
00620         if (a.MajicNumber() != MajicNumber())
00621         {
00622                 return 1;
00623         }
00624         const UInt32& vp = static_cast<const UInt32&>(a);
00625         vp.ValidateMem();
00626         return m_val - vp.m_val;
00627 }
00628 
00629 int32 UInt32::MajicNumber() const
00630 {
00631         return UINT32_MAJIC;
00632 }
00633 
00634 int UInt32::ToInt() const
00635 {
00636         return (int)m_val;
00637 }
00638 
00639 double UInt32::ToDouble() const
00640 {
00641         return (double)m_val;
00642 }
00643 
00644 StringPtr UInt32::ToString() const
00645 {
00646         return ToString(m_val);
00647 }
00648 
00649 #ifdef DEBUG
00650 void UInt32::ValidateMem() const
00651 {
00652 }
00653 
00654 void UInt32::CheckMem() const
00655 {
00656 }
00657 #endif
00658 
00659 uint32 UInt32::Parse(const char *cp, const int cplen, int radix)
00660 {
00661         if (radix == 10)
00662         {
00663                 return atoi(cp);
00664         }
00665         return (uint32)_baseToInt(cp, radix);
00666 }
00667 
00668 StringPtr UInt32::ToString(uint32 i, int radix)
00669 {
00670         return Int64::ToString((int64)i, radix);
00671 }
00672 
00673 
00674 UInt64::UInt64()
00675 : m_val(0)
00676 {
00677 }
00678 
00679 UInt64::UInt64(const uint64 i)
00680 : m_val(i)
00681 {
00682 }
00683 
00684 UInt64::UInt64(const UInt64& i)
00685 : m_val(i.m_val)
00686 {
00687 }
00688 
00689 UInt64::~UInt64()
00690 {
00691 }
00692 
00693 int32 UInt64::HashCode() const
00694 {
00695         return Math::Hash(m_val);
00696 }
00697 
00698 bool UInt64::Equals(const IComparable *a) const
00699 {
00700         if (a->MajicNumber() != MajicNumber())
00701         {
00702                 return false;
00703         }
00704         const UInt64 *vp = static_cast<const UInt64 *>(a);
00705         vp->ValidateMem();
00706         return m_val == vp->m_val;
00707 }
00708 
00709 int UInt64::Compare(const IComparable *a) const
00710 {
00711         if (a->MajicNumber() != MajicNumber())
00712         {
00713                 return 1;
00714         }
00715         const UInt64 *vp = static_cast<const UInt64 *>(a);
00716         vp->ValidateMem();
00717         return (int)(m_val - vp->m_val);
00718 }
00719 
00720 bool UInt64::Equals(const IComparable& a) const
00721 {
00722         if (a.MajicNumber() != MajicNumber())
00723         {
00724                 return false;
00725         }
00726         const UInt64& vp = static_cast<const UInt64&>(a);
00727         vp.ValidateMem();
00728         return m_val == vp.m_val;
00729 }
00730 
00731 int UInt64::Compare(const IComparable& a) const
00732 {
00733         if (a.MajicNumber() != MajicNumber())
00734         {
00735                 return 1;
00736         }
00737         const UInt64& vp = static_cast<const UInt64&>(a);
00738         vp.ValidateMem();
00739         return (int)(m_val - vp.m_val);
00740 }
00741 
00742 int32 UInt64::MajicNumber() const
00743 {
00744         return UINT64_MAJIC;
00745 }
00746 
00747 int UInt64::ToInt() const
00748 {
00749         return (int)m_val;
00750 }
00751 
00752 double UInt64::ToDouble() const
00753 {
00754         return (double)(int64)m_val;
00755 }
00756 
00757 StringPtr UInt64::ToString() const
00758 {
00759         return ToString(m_val);
00760 }
00761 
00762 #ifdef DEBUG
00763 void UInt64::ValidateMem() const
00764 {
00765 }
00766 
00767 void UInt64::CheckMem() const
00768 {
00769 }
00770 #endif
00771 
00772 uint64 UInt64::Parse(const char *cp, const int cplen, int radix)
00773 {
00774         if (radix == 10)
00775         {
00776                 return atoi(cp);
00777         }
00778         return _baseToInt(cp, radix);
00779 }
00780 
00781 StringPtr UInt64::ToString(uint64 i, int radix)
00782 {
00783         return Int64::ToString((int64)i, radix);
00784 }
00785 
00786 
00787 Double::Double()
00788 : m_val(0)
00789 {
00790 }
00791 
00792 Double::Double(const double d)
00793 : m_val(d)
00794 {
00795 }
00796 
00797 Double::Double(const Double& d)
00798 : m_val(d.m_val)
00799 {
00800 }
00801 
00802 Double::~Double()
00803 {
00804 }
00805 
00806 int32 Double::HashCode() const
00807 {
00808         return Math::Hash(m_val);
00809 }
00810 
00811 bool Double::Equals(const IComparable *a) const
00812 {
00813         if (a->MajicNumber() != MajicNumber())
00814         {
00815                 return false;
00816         }
00817         const Double *vp = static_cast<const Double *>(a);
00818         vp->ValidateMem();
00819         return m_val == vp->m_val;
00820 }
00821 
00822 int Double::Compare(const IComparable *a) const
00823 {
00824         if (a->MajicNumber() != MajicNumber())
00825         {
00826                 return 1;
00827         }
00828         const Double *vp = static_cast<const Double *>(a);
00829         vp->ValidateMem();
00830         return (int)(m_val - vp->m_val);
00831 }
00832 
00833 bool Double::Equals(const IComparable& a) const
00834 {
00835         if (a.MajicNumber() != MajicNumber())
00836         {
00837                 return false;
00838         }
00839         const Double& vp = static_cast<const Double&>(a);
00840         vp.ValidateMem();
00841         return m_val == vp.m_val;
00842 }
00843 
00844 int Double::Compare(const IComparable& a) const
00845 {
00846         if (a.MajicNumber() != MajicNumber())
00847         {
00848                 return 1;
00849         }
00850         const Double& vp = static_cast<const Double&>(a);
00851         vp.ValidateMem();
00852         return (int)(m_val - vp.m_val);
00853 }
00854 
00855 int32 Double::MajicNumber() const
00856 {
00857         return DOUBLE_MAJIC;
00858 }
00859 
00860 int Double::ToInt() const
00861 {
00862         return (int)m_val;
00863 }
00864 
00865 double Double::ToDouble() const
00866 {
00867         return (double)m_val;
00868 }
00869 
00870 StringPtr Double::ToString() const
00871 {
00872         return ToString(m_val);
00873 }
00874 
00875 bool Double::IsNaN(double d)
00876 {
00877         return std::numeric_limits<double>::quiet_NaN() == d;
00878 }
00879 
00880 bool Double::IsPositiveZero(double d)
00881 {
00882         return d == 0.0;
00883 }
00884 
00885 bool Double::IsNegativeZero(double d)
00886 {
00887         return d == -0.0;
00888 }
00889 
00890 double Double::PositiveInfinity()
00891 {
00892         return HUGE_VAL;
00893 }
00894 
00895 double Double::NegativeInfinity()
00896 {
00897         return -HUGE_VAL;
00898 }
00899 
00900 #ifdef DEBUG
00901 void Double::ValidateMem() const
00902 {
00903 }
00904 
00905 void Double::CheckMem() const
00906 {
00907 }
00908 #endif
00909 
00910 float64 Double::Parse(const char *cp, const int cplen)
00911 {
00912         return atof(cp);
00913 }
00914 
00915 bool Double::IsDouble(const char *cp, const int cplen)
00916 {
00917         return Numeric::IsNumeric(cp, cplen);
00918 }
00919 
00920 StringPtr Double::ToString(float64 d)
00921 {
00922         char buf[256];
00923         sprintf(buf, "%f", d);
00924         StringPtr ret = String( buf ).RTrim('0');
00925         if (ret->EndsWith('.'))
00926         {
00927                 return ret->Substring(0, ret->Length()-1);
00928         }
00929         return ret;
00930 }
00931 
00932 Char::Char()
00933 : m_val(0)
00934 {
00935 }
00936 
00937 Char::Char(const Char& i)
00938 : m_val(i.m_val)
00939 {
00940 }
00941 
00942 Char::Char(const int i)
00943 : m_val(i)
00944 {
00945 }
00946 
00947 Char::~Char()
00948 {
00949 }
00950 
00951 bool Char::IsWhiteSpace(const int32 c)
00952 {
00953         switch(c)
00954         {
00955         case 0x0020:
00956         case 0x1680:
00957         case 0x180E:
00958         case 0x2000:
00959         case 0x2001:
00960         case 0x2002:
00961         case 0x2003:
00962         case 0x2004:
00963         case 0x2005:
00964         case 0x2006:
00965         case 0x2007:
00966         case 0x2008:
00967         case 0x2009:
00968         case 0x200A:
00969         case 0x202F:
00970         case 0x205F:
00971         case 0x3000:
00972         case 0x2028:
00973         case 0x2029:
00974         case 0x0009:
00975         case 0x000A:
00976         case 0x000B:
00977         case 0x000C:
00978         case 0x000D:
00979         case 0x0085:
00980         case 0x0000A0:
00981                 return true;
00982         }
00983         return false;
00984 }
00985 
00986 int32 Char::HashCode() const
00987 {
00988         if (m_val < 256)
00989         {
00990                 return Math::Hash((char)m_val);
00991         }
00992         return Math::Hash(m_val);
00993 }
00994 
00995 bool Char::Equals(const IComparable *a) const
00996 {
00997         if (a->MajicNumber() != MajicNumber())
00998         {
00999                 return false;
01000         }
01001         const Char *c = static_cast<const Char *>(a);
01002         return m_val == c->m_val;
01003 }
01004 
01005 int Char::Compare(const IComparable *a) const
01006 {
01007         if (a->MajicNumber() != MajicNumber())
01008         {
01009                 return 1;
01010         }
01011         const Char *c = static_cast<const Char *>(a);
01012         return m_val - c->m_val;
01013 }
01014 
01015 bool Char::Equals(const IComparable& a) const
01016 {
01017         if (a.MajicNumber() != MajicNumber())
01018         {
01019                 return false;
01020         }
01021         const Char& c = static_cast<const Char&>(a);
01022         return m_val == c.m_val;
01023 }
01024 
01025 int Char::Compare(const IComparable& a) const
01026 {
01027         if (a.MajicNumber() != MajicNumber())
01028         {
01029                 return 1;
01030         }
01031         const Char& c = static_cast<const Char&>(a);
01032         return m_val - c.m_val;
01033 }
01034 
01035 int32 Char::MajicNumber() const
01036 {
01037         return CHAR_MAJIC;
01038 }
01039 
01040 int Char::ToInt() const
01041 {
01042         return m_val;
01043 }
01044 
01045 double Char::ToDouble() const
01046 {
01047         return (double)m_val;
01048 }
01049 
01050 StringPtr Char::ToString() const
01051 {
01052         return Char::ToString(m_val);
01053 }
01054 
01055 StringPtr Char::ToString(char c)
01056 {
01057         return Char::ToString((int32)c);
01058 }
01059 
01060 StringPtr Char::ToString(int32 c)
01061 {
01062         char buf[5];
01063         buf[0] = 0xFF & c;
01064         if (c < 256)
01065         {
01066                 buf[1] = '\0';
01067         }
01068         else
01069         {
01070                 buf[1] = 0xFF & (c >> 8);
01071                 buf[2] = 0xFF & (c >> 16);
01072                 buf[3] = 0xFF & (c >> 24);
01073                 buf[4] = '\0';
01074         }
01075         return StringPtr(new String(buf));
01076 }
01077 
01078 #ifdef DEBUG
01079 void Char::ValidateMem() const
01080 {
01081 }
01082 
01083 void Char::CheckMem() const
01084 {
01085 }
01086 #endif
01087 
01088 IConvertable::IConvertable()
01089 {
01090 }
01091 
01092 IConvertable::~IConvertable()
01093 {
01094 }