00001 #ifndef SimTK_SimTKCOMMON_STRING_H_
00002 #define SimTK_SimTKCOMMON_STRING_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifdef _MSC_VER
00037 #pragma warning(disable:4996)
00038 #endif
00039
00040
00041 #include "SimTKcommon/internal/common.h"
00042
00043 #include <cstdio>
00044 #include <string>
00045 #include <limits>
00046 #include <complex>
00047 #include <sstream>
00048
00049 namespace SimTK {
00050
00066 class String : public std::string {
00067 public:
00068
00070 String() { }
00071
00072
00073
00075 String(const char* s) : std::string(s) { }
00076
00078 explicit String(char c) {push_back(c);}
00079
00081 String(const std::string& s) : std::string(s) { }
00082
00085 String(const String& s, int start, int len) : std::string(s,start,len) { }
00086
00089 operator const char*() const { return c_str(); }
00090
00092 char& operator[](int i) {
00093 assert(i >= 0);
00094 return std::string::operator[]((std::string::size_type)i);
00095 }
00096
00098 char operator[](int i) const {
00099 assert(i >= 0);
00100 return std::string::operator[]((std::string::size_type)i);
00101 }
00102
00104 char& operator[](std::string::size_type i) {return std::string::operator[](i);}
00106 char operator[](std::string::size_type i) const {return std::string::operator[](i);}
00107
00110 int size() const {return (int)std::string::size();}
00111
00114 int length() const {return (int)std::string::length();}
00115
00120 explicit String(int i) { char buf[32]; sprintf(buf,"%d",i); (*this)=buf; }
00122 explicit String(long i) { char buf[32]; sprintf(buf,"%ld",i); (*this)=buf; }
00124 explicit String(long long i) { char buf[64]; sprintf(buf,"%lld",i); (*this)=buf; }
00126 explicit String(unsigned int s) { char buf[32]; sprintf(buf,"%u",s); (*this)=buf; }
00128 explicit String(unsigned long s) { char buf[32]; sprintf(buf,"%lu",s); (*this)=buf; }
00130 explicit String(unsigned long long s) { char buf[64]; sprintf(buf,"%llu",s); (*this)=buf; }
00132 explicit String(float r) { char buf[64]; sprintf(buf,"%.8g",r); (*this)=buf; }
00134 explicit String(double r) { char buf[64]; sprintf(buf,"%.16g",r); (*this)=buf; }
00136 explicit String(long double r) { char buf[64]; sprintf(buf,"%.20Lg",r); (*this)=buf; }
00138 explicit String(std::complex<float> r)
00139 { char buf[128]; sprintf(buf,"(%.8g,%.8g)",r.real(),r.imag()); (*this)=buf; }
00141 explicit String(std::complex<double> r)
00142 { char buf[128]; sprintf(buf,"(%.16g,%.16g)",r.real(),r.imag()); (*this)=buf; }
00144 explicit String(std::complex<long double> r)
00145 { char buf[128]; sprintf(buf,"(%.20Lg,%.20Lg)",r.real(),r.imag()); (*this)=buf; }
00148 explicit String(bool b) : std::string(b?"true":"false") { }
00152 template <class T> inline explicit String(const T& t);
00185 template <class T> inline bool tryConvertTo(T& out) const;
00186
00193 template <class T> inline void convertTo(T& out) const;
00194
00201 template <class T> T convertTo() const
00202 { T temp; convertTo<T>(temp); return temp; }
00203
00216 SimTK_SimTKCOMMON_EXPORT String& toUpper();
00219 SimTK_SimTKCOMMON_EXPORT String& toLower();
00223 SimTK_SimTKCOMMON_EXPORT String& trimWhiteSpace();
00226 SimTK_SimTKCOMMON_EXPORT String& replaceAllChar(char oldChar, char newChar);
00237 static const String& getAs(const std::string& s)
00238 { return reinterpret_cast<const String&>(s); }
00242 static String& updAs(std::string& s)
00243 { return reinterpret_cast<String&>(s); }
00246 static String toUpper(const std::string& in)
00247 { return String(in).toUpper(); }
00250 static String toLower(const std::string& in)
00251 { return String(in).toLower(); }
00256 static SimTK_SimTKCOMMON_EXPORT String trimWhiteSpace(const std::string& in);
00259 String& replaceAllChar(const std::string& in, char oldChar, char newChar)
00260 { return String(in).replaceAllChar(oldChar, newChar); }
00263 };
00264
00265
00266
00267
00268
00269
00270 template <class T> inline
00271 String::String(const T& t) {
00272 std::ostringstream stream;
00273 stream << t;
00274 *this = stream.str();
00275 }
00276
00277
00278
00279
00280
00281 template <class T> inline static
00282 bool tryConvertStringTo(const String& value, T& out) {
00283 std::istringstream sstream(value);
00284 sstream >> out; if (sstream.fail()) return false;
00285 if (sstream.eof()) return true;
00286
00287
00288 std::ws(sstream);
00289 return sstream.eof();
00290 }
00291
00292
00293
00294
00295
00296 template<> inline static
00297 bool tryConvertStringTo(const String& value, String& out)
00298 { out = value; return true; }
00299
00300
00301 template<> inline static
00302 bool tryConvertStringTo(const String& value, std::string& out)
00303 { out = value; return true; }
00304
00305
00306
00307 template<class T> inline static
00308 bool tryConvertStringTo(const String& value, T*& out) {
00309 SimTK_ERRCHK1_ALWAYS(false, "SimTK::convertStringTo(value,T*)",
00310 "Can't interpret a string as a pointer (%s*).",
00311 NiceTypeName<T>::name());
00312 return false;
00313 }
00314
00315 template <class T> inline bool
00316 String::tryConvertTo(T& out) const
00317 { return tryConvertStringTo(*this, out); }
00318
00319 template <class T> inline void
00320 String::convertTo(T& out) const {
00321 const int MaxStr = 50;
00322 const bool convertOK = tryConvertTo<T>(out);
00323 if (convertOK) return;
00324
00325
00326
00327 String shorter = this->substr(0, MaxStr);
00328 if (shorter.size() < this->size()) shorter += " ...";
00329 SimTK_ERRCHK2_ALWAYS(convertOK, "Xml::getAs()",
00330 "Couldn't interpret string '%s' as type T=%s.",
00331 shorter.c_str(), NiceTypeName<T>::name());
00332 }
00333
00345 template <class T> inline static
00346 void convertStringTo(const String& in, T& out)
00347 { in.convertTo<T>(out); }
00348
00359 template <class T> inline static
00360 T convertStringTo(const String& in)
00361 { return in.convertTo<T>(); }
00362
00363 }
00364 #endif // SimTK_SimTKCOMMON_STRING_H_