String.hpp
1 #ifndef OPALS_STRING_HPP_INCLUDED
2 #define OPALS_STRING_HPP_INCLUDED
3 
4 #include <opals/fwd.hpp>
5 
6 #include <cstddef>
7 #include <type_traits>
8 
9 namespace std
10 {
11  struct random_access_iterator_tag;
12 }
13 
14 namespace opals
15 {
16 
17  /**
18  \class String
19 
20  \brief A dynamic character string whose interface conforms to STL's std::string
21 
22  \author wk
23  \date 02.02.2011
24 
25  \internal
26  opals::String is based on STL's std::string, which it however hides from the
27  interface in order to avoid problems when using the interface / opals-DLLs
28  with different STL-implementations.
29  The interface of opals::String differs slightly from the one of std::string:
30  - no template functions 'insert'
31  -> these functions are defined as overloaded non-template functions
32  for all String-iterator types
33  Conversion operators from/to std::string and its iterators, and
34  operator<< and operator>> for basic_istream and basic_ostream are provided for internal use only.
35  */
36  class OPALS_API String
37  {
38  class Impl;
39  Impl *pimpl_;
40 
41  public:
42  template<bool Const,bool Forward>
43  class Iterator;
44 
49 
50  typedef char value_type;
51  typedef char* pointer;
52  typedef char& reference;
53  typedef char const& const_reference;
54  typedef std::size_t size_type;
55  typedef std::ptrdiff_t difference_type;
56 
57  static const size_type& npos();
58 
59  /// \name construction / destruction
60  ///@{
61  String();
62  String( const String& other, size_type pos = 0, size_type n = npos() );
63  String( const char* s );
64  String( const char* s, size_type n );
65  String( size_type n, char c );
66  String( iterator beg, iterator end );
70  ~String();
71  ///}@
72 
73  /// \name assignment, swapping
74  ///@{
75  String& operator=( const String& other );
76  String& operator=( const char* other );
77  String& operator=( char c );
78  String& assign(const String&);
79  String& assign(const String& s, size_type pos, size_type n);
80  String& assign(const char* s, size_type n);
81  String& assign(const char* s);
82  String& assign(size_type n, char c);
83  String& assign( iterator beg, iterator end );
84  String& assign( const_iterator beg, const_iterator end );
85  String& assign( reverse_iterator beg, reverse_iterator end );
87  void swap( String& other );
88  ///}@
89 
90  /// \name iterator traversal
91  /// forward/reverse, const/non-const
92  ///@{
93  iterator begin();
94  const_iterator begin() const;
95  const_iterator cbegin() const;
96 
97  iterator end();
98  const_iterator end() const;
99  const_iterator cend() const;
100 
101  reverse_iterator rbegin();
102  const_reverse_iterator rbegin() const;
103  const_reverse_iterator crbegin() const;
104 
105  reverse_iterator rend();
106  const_reverse_iterator rend() const;
107  const_reverse_iterator crend() const;
108  ///}@
109 
110  /// \name element access
111  ///@{
112  reference at( size_type n );
113  const_reference at( size_type n ) const;
114  reference operator[]( size_type n );
115  const_reference operator[]( size_type n ) const;
116  reference front();
117  const_reference front() const;
118  reference back();
119  const_reference back() const;
120  const char* c_str() const;
121  const char* data() const;
122  ///}@
123 
124  /// \name size
125  ///@{
126  size_type size() const;
127  size_type length() const;
128  size_type max_size() const;
129  size_type capacity() const;
130  bool empty() const;
131  void clear();
132  void resize(size_type n, char c = char());
133  ///}@
134 
135  /// \name append
136  ///@{
137  String& append( const String& s );
138  String& append( const String& s, size_type pos, size_type n );
139  String& append( const char* s );
140  String& append( const char* s, size_type n );
141  String& append( size_type n, char c);
142  String& append( iterator beg, iterator end );
143  String& append( const_iterator beg, const_iterator end );
144  String& append( reverse_iterator beg, reverse_iterator end );
146 
147  void push_back(char c);
148 
149  String& operator+=(const String& s);
150  String& operator+=(const char* s);
151  String& operator+=(char c);
152  ///}@
153 
154  /// \name insert
155  ///@{
156  iterator insert( iterator pos, const char& s );
157  void insert( iterator pos, size_type n, const char& s );
158  String& insert( size_type n, const String& s );
159  String& insert( size_type pos, const String& s, size_type pos1, size_type n );
160  String& insert( size_type pos, const char* s );
161  String& insert( size_type pos, const char* s, size_type n );
162  String& insert( size_type pos, size_type n, char c );
163  void insert( iterator pos, iterator beg, iterator end );
164  void insert( iterator pos, const_iterator beg, const_iterator end );
165  void insert( iterator pos, reverse_iterator beg, reverse_iterator end );
166  void insert( iterator pos, const_reverse_iterator beg, const_reverse_iterator end );
167  ///}@
168 
169  /// \name erase
170  ///@{
171  iterator erase( iterator p );
172  iterator erase( iterator first, iterator last );
173  String& erase( size_type pos = 0, size_type n = npos() );
174  ///}@
175 
176  /// \name replace
177  ///@{
178  String& replace( size_type pos, size_type n, const String& s );
179  String& replace( size_type pos, size_type n, const String& s, size_type pos1, size_type n1 );
180  String& replace( size_type pos, size_type n, const char* s, size_type n1 );
181  String& replace( size_type pos, size_type n, const char* s );
182  String& replace( size_type pos, size_type n, size_type n1, char c );
183  String& replace( iterator first, iterator last, const String& s);
184  String& replace( iterator first, iterator last, const char* s, size_type n );
185  String& replace( iterator first, iterator last, const char* s );
186  String& replace( iterator first, iterator last, size_type n, char c );
187  String& replace( iterator beg1, iterator end1, iterator beg2, iterator end2 );
188  String& replace( iterator beg1, iterator end1, const_iterator beg2, const_iterator end2 );
189  String& replace( iterator beg1, iterator end1, reverse_iterator beg2, reverse_iterator end2 );
190  String& replace( iterator beg1, iterator end1, const_reverse_iterator beg2, const_reverse_iterator end2 );
191  ///}@
192 
193  /// \name find
194  /// forward/reverse
195  ///@{
196  size_type find( const String& s, size_type pos = 0 ) const;
197  size_type find( const char* s, size_type pos, size_type n ) const;
198  size_type find( const char* s, size_type pos = 0 ) const;
199  size_type find( char c, size_type pos = 0 ) const;
200  size_type rfind( const String& s, size_type pos = npos() ) const;
201  size_type rfind( const char* s, size_type pos, size_type n ) const;
202  size_type rfind( const char* s, size_type pos = npos() ) const;
203  size_type rfind( char c, size_type pos = npos() ) const;
204  size_type find_first_of( const String& s, size_type pos = 0 ) const;
205  size_type find_first_of( const char* s, size_type pos, size_type n ) const;
206  size_type find_first_of( const char* s, size_type pos = 0 ) const;
207  size_type find_first_of( char c, size_type pos = 0 ) const;
208  size_type find_first_not_of( const String& s, size_type pos = 0 ) const;
209  size_type find_first_not_of( const char* s, size_type pos, size_type n ) const;
210  size_type find_first_not_of( const char* s, size_type pos = 0 ) const;
211  size_type find_first_not_of( char c, size_type pos = 0 ) const;
212  size_type find_last_of( const String& s, size_type pos = npos() ) const;
213  size_type find_last_of( const char* s, size_type pos, size_type n ) const;
214  size_type find_last_of( const char* s, size_type pos = npos() ) const;
215  size_type find_last_of( char c, size_type pos = npos() ) const;
216  size_type find_last_not_of( const String& s, size_type pos = npos() ) const;
217  size_type find_last_not_of( const char* s, size_type pos, size_type n ) const;
218  size_type find_last_not_of( const char* s, size_type pos = npos() ) const;
219  size_type find_last_not_of( char c, size_type pos = npos() ) const;
220  ///}@
221 
222  /// \name substring
223  ///@{
224  String substr( size_type pos = 0, size_type n = npos() ) const;
225  ///}@
226 
227  /// \name copy to buffer
228  ///@{
229  size_type copy( char* buf, size_type n, size_type pos = 0 ) const;
230  ///}@
231 
232  /// \name 3-way comparison
233  ///@{
234  int compare( const String& s ) const;
235  int compare( size_type pos, size_type n, const String& s ) const;
236  int compare( size_type pos, size_type n, const String& s, size_type pos1, size_type n1 ) const;
237  int compare( const char* s ) const;
238  int compare( size_type pos, size_type n, const char* s, size_type len = npos() ) const;
239  ///}@
240 
241  /**
242  \class Iterator
243  \tparam Const constant-ness
244  \tparam Forward forward/reverse traversal
245 
246  \brief A random access iterator class for String
247 
248  \author wk
249  \date 02.02.2011
250  */
251  template<bool Const,bool Forward>
252  class Iterator
253  {
254  typedef typename std::conditional< Const, const char, char >::type Char;
255  class Impl;
256  Impl *pimpl_;
257 
258  public:
259  typedef std::random_access_iterator_tag iterator_category;
260  typedef char value_type;
261  typedef String::difference_type difference_type;
262  typedef Char& reference;
263  typedef Char* pointer;
265 
266  Iterator();
267  Iterator( const Iterator& other );
268  operator ConstIterator() const;
269  ~Iterator();
270  Iterator &operator= ( const Iterator& other );
271  reference operator* () const;
272  pointer operator->() const;
273  Iterator& operator++();
274  Iterator operator++(int);
275  Iterator& operator--();
276  Iterator operator--(int);
277  Iterator& operator+=( difference_type offset );
278  Iterator operator+ ( difference_type offset ) const;
279  Iterator& operator-=( difference_type offset );
280  Iterator operator- ( difference_type offset ) const;
281  difference_type operator-( const Iterator<true, Forward>& other ) const;
282  difference_type operator-( const Iterator<false,Forward>& other ) const;
283  reference operator[]( difference_type offset ) const;
284 
285  bool operator==( const Iterator<true, Forward>& other ) const;
286  bool operator==( const Iterator<false,Forward>& other ) const;
287  bool operator!=( const Iterator<true, Forward>& other ) const;
288  bool operator!=( const Iterator<false,Forward>& other ) const;
289  bool operator< ( const Iterator<true, Forward>& other ) const;
290  bool operator< ( const Iterator<false,Forward>& other ) const;
291  bool operator> ( const Iterator<true, Forward>& other ) const;
292  bool operator> ( const Iterator<false,Forward>& other ) const;
293  bool operator<=( const Iterator<true, Forward>& other ) const;
294  bool operator<=( const Iterator<false,Forward>& other ) const;
295  bool operator>=( const Iterator<true, Forward>& other ) const;
296  bool operator>=( const Iterator<false,Forward>& other ) const;
297  };
298 
299  };
300 
301  /// \relatesalso String
302  OPALS_API String operator+(const String& s1, const String& s2);
303  /// \relatesalso String
304  OPALS_API String operator+(const char* s1, const String& s2);
305  /// \relatesalso String
306  OPALS_API String operator+(const String& s1, const char* s2);
307  /// \relatesalso String
308  OPALS_API String operator+(char c, const String& s2);
309  /// \relatesalso String
310  OPALS_API String operator+(const String& s1, char c);
311 
312  /// \relatesalso String
313  OPALS_API bool operator==(const String& s1, const String& s2);
314  /// \relatesalso String
315  OPALS_API bool operator==(const char* s1, const String& s2);
316  /// \relatesalso String
317  OPALS_API bool operator==(const String& s1, const char* s2);
318 
319  /// \relatesalso String
320  OPALS_API bool operator!=(const String& s1, const String& s2);
321  /// \relatesalso String
322  OPALS_API bool operator!=(const char* s1, const String& s2);
323  /// \relatesalso String
324  OPALS_API bool operator!=(const String& s1, const char* s2);
325 
326  /// \relatesalso String
327  OPALS_API bool operator<(const String& s1, const String& s2);
328  /// \relatesalso String
329  OPALS_API bool operator<(const char* s1, const String& s2);
330  /// \relatesalso String
331  OPALS_API bool operator<(const String& s1, const char* s2);
332 
333  /// \relatesalso String
334  OPALS_API void swap(String& s1, String& s2);
335 
336 }
337 
338 #endif