Claw  1.7.3
impl/string_algorithm.tpp
Go to the documentation of this file.
00001 /*
00002   CLAW - a C++ Library Absolutely Wonderful
00003 
00004   CLAW is a free library without any particular aim but being useful to 
00005   anyone.
00006 
00007   Copyright (C) 2005-2011 Julien Jorge
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023   contact: julien.jorge@gamned.org
00024 */
00031 #include <claw/algorithm.hpp>
00032 #include <claw/glob.hpp>
00033 
00034 #include <sstream>
00035 #include <string>
00036 #include <iterator>
00037 
00038 /*----------------------------------------------------------------------------*/
00045 template<typename StreamType, typename StringType>
00046 StreamType& claw::text::getline( StreamType& is, StringType& str )
00047 {
00048   std::getline( is, str );
00049 
00050   if ( !str.empty() )
00051     if ( str[ str.size() - 1 ] == typename StringType::value_type('\r') )
00052       str.erase( str.size() - 1 );
00053 
00054   return is;
00055 } // getline()
00056 
00057 /*----------------------------------------------------------------------------*/
00063 template<typename StringType>
00064 void claw::text::trim_left( StringType& str,
00065                             const typename StringType::value_type* const s )
00066 {
00067   typename StringType::size_type p = str.find_first_not_of(s);
00068 
00069   if (p != StringType::npos)
00070     str = str.substr(p);
00071 } // trim_left()
00072 
00073 /*----------------------------------------------------------------------------*/
00079 template<typename StringType>
00080 void claw::text::trim_right( StringType& str,
00081                              const typename StringType::value_type* const s )
00082 {
00083   typename StringType::size_type p = str.find_last_not_of(s);
00084 
00085   if (p != StringType::npos)
00086     str = str.substr( 0, p+1 );
00087 } // trim_right()
00088 
00089 /*----------------------------------------------------------------------------*/
00095 template<typename StringType>
00096 void claw::text::trim( StringType& str,
00097                        const typename StringType::value_type* const s )
00098 {
00099   typename StringType::size_type first = str.find_first_not_of(s);
00100   typename StringType::size_type last  = str.find_last_not_of(s);
00101 
00102   if (first != StringType::npos)
00103     str = str.substr( first, last - first + 1 );
00104 } // trim()
00105 
00106 /*----------------------------------------------------------------------------*/
00119 template<typename StringType>
00120 void claw::text::squeeze( StringType& str,
00121                           const typename StringType::value_type* const s )
00122 {
00123   typedef typename StringType::size_type size_type;
00124 
00125   size_type first(0);
00126 
00127   do
00128     {
00129       first = str.find_first_of(s, first);
00130 
00131       if ( first != StringType::npos )
00132         {
00133           size_type last = str.find_first_not_of(str[first], first+1);
00134 
00135           if ( last == StringType::npos )
00136             str = str.substr(0, first+1);
00137           else if ( last - first > 1 )
00138             str = str.substr(0, first+1) + str.substr(last);
00139 
00140           ++first;
00141         }
00142     }
00143   while ( (first != StringType::npos) && (first != str.length()) );
00144 } // squeeze()
00145 
00146 /*----------------------------------------------------------------------------*/
00165 template<typename StringType>
00166 std::size_t claw::text::replace
00167 ( StringType& str, const StringType& e1, const StringType& e2 )
00168 {
00169   return
00170     claw::replace
00171     ( str.begin(), str.end(), e1.begin(), e1.end(), e2.begin(), e2.end() );
00172 } // replace()
00173 
00174 /*----------------------------------------------------------------------------*/
00179 template<typename T, typename StringType>
00180 bool claw::text::is_of_type( const StringType& str )
00181 {
00182   std::basic_istringstream< typename StringType::value_type,
00183     typename StringType::traits_type,
00184     typename StringType::allocator_type > iss(str);
00185 
00186   T val;
00187   bool result = false;
00188 
00189   if ( iss >> val )
00190     result = iss.eof();
00191 
00192   return result;
00193 } // is_of_type()
00194 
00195 /*----------------------------------------------------------------------------*/
00203 template<typename Sequence>
00204 void claw::text::split
00205 ( Sequence& sequence, const typename Sequence::value_type& str,
00206   const typename Sequence::value_type::value_type sep )
00207 {
00208   split(sequence, str.begin(), str.end(), sep);
00209 } // split()
00210 
00211 /*----------------------------------------------------------------------------*/
00220 template<typename Sequence>
00221 void claw::text::split
00222 ( Sequence& sequence, typename Sequence::value_type::const_iterator first,
00223   typename Sequence::value_type::const_iterator last,
00224   const typename Sequence::value_type::value_type sep )
00225 {
00226   typedef typename Sequence::value_type string_type;
00227 
00228   string_type line;
00229   std::basic_istringstream< typename string_type::value_type,
00230     typename string_type::traits_type,
00231     typename string_type::allocator_type > iss( string_type(first, last) );
00232 
00233   while ( std::getline(iss, line, sep) )
00234     *std::insert_iterator<Sequence>(sequence, sequence.end()) = line;
00235 } // split()
00236 
00237 /*----------------------------------------------------------------------------*/
00259 template<typename InputIterator, typename OutputIterator>
00260 void claw::text::c_escape
00261 ( InputIterator first, InputIterator last, OutputIterator out )
00262 {
00263   typedef typename std::iterator_traits<InputIterator>::value_type char_type;
00264   typedef std::basic_string<char_type> string_type;
00265 
00266   const string_type oct("01234567");
00267   const string_type hex("0123456789ABCDEFabcdef");
00268 
00269   bool escape(false);
00270 
00271   for ( ; first!=last; ++out )
00272     if ( escape )
00273       {
00274         switch( *first )
00275           {
00276           case 'a': *out = '\a'; ++first; break;
00277           case 'b': *out = '\b'; ++first; break;
00278           case 'f': *out = '\f'; ++first; break;
00279           case 'n': *out = '\n'; ++first; break;
00280           case 'r': *out = '\r'; ++first; break;
00281           case 't': *out = '\t'; ++first; break;
00282           case 'v': *out = '\v'; ++first; break;
00283           case 'o':
00284             {
00285               ++first;
00286               int v(0);
00287               const InputIterator e
00288                 ( find_first_not_of(first, last, oct.begin(), oct.end()) );
00289 
00290               std::basic_istringstream<char_type> iss( string_type(first, e) );
00291               iss >> std::oct >> v;
00292               *out = (char_type)v;
00293               first = e;
00294               break;
00295             }
00296           case 'x':
00297             {
00298               ++first;
00299               int v(0);
00300               const InputIterator e
00301                 ( find_first_not_of(first, last, hex.begin(), hex.end()) );
00302 
00303               std::basic_istringstream<char_type> iss( string_type(first, e) );
00304               iss >> std::hex >> v;
00305               *out = (char_type)v;
00306               first = e;
00307               break;
00308             }
00309           default: *out = *first; ++first;
00310           }
00311 
00312         escape = false;
00313       }
00314     else if ( *first == '\\' )
00315       {
00316         escape = true;
00317         ++first;
00318       }
00319     else
00320       {
00321         *out = *first;
00322         ++first;
00323       }
00324 } // c_escape()
00325 
00326 /*----------------------------------------------------------------------------*/
00336 template<typename StringType>
00337 bool claw::text::glob_match
00338 ( const StringType& pattern, const StringType& text,
00339   const typename StringType::value_type any_sequence,
00340   const typename StringType::value_type zero_or_one,
00341   const typename StringType::value_type any )
00342 {
00343   return claw::glob_match
00344     ( pattern.begin(), pattern.end(), text.begin(), text.end(), any_sequence,
00345       zero_or_one, any );
00346 } // glob_match()
00347 
00348 /*----------------------------------------------------------------------------*/
00358 template<typename StringType>
00359 bool claw::text::glob_potential_match
00360 ( const StringType& pattern, const StringType& text,
00361   const typename StringType::value_type any_sequence,
00362   const typename StringType::value_type zero_or_one,
00363   const typename StringType::value_type any )
00364 {
00365   return claw::glob_potential_match
00366     ( pattern.begin(), pattern.end(), text.begin(), text.end(), any_sequence,
00367       zero_or_one, any );
00368 } // glob_potential_match()