const_super_string.hpp

00001 #ifndef _BASIC_CONST_SUPER_STRING_HPP__
00002 #define _BASIC_CONST_SUPER_STRING_HPP__
00003 
00004 
00005 /* Copyright 2006 CrystalClear Software, Inc.
00006  * Use, modification and distribution is subject to the 
00007  * Boost Software License, Version 1.0. (See accompanying
00008  * file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
00009  *
00010  * Author:  Jeff Garland 
00011  * Last Modified: $Date: 2006/07/03 02:43:02 $
00012  * Created: Sat Jun  29 14:02:41 2006 
00013  */
00014 
00015 
00016 #include <boost/const_string/const_string.hpp>
00017 #include <boost/const_string/concatenation.hpp>
00018 #include <boost/const_string/io.hpp>
00019 
00020 #include <boost/algorithm/string.hpp>
00021 #include <boost/algorithm/string/regex.hpp>
00022 #include <boost/regex.hpp>
00023 #include <boost/format.hpp>
00024 #include <string>
00025 #include <vector>
00026 #include <sstream>
00027 #include <fstream>
00028 
00032 template<class char_type>
00033 class basic_const_super_string : public boost::const_string<char_type> {
00034 public:
00035   typedef boost::const_string<char_type>              ss_base_string_type;
00036   typedef boost::const_string<char_type>              base_string_type;
00037   typedef std::basic_string<char_type>                std_string_type;
00038   typedef typename base_string_type::const_iterator   iterator_type;
00039   typedef typename base_string_type::size_type        size_type;
00040   typedef std::basic_stringstream<char_type>          string_stream_type;
00041   typedef std::vector<basic_const_super_string<char_type> > string_vector;
00042   
00043   basic_const_super_string() 
00044   {}
00045 
00046   basic_const_super_string(const char_type* const s) :
00047     base_string_type(s)
00048   {}
00049 
00050   basic_const_super_string(const base_string_type& s) :
00051     base_string_type(s)
00052   {}
00053 
00054   basic_const_super_string(iterator_type beg, iterator_type end) :
00055     base_string_type(beg, end)
00056   {}
00057 
00058   //Append contents of a file to the string
00059   basic_const_super_string append_file(const std_string_type& filepath) const;
00060 
00061   //See if the string contains the regular expression somewhere
00062   bool contains_regex (const base_string_type& s) const;
00063 
00064   //Query functions for start / contains
00065   bool contains    (const base_string_type& s) const;
00066   bool starts_with (const base_string_type& s, size_type offset=0) const;
00067   bool ends_with   (const base_string_type& s) const;
00068 
00069   //Case insensitive query functions 
00070   bool icontains   (const base_string_type& s) const;
00071   bool istarts_with(const base_string_type& s, size_type offset=0) const;
00072   bool iends_with  (const base_string_type& s) const;
00073 
00074   //Split the string based on the predicate string
00075   unsigned int split(const base_string_type& predicate, 
00076                      string_vector& result)             const;
00077 
00078   unsigned int split_regex(const base_string_type& predicate_regex, 
00079                            string_vector& result)             const;
00080   
00081 
00082   //Enhanced replace functions
00083   basic_const_super_string
00084   replace_all_regex  (const base_string_type& match_regex, 
00085                       const base_string_type& replace_regex) const;
00086 
00087   basic_const_super_string 
00088   replace_first(const base_string_type& match_string, 
00089                 const base_string_type& replace_string) const;
00090 
00091   basic_const_super_string 
00092   replace_last (const base_string_type& match_string, 
00093                 const base_string_type& replace_string) const;
00094 
00095   basic_const_super_string 
00096   replace_nth  (const base_string_type& match_string, 
00097                 const base_string_type& replace_string, 
00098                 size_type n) const;
00099 
00100   basic_const_super_string 
00101   replace_all  (const base_string_type& match_string, 
00102                 const base_string_type& replace_string) const;
00103 
00104   //Case insensitive enhanced replace functions
00105   basic_const_super_string 
00106   ireplace_first(const base_string_type& match_string, 
00107                  const base_string_type& replace_string) const;
00108 
00109   basic_const_super_string 
00110   ireplace_last (const base_string_type& match_string, 
00111                  const base_string_type& replace_string) const;
00112 
00113   basic_const_super_string 
00114   ireplace_nth  (const base_string_type& match_string, 
00115                  const base_string_type& replace_string, 
00116                  size_type n) const;
00117 
00118   basic_const_super_string 
00119   ireplace_all  (const base_string_type& match_string, 
00120                  const base_string_type& replace_string) const;
00121   
00122   //White space trimming functions
00123   basic_const_super_string trim()       const;
00124   basic_const_super_string trim_left()  const;
00125   basic_const_super_string trim_right() const;
00126   
00127 
00128   //Case Conversion
00129   basic_const_super_string  to_lower() const;
00130   basic_const_super_string  to_upper() const;
00131 
00132 
00133   //Type  conversion functions
00134   //JKG TODO: look at doing some meta-programming magic to write
00135   //the these functions with few overloads.
00136   template<typename T>
00137   basic_const_super_string<char_type> append    (const T& value) const;
00138 
00139   template<typename T1, typename T2>
00140   basic_const_super_string<char_type> append    (const T1& val1, 
00141                                                  const T2& val2) const;
00142 
00143   template<typename T1, typename T2, typename T3>
00144   basic_const_super_string<char_type> append    (const T1& val1, 
00145                                                  const T2& val2,
00146                                                  const T3& val3) const;
00147   
00148   template<typename T1, typename T2, typename T3, typename T4>
00149   basic_const_super_string<char_type> append    (const T1& val1, 
00150                                                  const T2& val2,
00151                                                  const T3& val3,
00152                                                  const T4& val4) const;
00153 
00154   template<typename T1, typename T2, typename T3, typename T4, typename T5>
00155   basic_const_super_string<char_type> append    (const T1& val1, 
00156                                                  const T2& val2,
00157                                                  const T3& val3,
00158                                                  const T4& val4,
00159                                                  const T5& val5) const;
00160   template<class T>
00161   basic_const_super_string<char_type> prepend   (const T& value) const;
00162 
00163   template<class T> 
00164   basic_const_super_string<char_type> insert_at (size_type pos, 
00165                                                  const T& value) const;
00166 
00167   template<typename T> 
00168   basic_const_super_string<char_type> append_formatted (const T& value, 
00169                                                         const base_string_type& fmt) const;
00170   template<typename T1, typename T2> 
00171   basic_const_super_string<char_type> append_formatted (const T1& val1, 
00172                                                         const T2& val2,
00173                                                         const base_string_type& fmt) const;
00174   template<typename T1, typename T2, typename T3> 
00175   basic_const_super_string<char_type> append_formatted (const T1& val1, 
00176                                                         const T2& val2,
00177                                                         const T3& val3,
00178                                                         const base_string_type& fmt) const;
00179   template<typename T1, typename T2, typename T3, typename T4> 
00180   basic_const_super_string<char_type> append_formatted (const T1& val1, 
00181                                                         const T2& val2,
00182                                                         const T3& val3,
00183                                                         const T4& val4,
00184                                                         const base_string_type& fmt) const;
00185   template<typename T1, typename T2, typename T3, typename T4, typename T5> 
00186   basic_const_super_string<char_type> append_formatted (const T1& val1, 
00187                                                         const T2& val2,
00188                                                         const T3& val3,
00189                                                         const T4& val4,
00190                                                         const T5& val5,
00191                                                         const base_string_type& fmt) const;
00192 
00193 
00194 private:
00195 
00196 };
00197 
00198 
00210 template<class char_type>
00211 inline
00212 basic_const_super_string<char_type>
00213 basic_const_super_string<char_type>::append_file(const std_string_type& filepath) const
00214 {
00215   std::ifstream infile(filepath.c_str());
00216   if (infile) {
00217     std::istreambuf_iterator<char> itr(infile);
00218     std::istreambuf_iterator<char> file_end;
00219     std_string_type data(itr, file_end);
00220     return base_string_type(this->str() + data);
00221   }
00222   return base_string_type();
00223 }
00224 
00225 
00243 template<class char_type>
00244 inline
00245 unsigned int 
00246 basic_const_super_string<char_type>::split(const base_string_type& predicate, 
00247                                      string_vector& result) const
00248 {
00249 
00250   namespace alg = boost::algorithm;
00251   
00252   alg::iter_split(result, *this, 
00253                   alg::first_finder(predicate, alg::is_equal()));
00254   
00255   //iter_split will return entire string if no matches found
00256   return result.size()-1; //todo bug here is result not empty
00257 }
00258 
00277 template<class char_type>
00278 inline
00279 unsigned int 
00280 basic_const_super_string<char_type>::split_regex(const base_string_type& predicate_regex, 
00281                                                                    string_vector& result)  const
00282 {
00283 
00284   boost::basic_regex<char_type> re(predicate_regex.begin(),
00285                                    predicate_regex.end());
00286 
00287   boost::regex_token_iterator<iterator_type> i(this->begin(), 
00288                                                this->end(), 
00289                                                re, -1);
00290   boost::regex_token_iterator<iterator_type> j;
00291   
00292   unsigned int count = 0;
00293   while(i != j) {
00294     base_string_type s(*i);
00295     result.push_back(s);
00296     count++;
00297     i++;
00298   }
00299   return count;
00300   
00301 }
00302 
00303 
00316 template<class char_type>
00317 inline
00318 bool
00319 basic_const_super_string<char_type>::contains_regex(const base_string_type& predicate_regex) const
00320 {
00321   boost::regex::basic_regex<char_type> pred(predicate_regex.begin(),
00322                                             predicate_regex.end());
00323   return boost::regex_search(this->begin(),
00324                              this->end(),
00325                              pred,
00326                              boost::match_default);
00327 }
00328 
00329 
00347 template<class char_type>
00348 inline
00349 basic_const_super_string<char_type>
00350 basic_const_super_string<char_type>::replace_all_regex(const base_string_type& match_regex, 
00351                                                                          const base_string_type& replace_format) const
00352 {
00353   boost::regex::basic_regex<char_type> pred(match_regex.str());
00354   return base_string_type(boost::algorithm::replace_all_regex_copy(this->str(), 
00355                                                                    pred, 
00356                                                                    replace_format.str()));
00357 }
00358 
00359 
00371 template<class char_type>
00372 inline
00373 basic_const_super_string<char_type>
00374 basic_const_super_string<char_type>::replace_all(const base_string_type& match_string, 
00375                                                                    const base_string_type& replace_string) const
00376 {
00377   return base_string_type(boost::algorithm::replace_all_copy(this->str(), 
00378                                                              match_string, 
00379                                                              replace_string));
00380 }
00381 
00382 
00395 template<class char_type>
00396 inline
00397 basic_const_super_string<char_type>
00398 basic_const_super_string<char_type>::replace_nth(const base_string_type& match_string, 
00399                                                                    const base_string_type& replace_string,
00400                                                                    size_type n) const
00401 {
00402   return base_string_type(boost::algorithm::replace_nth_copy(this->str(), 
00403                                                              match_string, 
00404                                                              n,
00405                                                              replace_string));
00406 }
00407 
00408 
00420 template<class char_type>
00421 inline
00422 basic_const_super_string<char_type>
00423 basic_const_super_string<char_type>::replace_first(const base_string_type& match_string, 
00424                                                                      const base_string_type& replace_string) const
00425 {
00426   return base_string_type(boost::algorithm::replace_first_copy(this->str(), 
00427                                                                match_string, 
00428                                                                replace_string));
00429 }
00430 
00431 
00443 template<class char_type>
00444 inline
00445 basic_const_super_string<char_type>
00446 basic_const_super_string<char_type>::replace_last(const base_string_type& match_string, 
00447                                                                     const base_string_type& replace_string) const
00448 {
00449   return base_string_type(boost::algorithm::replace_last_copy(this->str(), 
00450                                                               match_string, 
00451                                                               replace_string));
00452 }
00453 
00465 template<class char_type>
00466 inline
00467 basic_const_super_string<char_type>
00468 basic_const_super_string<char_type>::ireplace_all(const base_string_type& match_string, 
00469                                                                     const base_string_type& replace_string) const
00470 {
00471   return base_string_type(boost::algorithm::ireplace_all_copy(this->str(), 
00472                                                               match_string, 
00473                                                               replace_string));
00474 }
00475 
00476 
00489 template<class char_type>
00490 inline
00491 basic_const_super_string<char_type>
00492 basic_const_super_string<char_type>::ireplace_nth(const base_string_type& match_string, 
00493                                                                     const base_string_type& replace_string,
00494                                                                     size_type n) const
00495 {
00496   return base_string_type(boost::algorithm::ireplace_nth_copy(this->str(), 
00497                                                               match_string, 
00498                                                               n, 
00499                                                               replace_string));
00500 }
00501 
00502 
00514 template<class char_type>
00515 inline
00516 basic_const_super_string<char_type>
00517 basic_const_super_string<char_type>::ireplace_first(const base_string_type& match_string, 
00518                                                                       const base_string_type& replace_string) const
00519 {
00520   return base_string_type(boost::algorithm::ireplace_first_copy(this->str(), 
00521                                                                 match_string, 
00522                                                                 replace_string));
00523 }
00524 
00525 
00537 template<class char_type>
00538 inline
00539 basic_const_super_string<char_type>
00540 basic_const_super_string<char_type>::ireplace_last(const base_string_type& match_string, 
00541                                                                      const base_string_type& replace_string) const
00542 {
00543   return base_string_type(boost::algorithm::ireplace_last_copy(this->str(), 
00544                                                                match_string, 
00545                                                                replace_string));
00546 }
00547 
00548 
00553 template<class char_type>
00554 inline
00555 bool
00556 basic_const_super_string<char_type>::contains(const base_string_type& predicate_string) const
00557 {
00558   return boost::algorithm::contains(*this, predicate_string);
00559 }
00560 
00566 template<class char_type>
00567 inline
00568 bool
00569 basic_const_super_string<char_type>::icontains(const base_string_type& predicate_string) const
00570 {
00571   return boost::algorithm::icontains(*this, predicate_string);
00572 }
00573 
00574 
00579 template<class char_type>
00580 inline
00581 bool
00582 basic_const_super_string<char_type>::ends_with(const base_string_type& predicate_string) const
00583 {
00584   return boost::algorithm::ends_with(*this, predicate_string);
00585 }
00586 
00597 template<class char_type>
00598 inline
00599 bool
00600 basic_const_super_string<char_type>::iends_with(const base_string_type& predicate_string) const
00601 {
00602   return boost::algorithm::iends_with(*this, predicate_string);
00603 }
00604 
00605 
00611 template<class char_type>
00612 inline
00613 bool
00614 basic_const_super_string<char_type>::starts_with(const base_string_type& predicate_string,
00615                                            size_type offset) const
00616 {
00617   return boost::algorithm::starts_with(this->substr(offset), predicate_string);
00618 }
00619 
00631 template<class char_type>
00632 inline
00633 bool
00634 basic_const_super_string<char_type>::istarts_with(const base_string_type& predicate_string, 
00635                                             size_type offset) const
00636 {
00637   return boost::algorithm::istarts_with(this->substr(offset), predicate_string);
00638 }
00639 
00640 
00659 template<class char_type>
00660 template<typename T>
00661 inline
00662 basic_const_super_string<char_type>
00663 basic_const_super_string<char_type>::append(const T& value) const
00664 {
00665   string_stream_type ss;
00666   ss << value;
00667   return base_string_type(*this + ss.str());
00668 }
00669 
00670 
00685 template<class char_type>
00686 template<typename T1, typename T2>
00687 inline
00688 basic_const_super_string<char_type>
00689 basic_const_super_string<char_type>::append(const T1& val1, const T2& val2) const
00690 {
00691   string_stream_type ss;
00692   ss << val1 << val2;
00693   return base_string_type(*this + ss.str());
00694 }
00695 
00711 template<class char_type>
00712 template<typename T1, typename T2, typename T3>
00713 inline
00714 basic_const_super_string<char_type>
00715 basic_const_super_string<char_type>::append(const T1& val1, 
00716                                                               const T2& val2,
00717                                                               const T3& val3) const
00718 {
00719   string_stream_type ss;
00720   ss << val1 << val2 << val3;
00721   return base_string_type(*this + ss.str());
00722 }
00723 
00724 
00740 template<class char_type>
00741 template<typename T1, typename T2, typename T3, typename T4>
00742 inline
00743 basic_const_super_string<char_type>
00744 basic_const_super_string<char_type>::append(const T1& val1, 
00745                                             const T2& val2,
00746                                             const T3& val3,
00747                                             const T4& val4) const
00748 {
00749   string_stream_type ss;
00750   ss << val1 << val2 << val3 << val4;
00751   return base_string_type(*this + ss.str());
00752 }
00753 
00769 template<class char_type>
00770 template<typename T1, typename T2, typename T3, typename T4, typename T5>
00771 inline
00772 basic_const_super_string<char_type>
00773 basic_const_super_string<char_type>::append(const T1& val1, 
00774                                             const T2& val2,
00775                                             const T3& val3,
00776                                             const T4& val4,
00777                                             const T5& val5) const
00778 {
00779   string_stream_type ss;
00780   ss << val1 << val2 << val3 << val4 << val5;
00781   return base_string_type(*this + ss.str());
00782 }
00783 
00784 
00804 template<class char_type>
00805 template<typename T>
00806 inline
00807 basic_const_super_string<char_type>
00808 basic_const_super_string<char_type>::append_formatted(const T& value, 
00809                                                       const base_string_type& format) const
00810 {
00811   boost::format f(format.str());
00812   string_stream_type ss;
00813   ss << *this << f % value;
00814   return base_string_type(ss.str());
00815 }
00816 
00817 
00835 template<class char_type>
00836 template<typename T1, typename T2>
00837 inline
00838 basic_const_super_string<char_type>
00839 basic_const_super_string<char_type>::append_formatted(const T1& val1,
00840                                                       const T2& val2,
00841                                                       const base_string_type& format) const
00842 {
00843   boost::format f(format.str());
00844   string_stream_type ss;
00845   ss << *this << f % val1 % val2;
00846   return base_string_type(ss.str());
00847 }
00848 
00867 template<class char_type>
00868 template<typename T1, typename T2, typename T3>
00869 inline
00870 basic_const_super_string<char_type>
00871 basic_const_super_string<char_type>::append_formatted(const T1& val1,
00872                                                       const T2& val2,
00873                                                       const T3& val3,
00874                                                       const base_string_type& format) const
00875 {
00876   boost::format f(format.str());
00877   string_stream_type ss;
00878   ss << *this << f % val1 % val2 % val3;
00879   return base_string_type(ss.str());
00880 }
00881 
00882 
00901 template<class char_type>
00902 template<typename T1, typename T2, typename T3, typename T4>
00903 inline
00904 basic_const_super_string<char_type>
00905 basic_const_super_string<char_type>::append_formatted(const T1& val1,
00906                                                       const T2& val2,
00907                                                       const T3& val3,
00908                                                       const T4& val4,
00909                                                       const base_string_type& format) const
00910 {
00911   boost::format f(format.str());
00912   string_stream_type ss;
00913   ss << *this << f % val1 % val2 % val3 % val4;
00914   return base_string_type(ss.str());
00915 }
00916 
00935 template<class char_type>
00936 template<typename T1, typename T2, typename T3, typename T4, typename T5>
00937 inline
00938 basic_const_super_string<char_type>
00939 basic_const_super_string<char_type>::append_formatted(const T1& val1,
00940                                                       const T2& val2,
00941                                                       const T3& val3,
00942                                                       const T4& val4,
00943                                                       const T5& val5,
00944                                                       const base_string_type& format) const
00945 {
00946   boost::format f(format.str());
00947   string_stream_type ss;
00948   ss << *this << f % val1 % val2 % val3 % val4 % val5;
00949   return base_string_type(ss.str());
00950 }
00951 
00952 
00968 template<class char_type>
00969 template<class T>
00970 inline
00971 basic_const_super_string<char_type>
00972 basic_const_super_string<char_type>::prepend(const T& value) const
00973 {
00974   string_stream_type ss;
00975   ss << value;
00976   return base_string_type(ss.str()+this->str());
00977 }
00978 
00993 template<class char_type>
00994 template<class T>
00995 inline
00996 basic_const_super_string<char_type>
00997 basic_const_super_string<char_type>::insert_at(size_type position, 
00998                                                const T& value) const
00999 {
01000   string_stream_type ss;
01001   ss << this->substr(0, position) << value << this->substr(position);
01002   
01003   return base_string_type(ss.str());
01004 }
01005 
01006 
01007 
01014 template<class char_type>
01015 inline
01016 basic_const_super_string<char_type>
01017 basic_const_super_string<char_type>::to_upper() const
01018 {
01019   //TODO: more hacking here...pure to_upper_copy fails
01020   std::basic_string<char_type> s(this->str());
01021   boost::algorithm::to_upper(s);
01022   return basic_const_super_string<char_type>(s);
01023 }
01024 
01025 
01032 template<class char_type>
01033 inline
01034 basic_const_super_string<char_type>
01035 basic_const_super_string<char_type>::to_lower() const
01036 {
01037   //TODO: more hacking here...pure to_upper_copy fails
01038   std::basic_string<char_type> s(this->str());
01039   boost::algorithm::to_lower(s);
01040   return basic_const_super_string<char_type>(s);
01041 }
01042 
01048 template<class char_type>
01049 inline
01050 basic_const_super_string<char_type>
01051 basic_const_super_string<char_type>::trim() const
01052 {
01053   return boost::algorithm::trim_copy(*this);
01054 }
01055 
01056 
01057 
01062 template<class char_type>
01063 inline
01064 basic_const_super_string<char_type>
01065 basic_const_super_string<char_type>::trim_left() const
01066 {
01067   return boost::algorithm::trim_left_copy(*this);
01068 }
01069 
01070 
01075 template<class char_type>
01076 inline
01077 basic_const_super_string<char_type>
01078 basic_const_super_string<char_type>::trim_right() const
01079 {
01080   return boost::algorithm::trim_right_copy(*this);
01081 }
01082 
01083 
01084 
01085 typedef basic_const_super_string<char> const_super_string;
01086 
01087 typedef basic_const_super_string<wchar_t> wconst_super_string;
01088 
01089 
01090 #endif

Generated on Sun Jul 9 15:43:03 2006 for SuperString by  doxygen 1.4.6