00001 #ifndef STATIC_CONTAINER_STRING_H
00002
00003 #define STATIC_CONTAINER_STRING_H
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include <iosfwd>
00058 #include <boost/assert.hpp>
00059 #include <gslib/static_container/STATIC_CONTAINER_MEMBERTYPEDEF.h>
00060 #include <gslib/numeric.h>
00061 #include <algorithm>
00062
00063 namespace gslib {
00064 namespace static_container {
00066
00072 template< size_t MaxStrLen, typename Ch = char, typename ChTraits = std::char_traits< Ch > >
00073 class string {
00074 public:
00075 STATIC_CONTAINER_MEMBERTYPEDEF( Ch )
00076 typedef Ch char_type;
00077 typedef ChTraits traits_type;
00078 typedef pointer iterator;
00079 typedef const_pointer const_iterator;
00080 private:
00081 Ch buffer_[ MaxStrLen + 1 ];
00082 public:
00084 BOOST_STATIC_CONSTANT( size_type, npos = -1 );
00085 BOOST_STATIC_CONSTANT( size_type, const_max = MaxStrLen );
00086
00088 static size_type max_size() { return const_max; }
00089
00091 static size_type capaciry() { return const_max; }
00092
00094 size_type size() const { return traits_type::length( buffer_ ); }
00095
00097 size_type length() const { return size(); }
00098
00099 iterator begin() { return buffer_; }
00100 const_iterator begin() const { return buffer_; }
00101 iterator end() { return begin() + size(); }
00102 const_iterator end() const { return begin() + size(); }
00103
00104 char_type& operator [] ( size_type i ) {
00105 PYD_ASSERT( i < size() );
00106 return *( begin() + i );
00107 }
00108 const char_type& operator [] ( size_type i ) const {
00109 PYD_ASSERT( i < size() );
00110 return *( begin() + i );
00111 }
00112 bool empty() const {
00113 return 0 == size();
00114 }
00115 reference at( size_type i ) { return operator [] ( i ); }
00116 char_type at( size_type i ) const { return operator [] ( i ); }
00117
00118 reference front() { return *begin(); }
00119 char_type front() const { return *begin(); }
00120 reference back() { return *( end() - 1 ); }
00121 char_type back() const { return *( end() - 1 ); }
00122
00124 void push_back( char_type ch ) {
00125
00126 if ( size() < MaxStrLen ) {
00127 iterator last = end();
00128 *last = ch;
00129 ++last;
00130 *last = char_type();
00131 }
00132 }
00133
00135 void append( char_type ch ) {
00136 push_back( ch );
00137 }
00138
00140 void append( const char* str ) {
00141 if ( 0 == str ) {
00142 return;
00143 }
00144 if ( size() + traits_type::length( str ) <= max_size() ) {
00145 traits_type::copy( end(), str, traits_type::length( str ) + 1 );
00146 } else {
00147 traits_type::copy( end(), str, max_size() );
00148 buffer_[ MaxStrLen ] = char_type();
00149 }
00150 }
00151
00153 template < size_type OtherMaxStrLen >
00154 void append( const string< OtherMaxStrLen, Ch, ChTraits >& other ) {
00155 append( other.c_str() );
00156 }
00157
00159 void pop_back() {
00160 BOOST_ASSERT( false == empty() );
00161 iterator last = end();
00162 --last;
00163 *last = char_type();
00164 }
00165
00167 string() {
00168 clear();
00169 }
00170
00172 template < size_type OtherMaxStrLen >
00173 string( const string< OtherMaxStrLen, Ch, ChTraits >& other ) {
00174 if ( buffer_ != other.begin() ) {
00175 size_type otherLen = other.size();
00176 if ( otherLen <= max_size() ) {
00177 traits_type::copy( buffer_, other.begin(), otherLen + 1 );
00178 } else {
00179 traits_type::copy( buffer_, other.begin(), max_size() + 1 );
00180 }
00181 }
00182 }
00183
00184 string( const char_type* s ) {
00185 if ( s != buffer_ ) {
00186 size_type otherLen = traits_type::length( s );
00187 if ( otherLen <= max_size() ) {
00188 traits_type::copy( buffer_, s, otherLen + 1 );
00189 } else {
00190 traits_type::copy( buffer_, s, max_size() + 1 );
00191 }
00192 }
00193 }
00194
00195
00196 ~string() {
00197 }
00198
00200 string& operator = ( const string& other ) {
00201 return operator = ( other.c_str() );
00202 }
00203 string& operator = ( const char_type* s ) {
00204 if ( s != buffer_ ) {
00205 clear();
00206 append( s );
00207 }
00208 return *this;
00209 }
00210
00212 pointer data() { return begin(); }
00213 const_pointer data() const { return begin(); }
00214 const_pointer c_str() const { return begin(); }
00215
00217 string operator += ( const char* other ) {
00218 append( other );
00219 return *this;
00220 }
00221
00223 template < size_type OtherMaxStrLen >
00224 string operator += ( const string< OtherMaxStrLen, Ch, ChTraits >& other ) {
00225 append( other );
00226 return *this;
00227 }
00228
00230 void clear() {
00231 buffer_[ 0 ] = char_type();
00232 }
00233
00235 template < size_type OtherMaxStrLen >
00236 friend bool operator == ( const string& a, const string< OtherMaxStrLen, Ch, ChTraits >& b ) {
00237 return operator == ( a, b.c_str() );
00238 }
00239
00241 friend bool operator == ( const string& a, const char* b ) {
00242 size_type size = a.size();
00243 return char_type() == b[ size ] &&
00244 std::equal( a.begin(), a.begin() + size, b, traits_type::eq );
00245 }
00246
00248 friend bool operator == ( const char* a, const string& b ) {
00249 return operator == ( b, a );
00250 }
00251
00253 template < size_type OtherMaxStrLen >
00254 friend bool operator != ( const string& a, const string< OtherMaxStrLen, Ch, ChTraits >& b ) {
00255 return !operator == ( a, b );
00256 }
00257
00259 friend bool operator != ( const string& a, const char* b ) {
00260 return !operator == ( a, b );
00261 }
00262
00264 friend bool operator != ( const char* a, const string& b ) {
00265 return !operator == ( a, b );
00266 }
00267
00269 template < size_type OtherMaxStrLen >
00270 friend bool operator < ( const string& a, const string< OtherMaxStrLen, Ch, ChTraits >& b ) {
00271 return operator < ( a, b.c_str() );
00272 }
00273
00275 friend bool operator < ( const string& a, const char* b ) {
00276 return std::lexicographical_compare(
00277 a.begin(), a.end(),
00278 b, b + traits_type::length( b ),
00279 traits_type::eq_int_type );
00280 }
00281
00283 friend bool operator < ( const char* a, const string& b ) {
00284 return operator < ( b, a );
00285 }
00286 };
00287 }
00288 }
00289
00290 #endif