// (C) Copyright Gennadiy Rozental 2001-2014. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/test for the library home page. // // File : $RCSfile$ // // Version : $Revision$ // // Description : simple string class definition // *************************************************************************** #ifndef CONST_STRING_HPP #define CONST_STRING_HPP // STL #include #include #include using std::string; namespace common_layer { // ************************************************************************** // // ************** const_string ************** // // ************************************************************************** // class const_string { public: // Subtypes typedef char const* iterator; typedef char const* const_iterator; typedef std::reverse_iterator reverse_iterator; typedef reverse_iterator const_reverse_iterator; // Constructor const_string() : m_begin( "" ), m_end( m_begin ) {} // Copy constructor is generated by compiler const_string( const std::string& s ) : m_begin( s.c_str() ), m_end( m_begin + s.length() ) {} const_string( char const* s ) : m_begin( s ? s : "" ) , m_end( s ? m_begin + std::strlen( s ) : m_begin ) {} const_string( char const* s, size_t length ) : m_begin( s ), m_end( m_begin + length ) { if( length == 0 ) erase(); } const_string( char const* first, char const* last ) : m_begin( first ), m_end( last ) {} // data access methods char operator[]( size_t index ) const { return m_begin[index]; } char at( size_t index ) const { return m_begin[index]; } char const* data() const { return m_begin; } // length operators size_t length() const { return m_end - m_begin; } bool is_empty() const { return m_end == m_begin; } void erase() { m_begin = m_end = ""; } void resize( size_t new_len ) { if( m_begin + new_len < m_end ) m_end = m_begin + new_len; } void rshorten( size_t shift = 1 ) { m_end -= shift; if( m_end <= m_begin ) erase(); } void lshorten( size_t shift = 1 ) { m_begin += shift; if( m_end <= m_begin ) erase(); } // Assignment operators const_string& operator=( const_string const& s ); const_string& operator=( string const& s ) { return *this = const_string( s ); } const_string& operator=( char const* s ) { return *this = const_string( s ); } const_string& assign( const_string const& s ) { return *this = s; } const_string& assign( string const& s, size_t len ) { return *this = const_string( s.data(), len ); } const_string& assign( string const& s ) { return *this = const_string( s ); } const_string& assign( char const* s ) { return *this = const_string( s ); } const_string& assign( char const* s, size_t len ) { return *this = const_string( s, len ); } const_string& assign( char const* f, char const* l ) { return *this = const_string( f, l ); } void swap( const_string& s ) { // do not want to include alogrithm char const* tmp1 = m_begin; char const* tmp2 = m_end; m_begin = s.m_begin; m_end = s.m_end; s.m_begin = tmp1; s.m_end = tmp2; } // Comparison operators friend bool operator==( const_string const& s1, const_string const& s2 ) { return s1.length() == s2.length() && std::strncmp( s1.data(), s2.data(), s1.length() ) == 0; } friend bool operator==( const_string const& s1, char const* s2 ) { return s1 == const_string( s2 ); } friend bool operator==( const_string const& s1, const string& s2 ) { return s1 == const_string( s2 ); } friend bool operator!=( const_string const& s1, const_string const& s2 ) { return !(s1 == s2); } friend bool operator!=( const_string const& s1, char const* s2 ) { return !(s1 == s2); } friend bool operator!=( const_string const& s1, const string& s2 ) { return !(s1 == s2); } friend bool operator==( char const* s2, const_string const& s1 ) { return s1 == s2; } friend bool operator==( const string& s2, const_string const& s1 ) { return s1 == s2; } friend bool operator!=( char const* s2, const_string const& s1 ) { return !(s1 == s2); } friend bool operator!=( const string& s2, const_string const& s1 ) { return !(s1 == s2); } // Iterators iterator begin() const { return m_begin; } iterator end() const { return m_end; } reverse_iterator rbegin() const { return reverse_iterator( m_end ); } reverse_iterator rend() const { return reverse_iterator( m_begin ); } private: // Data members char const* m_begin; char const* m_end; }; //____________________________________________________________________________// // first character class first_char { public: char operator()( const_string source, char default_char = '\0' ) const { return source.is_empty() ? default_char : *source.data(); } }; //____________________________________________________________________________// // last character class last_char { public: char operator()( const_string source, char default_char = '\0' ) const { return source.is_empty() ? default_char : *source.rbegin(); } }; //____________________________________________________________________________// inline const_string& const_string::operator=( const_string const& s ) { if( &s != this ) { m_begin = s.m_begin; m_end = s.m_end; } return *this; } //____________________________________________________________________________// typedef const_string const literal; //____________________________________________________________________________// inline std::ostream& operator<<( std::ostream& os, const_string const& str ) { os << std::string( str.begin(), str.length() ); return os; } //____________________________________________________________________________// }; // namespace common_layer #endif // CONST_STRING_HPP