00001 #ifndef H_XSTRING
00002 #define H_XSTRING
00003
00004 template<class E, class T=std::char_traits<E>, class A=std::allocator<E> >
00005 class basic_xstring : public std::basic_string<E,T,A>
00006 {
00007 typedef E value_type;
00008 typedef A allocator_type;
00009 typedef std::basic_string<E,T,A> parent;
00010 typedef basic_string<E,T,A> self;
00011 typedef typename parent::size_type size_type;
00012 public:
00013 basic_xstring(const value_type* ptr, size_type n, const allocator_type& al = allocator_type())
00014 : parent(ptr,n,al) {}
00015 basic_xstring(const value_type* ptr, const allocator_type& al = allocator_type())
00016 : parent(ptr,al) {}
00017 basic_xstring(const basic_xstring& s, size_type off = 0, size_type n = npos, const allocator_type& al = allocator_type())
00018 : parent(s,off,n,al) {}
00019 basic_xstring(size_type n, value_type c, const allocator_type& al = allocator_type())
00020 : parent(n,c,al) {}
00021 explicit basic_xstring(const allocator_type& al = allocator_type())
00022 : parent(al) {}
00023 basic_xstring(const parent& p) : parent(p) {}
00024 template<class U>
00025 explicit basic_xstring(const U& u)
00026 {
00027 std::basic_ostringstream<E,T,A> os;
00028 os << u;
00029 *this=os.str();
00030 }
00031
00032 operator const value_type* () { return c_str(); }
00033 int as_int() const
00034 {
00035 return atoi(c_str());
00036 }
00037
00038 double as_double() const
00039 {
00040 return atof(c_str());
00041 }
00042
00043 void trim_left()
00044 {
00045 int p=find_first_not_of(" \t\n\r");
00046 if (p>0) *this=substr(p);
00047 }
00048
00049 void trim_right()
00050 {
00051 int p=find_last_not_of(" \t\n\r");
00052 if (p>=0)
00053 *this=substr(0,p+1);
00054 }
00055
00056 void trim()
00057 {
00058 trim_left();
00059 trim_right();
00060 }
00061
00062 bool read_line(std::istream& is)
00063 {
00064 *this="";
00065 if (is.eof()) return false;
00066 char buffer[1024];
00067 while (true)
00068 {
00069 is.getline(buffer,1000);
00070 if (is.eof()) return !empty();
00071 xstring s=buffer;
00072 *this+=s;
00073 if (s.length()<1000) return !empty();
00074 }
00075 }
00076 };
00077
00078 template<class T>
00079 class basic_string_tokenizer
00080 {
00081 typedef basic_xstring<T> str;
00082 typedef std::vector<str> seq;
00083 seq m_Tokens;
00084 unsigned m_Current;
00085 public:
00086 basic_string_tokenizer(const str& s, const str& delim=" \t")
00087 : m_Current(0)
00088 {
00089 int p=-1;
00090 int len=s.length();
00091 while (true)
00092 {
00093 p=s.find_first_not_of(delim,p+1);
00094 if (p<0) break;
00095 int e=s.find_first_of(delim,p+1);
00096 if (e<0) e=len;
00097 m_Tokens.push_back(s.substr(p,e-p));
00098 p=e;
00099 }
00100 }
00101
00102 unsigned size() const { return m_Tokens.size(); }
00103 bool has_more_tokens() const { return m_Current<m_Tokens.size(); }
00104 str get_next_token() { return m_Tokens[m_Current++]; }
00105 };
00106
00107 typedef basic_xstring<char> xstring;
00108 typedef basic_string_tokenizer<char> xstring_tokenizer;
00109
00110 inline void make_lower(xstring& s)
00111 {
00112 xstring::iterator b=s.begin(),e=s.end();
00113 for(;b!=e;++b)
00114 {
00115 char& c=*b;
00116 if (c>='A' && c<='Z') c+=32;
00117 }
00118 }
00119
00120
00121 #endif // H_XSTRING
00122