libs/test/doc/components/unit_test_framework/getting_started/const_string.hpp
// (C) Copyright Gennadiy Rozental 2001.
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
#ifndef CONST_STRING_HPP
#define CONST_STRING_HPP
// STL
#include <string>
using std::string;
namespace common_layer {
// ************************************************************************** //
// ************** const_string ************** //
// ************************************************************************** //
class const_string {
public:
// Subtypes
typedef char const* iterator;
typedef char const* const_iterator;
#if defined(__SUNPRO_CC) && !defined(__SGI_STL_PORT)
typedef std::reverse_iterator<iterator,std::random_access_iterator_tag, char, char const&> reverse_iterator;
#else
typedef std::reverse_iterator<iterator,char, char const&> reverse_iterator;
#endif
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 );
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;
char const* data() const { return m_begin; }
#ifndef NO_CONST_STRING_IMPLISIT_CONVERTION
operator char const*() const { return m_begin; }
#endif
// 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 );
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 m_end; }
reverse_iterator rend() const { return m_begin; }
// search operation
iterator find_first_of( char c );
iterator find_first_of( const_string cs );
iterator find_last_of( char c );
iterator find_last_of( const_string cs );
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;
}; // namespace common_layer
#endif // CONST_STRING_HPP