00001 /* 00002 * Number.cc 00003 * 00004 * Smalltalk like class library for C++ 00005 * Abstract number. 00006 * 00007 * Copyright (c) 2003, 2004 Milan Cermak, Martin Dvorak 00008 */ 00009 /* 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 */ 00024 #include <stdlib.h> 00025 #include <stlib/Number.h> 00026 00027 #include <stlib/Character.h> 00028 #include <stlib/Integer.h> 00029 #include <stlib/Locale.h> 00030 #include <stlib/Real.h> 00031 #include <stlib/String.h> 00032 #include <stlib/Visitor.h> 00033 00034 using namespace Core; 00035 00036 /* Class-accessing protocol */ 00037 String* Number::className(void) const 00038 { 00039 return new String("Number"); 00040 } 00041 00042 /* Instance creation protocol */ 00043 Number *Number::fromString(String *str) 00044 { 00045 return fromStringRadix(str, 0); 00046 } 00047 00048 Number *Number::fromStringRadix(String *str, int radix) 00049 { 00050 char *string = str->asCString(); 00051 char *end; 00052 long long integer; 00053 00054 integer = strtoll(string, &end, radix); 00055 if (end[0] == '.' || Locale::current()->decimalPoint()->isEqual(end[0])) { 00056 double real; 00057 end[0] = Locale::current()->decimalPoint()->asInteger(); 00058 real = strtod(string, NULL); 00059 return Real::value(real); 00060 } else { 00061 return Integer::value(integer); 00062 } 00063 } 00064 00065 /* Comparing protocol */ 00066 bool Number::isEqual(int arg) const 00067 { 00068 return this->isEqualToLongLong(arg); 00069 } 00070 00071 bool Number::isEqual(double arg) const 00072 { 00073 return this->isEqualToDouble(arg); 00074 } 00075 00076 /* Converting protocol */ 00077 Number::operator long(void) const 00078 { 00079 return asLong(); 00080 } 00081 00082 long Number::asLong(void) const 00083 { 00084 return (long) asLongLong(); 00085 } 00086 00087 Number::operator unsigned long(void) const 00088 { 00089 return asUnsignedLong(); 00090 } 00091 00092 unsigned long Number::asUnsignedLong(void) const 00093 { 00094 return (unsigned long) asLongLong(); 00095 } 00096 00097 Number::operator long long(void) const 00098 { 00099 return asLongLong(); 00100 } 00101 00102 Number::operator double(void) const 00103 { 00104 return asDouble(); 00105 } 00106 00107 /* Testing protocol */ 00108 bool Number::isInteger(void) const 00109 { 00110 return false; 00111 } 00112 00113 bool Number::isNegative(void) const 00114 { 00115 return !isPositive(); 00116 } 00117 00118 bool Number::isNumber(void) const 00119 { 00120 return true; 00121 } 00122 00123 bool Number::isReal(void) const 00124 { 00125 return false; 00126 } 00127 00128 /* Visiting protocol */ 00129 void Number::visitBy(Visitor *visitor) 00130 { 00131 visitor->visitNumber(this); 00132 }