const_string.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // (C) Copyright Gennadiy Rozental 2001-2014.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. // File : $RCSfile$
  8. //
  9. // Version : $Revision$
  10. //
  11. // Description : simple string class definition
  12. // ***************************************************************************
  13. #ifndef CONST_STRING_HPP
  14. #define CONST_STRING_HPP
  15. // STL
  16. #include <iterator>
  17. #include <string>
  18. #include <cstring>
  19. using std::string;
  20. namespace common_layer {
  21. // ************************************************************************** //
  22. // ************** const_string ************** //
  23. // ************************************************************************** //
  24. class const_string {
  25. public:
  26. // Subtypes
  27. typedef char const* iterator;
  28. typedef char const* const_iterator;
  29. typedef std::reverse_iterator<iterator> reverse_iterator;
  30. typedef reverse_iterator const_reverse_iterator;
  31. // Constructor
  32. const_string()
  33. : m_begin( "" ), m_end( m_begin ) {}
  34. // Copy constructor is generated by compiler
  35. const_string( const std::string& s )
  36. : m_begin( s.c_str() ),
  37. m_end( m_begin + s.length() ) {}
  38. const_string( char const* s )
  39. : m_begin( s ? s : "" )
  40. , m_end( s ? m_begin + std::strlen( s ) : m_begin )
  41. {}
  42. const_string( char const* s, size_t length )
  43. : m_begin( s ), m_end( m_begin + length ) { if( length == 0 ) erase(); }
  44. const_string( char const* first, char const* last )
  45. : m_begin( first ), m_end( last ) {}
  46. // data access methods
  47. char operator[]( size_t index ) const { return m_begin[index]; }
  48. char at( size_t index ) const { return m_begin[index]; }
  49. char const* data() const { return m_begin; }
  50. // length operators
  51. size_t length() const { return m_end - m_begin; }
  52. bool is_empty() const { return m_end == m_begin; }
  53. void erase() { m_begin = m_end = ""; }
  54. void resize( size_t new_len ) { if( m_begin + new_len < m_end ) m_end = m_begin + new_len; }
  55. void rshorten( size_t shift = 1 ) { m_end -= shift; if( m_end <= m_begin ) erase(); }
  56. void lshorten( size_t shift = 1 ) { m_begin += shift; if( m_end <= m_begin ) erase(); }
  57. // Assignment operators
  58. const_string& operator=( const_string const& s );
  59. const_string& operator=( string const& s ) { return *this = const_string( s ); }
  60. const_string& operator=( char const* s ) { return *this = const_string( s ); }
  61. const_string& assign( const_string const& s ) { return *this = s; }
  62. const_string& assign( string const& s, size_t len ) { return *this = const_string( s.data(), len ); }
  63. const_string& assign( string const& s ) { return *this = const_string( s ); }
  64. const_string& assign( char const* s ) { return *this = const_string( s ); }
  65. const_string& assign( char const* s, size_t len ) { return *this = const_string( s, len ); }
  66. const_string& assign( char const* f, char const* l ) { return *this = const_string( f, l ); }
  67. void swap( const_string& s ) {
  68. // do not want to include alogrithm
  69. char const* tmp1 = m_begin;
  70. char const* tmp2 = m_end;
  71. m_begin = s.m_begin;
  72. m_end = s.m_end;
  73. s.m_begin = tmp1;
  74. s.m_end = tmp2;
  75. }
  76. // Comparison operators
  77. friend bool operator==( const_string const& s1, const_string const& s2 )
  78. {
  79. return s1.length() == s2.length() && std::strncmp( s1.data(), s2.data(), s1.length() ) == 0;
  80. }
  81. friend bool operator==( const_string const& s1, char const* s2 ) { return s1 == const_string( s2 ); }
  82. friend bool operator==( const_string const& s1, const string& s2 ) { return s1 == const_string( s2 ); }
  83. friend bool operator!=( const_string const& s1, const_string const& s2 ) { return !(s1 == s2); }
  84. friend bool operator!=( const_string const& s1, char const* s2 ) { return !(s1 == s2); }
  85. friend bool operator!=( const_string const& s1, const string& s2 ) { return !(s1 == s2); }
  86. friend bool operator==( char const* s2, const_string const& s1 ) { return s1 == s2; }
  87. friend bool operator==( const string& s2, const_string const& s1 ) { return s1 == s2; }
  88. friend bool operator!=( char const* s2, const_string const& s1 ) { return !(s1 == s2); }
  89. friend bool operator!=( const string& s2, const_string const& s1 ) { return !(s1 == s2); }
  90. // Iterators
  91. iterator begin() const { return m_begin; }
  92. iterator end() const { return m_end; }
  93. reverse_iterator rbegin() const { return reverse_iterator( m_end ); }
  94. reverse_iterator rend() const { return reverse_iterator( m_begin ); }
  95. private:
  96. // Data members
  97. char const* m_begin;
  98. char const* m_end;
  99. };
  100. //____________________________________________________________________________//
  101. // first character
  102. class first_char {
  103. public:
  104. char operator()( const_string source, char default_char = '\0' ) const {
  105. return source.is_empty() ? default_char : *source.data();
  106. }
  107. };
  108. //____________________________________________________________________________//
  109. // last character
  110. class last_char {
  111. public:
  112. char operator()( const_string source, char default_char = '\0' ) const {
  113. return source.is_empty() ? default_char : *source.rbegin();
  114. }
  115. };
  116. //____________________________________________________________________________//
  117. inline const_string&
  118. const_string::operator=( const_string const& s ) {
  119. if( &s != this ) {
  120. m_begin = s.m_begin;
  121. m_end = s.m_end;
  122. }
  123. return *this;
  124. }
  125. //____________________________________________________________________________//
  126. typedef const_string const literal;
  127. //____________________________________________________________________________//
  128. inline std::ostream&
  129. operator<<( std::ostream& os, const_string const& str )
  130. {
  131. os << std::string( str.begin(), str.length() );
  132. return os;
  133. }
  134. //____________________________________________________________________________//
  135. }; // namespace common_layer
  136. #endif // CONST_STRING_HPP