00001 /* Copyright (C) 2001 Stefan Buehler <sbuehler@uni-bremen.de> 00002 00003 This program is free software; you can redistribute it and/or modify it 00004 under the terms of the GNU General Public License as published by the 00005 Free Software Foundation; either version 2, or (at your option) any 00006 later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00016 USA. */ 00017 00027 #ifndef string_h 00028 #define string_h 00029 00030 #include <string> 00031 #include <climits> 00032 #include <iostream> 00033 #include "arts.h" 00034 00035 // String stream library. This is included with the ARTS source code 00036 // for now, because it is missing in gcc <= 2.95.2 00037 #ifdef HAVE_SSTREAM 00038 #include <sstream> 00039 #else 00040 #include "sstream.h" 00041 #endif 00042 00059 template<class charT> 00060 class my_basic_string : public std::basic_string<charT> 00061 { 00062 public: 00063 // Constructors: 00064 my_basic_string(); 00065 explicit my_basic_string(Index n, char c=' '); 00066 my_basic_string(const basic_string<charT>& A, 00067 Index pos=0, 00068 Index npos=my_basic_string<charT>::npos); 00069 my_basic_string(const char A[]); 00070 00071 // Assignment operators: 00072 my_basic_string& operator=(const my_basic_string<charT>& A); 00073 // my_basic_string& operator=(const char A[]); 00074 00075 // Number of elements: 00076 Index nelem() const; 00077 00078 // Find functions: 00079 // Index find(char c); 00080 // Index find(const my_basic_string<charT>& c); 00081 00082 // Index operators: 00083 const char operator[](Index n) const; 00084 char& operator[](Index n); 00085 00087 static const Index npos = static_cast<Index>(std::basic_string<charT>::npos); 00088 }; 00089 00090 00091 // Member functions for my_basic_string: 00092 00093 00094 // Constructors: 00095 00097 template<class charT> 00098 inline my_basic_string<charT>::my_basic_string() : std::basic_string<charT>() 00099 { /* Nothing to do here. */ }; 00100 00108 template<class charT> 00109 inline my_basic_string<charT>::my_basic_string(Index n, char c) : 00110 std::basic_string<charT>(n,c) 00111 { /* Nothing to do here. */ }; 00112 00114 // template<class charT> 00115 // inline my_basic_string<charT>::my_basic_string(const my_basic_string& A) : std::basic_string<charT>(A) 00116 // { /* Nothing to do here. */ }; 00117 00130 template<class charT> 00131 inline my_basic_string<charT>::my_basic_string(const basic_string<charT>& A, 00132 Index pos, 00133 Index npos) 00134 { 00135 // Range checks: 00136 assert(0<=pos); // Start index must be 0 or greater 0. 00137 00138 // cout << "A = " << A << "\n"; 00139 // cout << "pos = " << pos << "\n"; 00140 // cout << "size = " << A.size() << "\n"; 00141 00142 assert(static_cast<typename std::basic_string<charT>::size_type>(pos)<A.size()); 00143 // At most the last element of the original string. 00144 00145 assert( npos==my_basic_string<charT>::npos || 00146 ( (npos >= 0) && 00147 (static_cast<typename std::basic_string<charT>::size_type>(npos)<=(A.size()-pos)) 00148 ) 00149 ); // Number of characters to copy must be at the most the 00150 // number left. -1 means all remaining characters. 00151 00152 // The assertions look complicated, because we have to cast pos and 00153 // npos to the unsigned size type of basic string to avoid warning 00154 // messages from the compiler. Both casts are save, because previous 00155 // assertions check that pos and npos are positive. (The allowed 00156 // case npos -1 (=my_basic_string<charT>::npos) is also handled 00157 // correctly.) 00158 00159 std::basic_string<charT>::operator=(std::basic_string<charT>(A,pos,npos)); 00160 00161 }; 00162 00164 template<class charT> 00165 inline my_basic_string<charT>::my_basic_string(const char A[]) : std::basic_string<charT>(A) 00166 { /* Nothing to do here. */ }; 00167 00168 00176 template<class charT> 00177 inline my_basic_string<charT>& my_basic_string<charT>::operator=(const my_basic_string<charT>& A) 00178 { 00179 std::basic_string<charT>::operator=(A); 00180 return *this; 00181 } 00182 00184 template<class charT> 00185 inline Index my_basic_string<charT>::nelem() const 00186 { 00187 size_t s = this->size(); 00188 assert(s<LONG_MAX); 00189 return static_cast<long>(s); 00190 } 00191 00192 // /** Find function for char. 00193 00194 // \param c What character to find. 00195 // \return Position of c, or npos if not found. 00196 00197 // Unfortunately, the std::basid_string.find() functions returns npos 00198 // when the character is not found. This is -1, but assigned to a 00199 // positive type! Gives a very high number. If you add 1 to this 00200 // number you get zero again, so it does indeed bahave like -1 in a 00201 // way. Yuck! With Index this does not work. */ 00202 // template<class charT> 00203 // inline Index my_basic_string<charT>::find(char c) 00204 // { 00205 // std::basic_string<charT>::size_type i = std::basic_string<charT>::find(c); 00206 // if ( i == std::basic_string<charT>::npos ) 00207 // return npos; 00208 // else 00209 // return static_cast<Index>(i); 00210 // } 00211 00212 // /** Find function for string. 00213 00214 // \param c What string to find. 00215 // \return Position of c, or npos if not found. 00216 00217 // Unfortunately, the std::basid_string.find() functions returns npos 00218 // when the character is not found. This is -1, but assigned to a 00219 // positive type! Gives a very high number. If you add 1 to this 00220 // number you get zero again, so it does indeed bahave like -1 in a 00221 // way. Yuck! With Index this does not work. */ 00222 // template<class charT> 00223 // inline Index my_basic_string<charT>::find(const my_basic_string<charT>& c) 00224 // { 00225 // std::basic_string<charT>::size_type i = std::basic_string<charT>::find(c); 00226 // if ( i == std::basic_string<charT>::npos ) 00227 // return npos; 00228 // else 00229 // return static_cast<Index>(i); 00230 // } 00231 00232 00235 template<class charT> 00236 inline const char my_basic_string<charT>::operator[](Index n) const 00237 { 00238 assert(0<=n); 00239 assert(n<nelem()); 00240 return std::basic_string<charT>::operator[](n); 00241 } 00242 00245 template<class charT> 00246 inline char& my_basic_string<charT>::operator[](Index n) 00247 { 00248 assert(0<=n); 00249 assert(n<nelem()); 00250 return std::basic_string<charT>::operator[](n); 00251 } 00252 00253 // Non-member functions: 00254 00255 // /** Output operator. */ 00256 // inline std::ostream& operator<<(std::ostream& os, const my_basic_string& v) 00257 // { 00258 // my_basic_string<base>::const_iterator i = v.begin(); 00259 // const my_basic_string<base>::const_iterator end = v.end(); 00260 00261 // if ( i!=end ) 00262 // { 00263 // os << *i; 00264 // ++i; 00265 // } 00266 00267 // for ( ; i!=end; ++i ) 00268 // { 00269 // os << "\n" << setw(3) << *i; 00270 // } 00271 00272 00273 // // Just use the operator of std::string. 00274 // operator<<(os,v); 00275 // return os; 00276 // } 00277 00278 00281 typedef my_basic_string<char> String; 00282 00283 // Declare the existance of class Array: 00284 template<class base> 00285 class Array; 00286 00288 typedef Array<String> ArrayOfString; 00289 00290 00291 #endif // string_h