00001 #ifndef STATIC_CONTAINER_STRING_H
00002
00003 #define STATIC_CONTAINER_STRING_H
00004
00005 #include <iosfwd>
00006 #include <boost/assert.hpp>
00007 #include "static_container/STATIC_CONTAINER_MEMBERTYPEDEF.h"
00008 #include "static_container/integer.h"
00009 #include <algorithm>
00010
00011 namespace static_container {
00013
00018 template< size_type MaxStrLen, typename Ch = char, typename ChTraits = std::char_traits< Ch > >
00019 class string {
00020 public:
00021 STATIC_CONTAINER_MEMBERTYPEDEF( Ch )
00022 typedef Ch char_type;
00023 typedef ChTraits traits_type;
00024 typedef pointer iterator;
00025 typedef const_pointer const_iterator;
00026 private:
00027 Ch buffer_[ MaxStrLen + 1 ];
00028 public:
00030 BOOST_STATIC_CONSTANT( size_type, npos = -1 );
00031 BOOST_STATIC_CONSTANT( size_type, const_max = MaxStrLen );
00032
00034 static size_type max_size() { return const_max; }
00035
00037 static size_type capaciry() { return const_max; }
00038
00040 size_type size() const { return traits_type::length( buffer_ ); }
00041
00043 size_type length() const { return size(); }
00044
00045 iterator begin() { return buffer_; }
00046 const_iterator begin() const { return buffer_; }
00047 iterator end() { return begin() + size(); }
00048 const_iterator end() const { return begin() + size(); }
00049
00050 char_type& operator [] ( size_type i ) {
00051 PYD_ASSERT( i < size() );
00052 return *( begin() + i );
00053 }
00054 const char_type& operator [] ( size_type i ) const {
00055 PYD_ASSERT( i < size() );
00056 return *( begin() + i );
00057 }
00058 bool empty() const {
00059 return 0 == size();
00060 }
00061 reference at( size_type i ) { return operator [] ( i ); }
00062 char_type at( size_type i ) const { return operator [] ( i ); }
00063
00064 reference front() { return *begin(); }
00065 char_type front() const { return *begin(); }
00066 reference back() { return *( end() - 1 ); }
00067 char_type back() const { return *( end() - 1 ); }
00068
00070 void push_back( char_type ch ) {
00071 BOOST_ASSERT( size() < MaxStrLen );
00072 iterator last = end();
00073 *last = ch;
00074 ++last;
00075 *last = char_type();
00076 }
00077
00079 void append( char_type ch ) {
00080 push_back( ch );
00081 }
00082
00084 void append( const char* str ) {
00085 BOOST_ASSERT( 0 != str && size() + traits_type::length( str ) <= max_size() );
00086 traits_type::copy( end(), str, traits_type::length( str ) + 1 );
00087 }
00088
00090 template < size_type OtherMaxStrLen >
00091 void append( const string< OtherMaxStrLen, Ch, ChTraits >& other ) {
00092 append( other.c_str() );
00093 }
00094
00096 void pop_back() {
00097 BOOST_ASSERT( false == empty() );
00098 iterator last = end();
00099 --last;
00100 *last = char_type();
00101 }
00102
00104 string() {
00105 clear();
00106 }
00107
00109 template < size_type OtherMaxStrLen >
00110 string( const string< OtherMaxStrLen, Ch, ChTraits >& other ) {
00111 if ( buffer_ != other.begin() ) {
00112 BOOST_ASSERT( other.size() <= max_size() );
00113 traits_type::copy( buffer_, other.begin(), other.size() + 1 );
00114 }
00115 }
00116
00117 string( const char_type* s ) {
00118 if ( s != buffer_ ) {
00119 BOOST_ASSERT( traits_type::length( s ) <= max_size() );
00120 traits_type::copy( buffer_, s, traits_type::length( s ) + 1 );
00121 }
00122 }
00123
00124
00125 ~string() {
00126 }
00127
00129 string& operator = ( const string& other ) {
00130 return operator = ( other.c_str() );
00131 }
00132 string& operator = ( const char_type* s ) {
00133 if ( s != buffer_ ) {
00134 BOOST_ASSERT( traits_type::length( s ) <= max_size() );
00135 traits_type::copy( buffer_, s, traits_type::length( s ) + 1 );
00136 }
00137 return *this;
00138 }
00139
00141 const_pointer c_str() const { return begin(); }
00142
00144 string operator += ( const char* other ) {
00145 append( other );
00146 return *this;
00147 }
00148
00150 template < size_type OtherMaxStrLen >
00151 string operator += ( const string< OtherMaxStrLen, Ch, ChTraits >& other ) {
00152 append( other );
00153 return *this;
00154 }
00155
00157 void clear() {
00158 buffer_[ 0 ] = char_type();
00159 }
00160
00162 template < size_type OtherMaxStrLen >
00163 friend bool operator == ( const string& a, const string< OtherMaxStrLen, Ch, ChTraits >& b ) {
00164 return operator == ( a, b.c_str() );
00165 }
00166
00168 friend bool operator == ( const string& a, const char* b ) {
00169 size_type size = a.size();
00170 return char_type() == b[ size ] &&
00171 std::equal( a.begin(), a.begin() + size, b, traits_type::eq );
00172 }
00173
00175 friend bool operator == ( const char* a, const string& b ) {
00176 return operator == ( b, a );
00177 }
00178
00180 template < size_type OtherMaxStrLen >
00181 friend bool operator != ( const string& a, const string< OtherMaxStrLen, Ch, ChTraits >& b ) {
00182 return !operator == ( a, b );
00183 }
00184
00186 friend bool operator != ( const string& a, const char* b ) {
00187 return !operator == ( a, b );
00188 }
00189
00191 friend bool operator != ( const char* a, const string& b ) {
00192 return !operator == ( a, b );
00193 }
00194
00196 template < size_type OtherMaxStrLen >
00197 friend bool operator < ( const string& a, const string< OtherMaxStrLen, Ch, ChTraits >& b ) {
00198 return operator < ( a, b.c_str() );
00199 }
00200
00202 friend bool operator < ( const string& a, const char* b ) {
00203 return std::lexicographical_compare(
00204 a.begin(), a.end(),
00205 b, b + traits_type::length( b ),
00206 traits_type::eq_int_type );
00207 }
00208
00210 friend bool operator < ( const char* a, const string& b ) {
00211 return operator < ( b, a );
00212 }
00213 };
00214 }
00215
00216 #endif