Sierra Toolkit Version of the Day
String.hpp
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2003 - 2008 Sandia Corporation.                       */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #ifndef STK_UTIL_DIAG_String_h
00010 #define STK_UTIL_DIAG_String_h
00011 
00012 #ifdef USE_CISTRING
00013 
00014 #include <stk_util/util/cistring.hpp>
00015 
00016 namespace sierra {
00017 
00018 typedef cistring String;
00019 typedef cistring Identifier;
00020 typedef cistring ParamId;
00021 
00022 } // namespace sierra
00023 
00024 #else 
00025 
00084 #include <iosfwd>
00085 #include <string>
00086 
00087 namespace sierra {
00088 
00093 
00094 struct char_simple_traits ;
00095 
00096 struct char_label_traits ;
00097 
00099 template<typename T1, typename T2> struct Precedence ;
00100 
00101 template<typename T> struct Precedence<T, T> { typedef T Type ; };
00102 
00103 template<>
00104 struct Precedence<char_simple_traits, char_label_traits> {
00105   typedef char_label_traits Type ;
00106 };
00107 
00108 template<>
00109 struct Precedence<char_label_traits, char_simple_traits> {
00110   typedef char_label_traits Type ;
00111 };
00112 
00116 template<class CharTraits> class StringBase ;
00117 
00121 typedef StringBase< char_simple_traits > String ;
00122 typedef StringBase< char_label_traits >  Identifier ;
00123 typedef StringBase< char_label_traits >  ParamId ;
00124 
00125 }
00126 
00127 //----------------------------------------------------------------------
00128 // Binary Operators:
00129 
00130 namespace sierra {
00131 
00132 template<class CT1, class CT2>
00133 bool operator== ( const StringBase<CT1> &, const StringBase<CT2> & );
00134 
00135 template<class CT1, class CT2>
00136 bool operator!= ( const StringBase<CT1> &, const StringBase<CT2> & );
00137 
00138 template<class CT1, class CT2>
00139 bool operator<  ( const StringBase<CT1> &, const StringBase<CT2> & );
00140 
00141 template<class CT1, class CT2>
00142 bool operator>  ( const StringBase<CT1> &, const StringBase<CT2> & );
00143 
00144 template<class CT1, class CT2>
00145 bool operator<= ( const StringBase<CT1> &, const StringBase<CT2> & );
00146 
00147 template<class CT1, class CT2>
00148 bool operator>= ( const StringBase<CT1> &, const StringBase<CT2> & );
00149 
00150 
00151 template<class CT1>
00152 bool operator== ( const StringBase<CT1> &, const std::string & );
00153 
00154 template<class CT1>
00155 bool operator!= ( const StringBase<CT1> &, const std::string & );
00156 
00157 template<class CT1>
00158 bool operator<  ( const StringBase<CT1> &, const std::string & );
00159 
00160 template<class CT1>
00161 bool operator>  ( const StringBase<CT1> &, const std::string & );
00162 
00163 template<class CT1>
00164 bool operator<= ( const StringBase<CT1> &, const std::string & );
00165 
00166 template<class CT1>
00167 bool operator>= ( const StringBase<CT1> &, const std::string & );
00168 
00169 
00170 template<class CT1>
00171 bool operator== ( const StringBase<CT1> &, const char * );
00172 
00173 template<class CT1>
00174 bool operator!= ( const StringBase<CT1> &, const char * );
00175 
00176 template<class CT1>
00177 bool operator<  ( const StringBase<CT1> &, const char * );
00178 
00179 template<class CT1>
00180 bool operator>  ( const StringBase<CT1> &, const char * );
00181 
00182 template<class CT1>
00183 bool operator<= ( const StringBase<CT1> &, const char * );
00184 
00185 template<class CT1>
00186 bool operator>= ( const StringBase<CT1> &, const char * );
00187 
00188 
00189 template<class CT1>
00190 bool operator== (const char *, const StringBase<CT1> & );
00191 
00192 template<class CT1>
00193 bool operator!= (const char *, const StringBase<CT1> & );
00194 
00195 template<class CT1>
00196 bool operator<  (const char *, const StringBase<CT1> & );
00197 
00198 template<class CT1>
00199 bool operator>  (const char *, const StringBase<CT1> & );
00200 
00201 template<class CT1>
00202 bool operator<= (const char *, const StringBase<CT1> & );
00203 
00204 template<class CT1>
00205 bool operator>= (const char *, const StringBase<CT1> & );
00206 
00207 
00208 template<class CT1>
00209 bool operator== (const std::string &, const StringBase<CT1> &);
00210 
00211 template<class CT1>
00212 bool operator!= (const std::string &, const StringBase<CT1> &);
00213 
00214 template<class CT1>
00215 bool operator<  (const std::string &, const StringBase<CT1> &);
00216 
00217 template<class CT1>
00218 bool operator>  (const std::string &, const StringBase<CT1> &);
00219 
00220 template<class CT1>
00221 bool operator<= (const std::string &, const StringBase<CT1> &);
00222 
00223 template<class CT1>
00224 bool operator>= (const std::string &, const StringBase<CT1> &);
00225 
00226 
00227 
00228 std::ostream &
00229 operator<<( std::ostream & os, const sierra::String &s);
00230 
00231 std::istream &
00232 operator>>( std::istream & is, sierra::String &s );
00233 
00234 std::ostream &
00235 operator<<( std::ostream & os, const sierra::Identifier &s);
00236 
00237 std::istream &
00238 operator>>( std::istream & is, sierra::Identifier &s );
00239 
00240 }
00241 
00242 //----------------------------------------------------------------------
00243 
00244 namespace sierra {
00245 
00246 namespace implementation {
00247 
00248 union StringData {
00249 
00250   // Required: buf_len % sizeof(long) == 0 && buf_len > sizeof(Large)
00251   enum { buf_len = 32 };
00252   enum { off_len = buf_len - 1 };
00253   enum { max_len = buf_len - 2 };
00254 
00255   struct Large {
00256     char * ptr ; // Pointer to allocated memory
00257     size_t len ; // Length of string
00258     size_t siz ; // Allocated size
00259   } large ;
00260 
00261   char small[ buf_len ];
00262 
00263   StringData();
00264   ~StringData();
00265 
00266   size_t len() const ;
00267   const char * c_str() const ;
00268   char * c_str();
00269 
00271   char * mem( const char *, size_t n );
00272 };
00273 
00274 }
00275 
00276 //----------------------------------------------------------------------
00277 
00278 template<class CT>
00279 class StringBase {
00280 public:
00281   typedef const char * const_iterator;
00282   typedef char * iterator;
00283 
00284   // Types:
00285   typedef CT     traits_type ;
00286   typedef char   value_type ;
00287   typedef size_t size_type ;
00288 
00289   // Construct/copy/destroy:
00290 
00291   ~StringBase();
00292 
00293   StringBase();
00294   explicit StringBase( const std::string &);
00295 
00296   StringBase( const_iterator );
00297   template <class It>
00298   StringBase( It, It );
00299   StringBase( const char *, size_type );
00300 
00301   StringBase( const StringBase & );
00302   StringBase & operator= ( const StringBase & );
00303 
00304   template<class CT2>
00305   StringBase( const StringBase<CT2> & );
00306 
00307   StringBase<CT> & operator= ( const char * );
00308   StringBase<CT> & operator= ( const std::string & );
00309 
00310   template<class CT2>
00311   StringBase<CT> & operator= ( const StringBase<CT2> & );
00312 
00313   StringBase<CT> & operator+= ( const char * );
00314   StringBase<CT> & operator+= ( const std::string & );
00315 
00316   template<class CT2>
00317   StringBase<CT> & operator+= ( const StringBase<CT2> & );
00318 
00319   // Capacity:
00320   size_type size() const;
00321   size_type length() const;
00322   bool      empty() const ;
00323 
00324   const_iterator begin() const;
00325   iterator begin();
00326   const_iterator end() const;
00327   iterator end();
00328 
00329   // Modifiers:
00330 
00331   StringBase<CT> & assign( const char * );
00332   StringBase<CT> & assign( const char *, const size_type );
00333   StringBase<CT> & assign( const std::string& );
00334 
00335   template<class CT2>
00336   StringBase<CT> & assign( const StringBase<CT2> & );
00337 
00338   StringBase<CT> & append( const char * );
00339   StringBase<CT> & append( const char *, const typename StringBase<CT>::size_type );
00340   StringBase<CT> & append( const std::string& );
00341 
00342   template<class CT2>
00343   StringBase<CT> & append( const StringBase<CT2> & );
00344 
00345   void swap( StringBase<CT> & );
00346 
00347   // string operations
00348   const char* c_str() const;
00349   std::string s_str() const ;
00350 
00351   int compare( const char * ) const ;
00352   int compare( const std::string & ) const ;
00353 
00354   template<class CT2>
00355   int compare( const StringBase<CT2> & ) const ;
00356 
00357 private:
00358   implementation::StringData data ;
00359 };
00360 
00364 struct char_simple_traits {
00365 public:
00367   static size_t length( const char * c1 );
00368 
00370   static void convert( char *, size_t )
00371   {}
00372 
00374   static int compare( const char * c1, const char * c2 );
00375 };
00376 
00381 struct char_label_traits {
00382 public:
00384   static size_t length( const char * c1 );
00385 
00387   static void convert( char * c, size_t n );
00388 
00390   static int compare( const char * c1, const char * c2 );
00391 };
00392 
00393 //----------------------------------------------------------------------
00394 
00395 template<class CT>
00396 bool StringBase<CT>::empty() const
00397 { return data.len() == 0 ; }
00398 
00399 template<class CT>
00400 typename StringBase<CT>::size_type StringBase<CT>::length() const
00401 { return data.len(); }
00402 
00403 template<class CT>
00404 typename StringBase<CT>::size_type StringBase<CT>::size() const
00405 { return data.len(); }
00406 
00407 template<class CT>
00408 typename StringBase<CT>::iterator
00409 StringBase<CT>::begin()
00410 { return data.c_str(); }
00411 
00412 template<class CT>
00413 typename StringBase<CT>::const_iterator
00414 StringBase<CT>::begin() const
00415 { return data.c_str(); }
00416 
00417 template<class CT>
00418 typename StringBase<CT>::iterator
00419 StringBase<CT>::end()
00420 { return data.c_str() + data.len(); }
00421 
00422 template<class CT>
00423 typename StringBase<CT>::const_iterator
00424 StringBase<CT>::end() const
00425 { return data.c_str() + data.len(); }
00426 
00427 
00428 template<class CT>
00429 const char* StringBase<CT>::c_str() const
00430 { return data.c_str(); }
00431 
00432 template<class CT>
00433 std::string StringBase<CT>::s_str() const
00434 { return std::string(c_str()) ; }
00435 
00436 template<class CT>
00437 StringBase<CT>::~StringBase()
00438 {}
00439 
00440 //----------------------------------------------------------------------
00441 
00442 template<class CT>
00443 StringBase<CT>::StringBase() {}
00444 
00445 template<class CT>
00446 template<class CT2>
00447 StringBase<CT>::StringBase( const StringBase<CT2> & cs )
00448 {
00449   const size_type n = cs.length();
00450   traits_type::convert( data.mem(cs.c_str(), n), n );
00451 }
00452 
00453 template<class CT>
00454 StringBase<CT>::StringBase( const std::string& cs )
00455 {
00456   const size_type n = cs.length();
00457   traits_type::convert( data.mem(cs.c_str(), n), n );
00458 }
00459 
00460 template<class CT>
00461 StringBase<CT>::StringBase( const char * cs, typename StringBase<CT>::size_type n )
00462 {
00463   traits_type::convert( data.mem(cs, n), n );
00464 }
00465 
00466 template<class CT>
00467 template<class It>
00468 StringBase<CT>::StringBase( It l_begin, It l_end )
00469 {
00470   traits_type::convert( data.mem(&(*l_begin), l_end - l_begin), l_end - l_begin );
00471 }
00472 
00473 template<class CT>
00474 StringBase<CT>::StringBase( const char * cs )
00475 {
00476   const size_type n = traits_type::length(cs);
00477   traits_type::convert( data.mem(cs, n), n );
00478 }
00479 
00480 template<class CT>
00481 StringBase<CT>::StringBase( const StringBase & cs )
00482 {
00483   data.mem(cs.c_str(), cs.size());
00484 }
00485 
00486 //----------------------------------------------------------------------
00487 
00488 template<class CT>
00489 StringBase<CT> &
00490 StringBase<CT>::assign( const char * cs, const typename StringBase<CT>::size_type n )
00491 {
00492   traits_type::convert( data.mem(cs, n), n );
00493   return *this ;
00494 }
00495 
00496 template<class CT>
00497 StringBase<CT> & StringBase<CT>::assign( const char * cs )
00498 { return assign( cs, traits_type::length(cs) ); }
00499 
00500 template<class CT>
00501 StringBase<CT> & StringBase<CT>::assign( const std::string & cs )
00502 { return assign( cs.c_str(), cs.length() ); }
00503 
00504 template<class CT>
00505 template<class CT2>
00506 StringBase<CT> & StringBase<CT>::assign( const StringBase<CT2> & cs )
00507 { return assign( cs.c_str(), cs.length() ); }
00508 
00509 template<class CT>
00510 StringBase<CT>&
00511 StringBase<CT>::operator= ( const StringBase & cs ) {
00512   if (this == &cs)
00513     return *this;
00514   return assign( cs.c_str(), cs.length() );
00515 }
00516 
00517 template<class CT>
00518 template<class CT2>
00519 StringBase<CT>&
00520 StringBase<CT>::operator= ( const StringBase<CT2> & cs ) {
00521   return assign( cs.c_str(), cs.length() );
00522 }
00523 
00524 template<class CT>
00525 StringBase<CT>&
00526 StringBase<CT>::operator= ( const char * cs )
00527 { return assign( cs, traits_type::length(cs) ); }
00528 
00529 template<class CT>
00530 StringBase<CT>&
00531 StringBase<CT>::operator= ( const std::string& cs )
00532 { return assign( cs.c_str(), cs.length() ); }
00533 
00534 //----------------------------------------------------------------------
00535 
00536 template<class CT>
00537 StringBase<CT> &
00538 StringBase<CT>::append( const char * cs, const typename StringBase<CT>::size_type n )
00539 {
00540   std::string t;
00541 
00542   t.reserve(data.len() + n);
00543   t.append(data.c_str())
00544    .append(cs, n);
00545   traits_type::convert( data.mem(t.data(), t.length()), t.length());
00546   return *this ;
00547 }
00548 
00549 template<>
00550 inline
00551 StringBase<char_label_traits> &
00552 StringBase<char_label_traits>::append( const char * cs, const StringBase<char_label_traits>::size_type n )
00553 {
00554   std::string t;
00555 
00556   if (n != 0) {
00557     t.reserve(data.len() + n + 1);
00558     t.append(data.c_str())
00559      .append(data.len() == 0 ? "" : "_")
00560      .append(cs, n);
00561     traits_type::convert( data.mem(t.data(), t.length()), t.length());
00562   }
00563   return *this ;
00564 }
00565 
00566 template<class CT>
00567 StringBase<CT> & StringBase<CT>::append( const char * cs )
00568 { return append( cs, traits_type::length(cs) ); }
00569 
00570 template<class CT>
00571 StringBase<CT> & StringBase<CT>::append( const std::string & cs )
00572 { return append( cs.data(), cs.length() ); }
00573 
00574 template<class CT>
00575 template<class CT2>
00576 StringBase<CT> & StringBase<CT>::append( const StringBase<CT2> & cs )
00577 { return append( cs.c_str(), cs.length() ); }
00578 
00579 
00580 template<class CT>
00581 template<class CT2>
00582 StringBase<CT>&
00583 StringBase<CT>::operator+= ( const StringBase<CT2> & cs )
00584 { return append( cs.c_str(), cs.length() ); }
00585 
00586 template<class CT>
00587 StringBase<CT>&
00588 StringBase<CT>::operator+= ( const char * cs )
00589 { return append( cs, traits_type::length(cs) ); }
00590 
00591 template<class CT>
00592 StringBase<CT>&
00593 StringBase<CT>::operator+= ( const std::string& cs )
00594 { return append( cs.data(), cs.length() ); }
00595 
00596 //----------------------------------------------------------------------
00597 
00598 template<class CT>
00599 template<class CT2>
00600 int StringBase<CT>::compare( const StringBase<CT2> & cs ) const
00601 {
00602   typedef typename Precedence<CT, CT2>::Type Traits ;
00603   return Traits::compare( c_str(), cs.c_str() );
00604 }
00605 
00606 template<class CT>
00607 int StringBase<CT>::compare( const std::string & cs ) const
00608 {
00609   return CT::compare( c_str(), cs.c_str() );
00610 }
00611 
00612 template<class CT>
00613 int StringBase<CT>::compare( const char * cs ) const
00614 {
00615   return CT::compare( c_str(), cs );
00616 }
00617 
00618 template<class CT, class CT2>
00619 bool operator== ( const StringBase<CT> & lhs,
00620        const StringBase<CT2> & rhs )
00621 { return lhs.compare(rhs) == 0 ; }
00622 
00623 template<class CT, class CT2>
00624 bool operator!= ( const StringBase<CT> & lhs,
00625        const StringBase<CT2> & rhs )
00626 { return lhs.compare(rhs) != 0 ; }
00627 
00628 template<class CT, class CT2>
00629 bool operator< ( const StringBase<CT> & lhs,
00630       const StringBase<CT2> & rhs )
00631 { return lhs.compare(rhs) < 0 ; }
00632 
00633 template<class CT, class CT2>
00634 bool operator<= ( const StringBase<CT> & lhs,
00635        const StringBase<CT2> & rhs )
00636 { return lhs.compare(rhs) <= 0 ; }
00637 
00638 template<class CT, class CT2>
00639 bool operator> ( const StringBase<CT> & lhs,
00640       const StringBase<CT2> & rhs )
00641 { return lhs.compare(rhs) > 0 ; }
00642 
00643 template<class CT, class CT2>
00644 bool operator>= ( const StringBase<CT> & lhs,
00645        const StringBase<CT2> & rhs )
00646 { return lhs.compare(rhs) >= 0 ; }
00647 
00648 
00649 template<class CT>
00650 bool operator== ( const StringBase<CT> & lhs,
00651        const std::string & rhs )
00652 { return lhs.compare(rhs) == 0 ; }
00653 
00654 template<class CT>
00655 bool operator!= ( const StringBase<CT> & lhs,
00656        const std::string & rhs )
00657 { return lhs.compare(rhs) != 0 ; }
00658 
00659 template<class CT>
00660 bool operator< ( const StringBase<CT> & lhs,
00661       const std::string & rhs )
00662 { return lhs.compare(rhs) < 0 ; }
00663 
00664 template<class CT>
00665 bool operator<= ( const StringBase<CT> & lhs,
00666        const std::string & rhs )
00667 { return lhs.compare(rhs) <= 0 ; }
00668 
00669 template<class CT>
00670 bool operator> ( const StringBase<CT> & lhs,
00671       const std::string & rhs )
00672 { return lhs.compare(rhs) > 0 ; }
00673 
00674 template<class CT>
00675 bool operator>= ( const StringBase<CT> & lhs,
00676        const std::string & rhs )
00677 { return lhs.compare(rhs) >= 0 ; }
00678 
00679 
00680 template<class CT>
00681 bool operator== ( const StringBase<CT> & lhs,
00682        const char * rhs )
00683 { return lhs.compare(rhs) == 0 ; }
00684 
00685 template<class CT>
00686 bool operator!= ( const StringBase<CT> & lhs,
00687        const char * rhs )
00688 { return lhs.compare(rhs) != 0 ; }
00689 
00690 template<class CT>
00691 bool operator< ( const StringBase<CT> & lhs,
00692       const char * rhs )
00693 { return lhs.compare(rhs) < 0 ; }
00694 
00695 template<class CT>
00696 bool operator<= ( const StringBase<CT> & lhs,
00697        const char * rhs )
00698 { return lhs.compare(rhs) <= 0 ; }
00699 
00700 template<class CT>
00701 bool operator> ( const StringBase<CT> & lhs,
00702       const char * rhs )
00703 { return lhs.compare(rhs) > 0 ; }
00704 
00705 template<class CT>
00706 bool operator>= ( const StringBase<CT> & lhs,
00707        const char * rhs )
00708 { return lhs.compare(rhs) >= 0 ; }
00709 
00710 
00711 template<class CT>
00712 bool operator== ( const std::string & lhs,
00713        const StringBase<CT> & rhs)
00714 { return rhs.compare(lhs) == 0 ; }
00715 
00716 template<class CT>
00717 bool operator!= ( const std::string & lhs,
00718        const StringBase<CT> & rhs)
00719 { return rhs.compare(lhs) != 0 ; }
00720 
00721 template<class CT>
00722 bool operator< ( const std::string & lhs,
00723       const StringBase<CT> & rhs)
00724 { return rhs.compare(lhs) > 0 ; }
00725 
00726 template<class CT>
00727 bool operator<= ( const std::string & lhs,
00728        const StringBase<CT> & rhs)
00729 { return rhs.compare(lhs) >= 0 ; }
00730 
00731 template<class CT>
00732 bool operator> ( const std::string & lhs,
00733       const StringBase<CT> & rhs)
00734 { return rhs.compare(lhs) < 0 ; }
00735 
00736 template<class CT>
00737 bool operator>= ( const std::string & lhs,
00738        const StringBase<CT> & rhs)
00739 { return rhs.compare(lhs) <= 0 ; }
00740 
00741 
00742 template<class CT>
00743 bool operator== ( const char * lhs,
00744        const StringBase<CT> & rhs)
00745 { return rhs.compare(lhs) == 0 ; }
00746 
00747 template<class CT>
00748 bool operator!= ( const char * lhs,
00749        const StringBase<CT> & rhs)
00750 { return rhs.compare(lhs) != 0 ; }
00751 
00752 template<class CT>
00753 bool operator< ( const char * lhs,
00754       const StringBase<CT> & rhs)
00755 { return rhs.compare(lhs) > 0 ; }
00756 
00757 template<class CT>
00758 bool operator<= ( const char * lhs,
00759        const StringBase<CT> & rhs)
00760 { return rhs.compare(lhs) >= 0 ; }
00761 
00762 template<class CT>
00763 bool operator> ( const char * lhs,
00764       const StringBase<CT> & rhs)
00765 { return rhs.compare(lhs) < 0 ; }
00766 
00767 template<class CT>
00768 bool operator>= ( const char * lhs,
00769        const StringBase<CT> & rhs)
00770 { return rhs.compare(lhs) <= 0 ; }
00771 
00772 //----------------------------------------------------------------------
00773 
00774 template<class CT, class CT2>
00775 StringBase<CT>
00776 operator+( const StringBase<CT> &cs1, const StringBase<CT2> &cs2) {
00777   StringBase<CT> t(cs1);
00778   t.append(cs2.c_str(), cs2.size());
00779   return t;
00780 }
00781 
00782 template<class CT>
00783 StringBase<CT>
00784 operator+( const StringBase<CT> &cs1, const char *cs2) {
00785   StringBase<CT> t(cs1);
00786   t.append(cs2);
00787   return t;
00788 }
00789 
00790 template<class CT>
00791 StringBase<CT>
00792 operator+( const StringBase<CT> &cs1, const std::string &cs2) {
00793   StringBase<CT> t(cs1);
00794   t.append(cs2.c_str(), cs2.length());
00795   return t;
00796 }
00797 
00798 template<class CT>
00799 StringBase<CT>
00800 operator+ ( const char *cs1, const StringBase<CT> &cs2 ) {
00801   StringBase<CT> t(cs1);
00802   t.append(cs2.c_str(), cs2.length());
00803   return t;
00804 }
00805 
00806 template<class CT>
00807 std::string operator+(const std::string & lhs, const StringBase<CT> & rhs ) {
00808   std::string s( lhs ); return s.append( rhs.c_str(), rhs.length() );
00809 }
00810 
00814 
00815 } // namespace sierra
00816 
00817 #endif // USE_CISTRING
00818 
00819 #endif // STK_UTIL_DIAG_String_h
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines