Rumba C++ SDK
StringView.h
Go to the documentation of this file.
1 /*
2 
3  *
4  ***
5  *****
6  ********************* Mercenaries Engineering SARL
7  ***************** Copyright (C) 2020
8  *************
9  ********* http://www.mercenaries-engineering.com
10  ***********
11  **** ****
12  ** **
13 
14 */
15 #pragma once
16 
17 #include <assert.h>
18 #include <string>
19 #include <vector>
20 #include <stdexcept>
21 #include <cstring>
22 
23 namespace maquina
24 {
25  // * This string view holds a 0 terminated string.
26  template<class C, class STDS>
28  public:
29  typedef std::char_traits<C> traits_type;
30  typedef C value_type;
31  typedef const C* pointer;
32  typedef const C* const_pointer;
33  typedef const C& reference;
34  typedef const C& const_reference;
37  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
39  typedef size_t size_type;
40  typedef ptrdiff_t difference_type;
41  static const size_type npos = size_type(-1);
42 
43  StringViewBase() noexcept
44  : _str{""}, _size{0}
45  {}
46 
47  StringViewBase( const StringViewBase& other ) noexcept = default;
48 
49  StringViewBase( StringViewBase&& other ) noexcept
50  : _str{ other._str }, _size{other._size}
51  {}
52 
53  StringViewBase& operator=( const StringViewBase& other ) noexcept = default;
54 
56  {
57  _str = other._str;
58  _size = other._size;
59  return *this;
60  }
61 
62  StringViewBase( const C* str ) noexcept
63  : _str{ str }, _size{strlen(str)}
64  {}
65 
66  StringViewBase( const std::basic_string<C>& string ) noexcept
67  : _str{ string.data() }, _size{ string.size() }
68  {}
69 
71  StringViewBase( const C* str, size_t size_ ) noexcept
72  : _str{str}, _size{size_}
73  {
74  assert(_size == strlen(_str));
75  }
76 
77  StringViewBase& operator=( const std::basic_string<C>& string ) noexcept
78  {
79  _str = string.data();
80  _size = string.size();
81  return *this;
82  }
83 
84  iterator begin() const noexcept
85  {
86  return cbegin();
87  }
88 
89  iterator end() const noexcept
90  {
91  return cend();
92  }
93 
94  const_iterator cbegin() const noexcept
95  {
96  return _str;
97  }
98 
99  const_iterator cend() const noexcept
100  {
101  return _str + _size;
102  }
103 
104  size_type size() const noexcept
105  {
106  return _size;
107  }
108 
109  size_type length() const noexcept
110  {
111  return size_type(strlen(_str));
112  }
113 
114  const_pointer data() const noexcept
115  {
116  return _str;
117  }
118 
119  pointer data() noexcept
120  {
121  return _str;
122  }
123 
124  const_pointer c_str() const noexcept
125  {
126  return _str;
127  }
128 
129  pointer c_str() noexcept
130  {
131  return _str;
132  }
133 
134  bool empty() const noexcept
135  {
136  return _size == size_type(0);
137  }
138 
139  bool operator==( const StringViewBase& other ) const noexcept
140  {
141  return other._size == _size
142  && traits_type::compare( _str, other._str, _size ) == 0;
143  }
144 
145  bool operator!=( const StringViewBase& other ) const noexcept
146  {
147  return other._size != _size
148  || traits_type::compare( _str, other._str, _size ) != 0;
149  }
150 
151  size_type find( value_type c, size_type pos = 0 ) const noexcept
152  {
153  size_type result = npos;
154  if( pos < _size )
155  {
156  const value_type* p = traits_type::find( _str + pos, _size - pos, c );
157  if( p )
158  result = p - _str;
159  }
160  return result;
161  }
162 
163  size_type find( const StringViewBase& pattern, size_type pos = 0 ) const noexcept
164  {
165  const auto pattern_size = pattern.size();
166  if( pattern_size == 0 )
167  return pos <= _size ? pos : npos;
168 
169  if( pattern_size <= _size )
170  {
171  for( ; pos <= _size - pattern_size; ++ pos )
172  {
173  if( traits_type::eq( _str[ pos ], pattern._str[0] )
174  && traits_type::compare( _str + pos + 1,
175  pattern._str + 1, pattern_size -1 ) == 0 )
176  return pos;
177  }
178  }
179  return npos;
180  }
181 
182  size_type
183  rfind( value_type c, size_type pos = npos ) const noexcept
184  {
185  size_type __size = _size;
186  if( __size )
187  {
188  if( --__size > pos )
189  __size = pos;
190  for( ++__size; __size-- > 0; )
191  if( traits_type::eq( _str[ __size ], c ) )
192  return __size;
193  }
194  return npos;
195  }
196 
197  size_type
198  rfind( const StringViewBase& pattern, size_type pos = npos ) const noexcept
199  {
200  const size_type __size = _size;
201  const size_type __n = pattern.size();
202  const value_type* __s = pattern.data();
203  if( __n <= __size )
204  {
205  pos = std::min( size_type(__size - __n), pos);
206  const value_type* __data = _str;
207  do
208  {
209  if( traits_type::compare( __data + pos, __s, __n ) == 0 )
210  return pos;
211  }
212  while( pos -- > 0 );
213  }
214  return npos;
215  }
216 
217  STDS substr( size_type pos = 0, size_type n = npos) const
218  {
219  if( pos > _size )
220  throw std::out_of_range("StringViewBase::substr");
221  size_type len = std::min( n, _size - pos );
222  return STDS( _str + pos, len );
223  }
224 
225  // FIXME: this implementation skips empty sub-parts
226  std::vector< STDS > split( StringViewBase separator ) const
227  {
228  std::vector< STDS > splitted;
229  size_type prev_pos = 0, pos = 0;
230  const auto separator_size = separator.size();
231  while( (pos = find( separator, pos ) ) != npos )
232  {
233  if( prev_pos != pos )
234  splitted.emplace_back( substr( prev_pos, pos - prev_pos ) );
235  pos += separator_size;
236  prev_pos = pos;
237  }
238  if( prev_pos != _size )
239  splitted.emplace_back( substr( prev_pos ) );
240  return splitted;
241  }
242 
243  value_type operator[]( size_type position ) const
244  {
245  return _str[ position ];
246  }
247 
248  operator STDS() const
249  {
250  return STDS( _str );
251  }
252 
253  protected:
254  const value_type* _str;
256  };
257 
258  template<class C, class STDS>
260 
261  size_t operator()( const StringViewBase<C, STDS>& str ) const noexcept
262  {
263  size_t result = static_cast<size_t>(0xc70f6907UL);
264  for( const auto& c : str )
265  {
266  hash_combine( result, c );
267  }
268  return result;
269  }
270  };
271 
272  template<class C, class STDS>
273  inline bool
274  operator==( const C* str, const StringViewBase<C, STDS>& sv ) noexcept
275  {
276  return sv.size() == StringViewBase<C, STDS>::traits_type::length( str )
277  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) == 0;
278  }
279 
280  template<class C, class STDS>
281  inline bool
282  operator==( const StringViewBase<C, STDS>& sv, const C* str ) noexcept
283  {
284  return sv.size() == StringViewBase<C, STDS>::traits_type::length( str )
285  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) == 0;
286  }
287 
288  template<class C, class STDS>
289  inline bool
290  operator==( const StringViewBase<C, STDS>& sv, const STDS& s ) noexcept
291  {
292  return sv.size() == s.size()
293  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) == 0;
294  }
295 
296  template<class C, class STDS>
297  inline bool
298  operator==( const STDS& s, const StringViewBase<C, STDS>& sv ) noexcept
299  {
300  return sv.size() == s.size()
301  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) == 0;
302  }
303 
304  template<class C, class STDS>
305  inline bool
306  operator!=( const C* str, const StringViewBase<C, STDS>& sv ) noexcept
307  {
308  return sv.size() != StringViewBase<C, STDS>::traits_type::length( str )
309  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) != 0;
310  }
311 
312  template<class C, class STDS>
313  inline bool
314  operator!=( const StringViewBase<C, STDS>& sv, const C* str ) noexcept
315  {
316  return sv.size() != StringViewBase<C, STDS>::traits_type::length( str )
317  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) != 0;
318  }
319 
320  template<class C, class STDS>
321  inline bool
322  operator!=( const StringViewBase<C, STDS>& sv, const STDS& s ) noexcept
323  {
324  return sv.size() != s.size()
325  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) != 0;
326  }
327 
328  template<class C, class STDS>
329  inline bool
330  operator!=( const STDS& s, const StringViewBase<C, STDS>& sv ) noexcept
331  {
332  return sv.size() != s.size()
333  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) != 0;
334  }
335 
336  template<class C, class STDS>
337  inline bool
338  operator<( const StringViewBase<C, STDS> &a, const StringViewBase<C, STDS>& b ) noexcept
339  {
341  a.data(), b.data(), std::min( a.size(), b.size() ) );
342  if( result == 0 )
343  return a.size() < b.size();
344  return result < 0;
345  }
346 
347  template<class _CharT, class _Traits, class C, class STDS>
348  std::basic_ostream<_CharT, _Traits>&
349  operator<<(std::basic_ostream<_CharT, _Traits>& os, const StringViewBase<C, STDS>& sv )
350  {
351  for( const auto& c : sv )
352  os << c;
353  return os;
354  }
355 
356  template<class C, class STDS>
358  {
359  using is_transparent = void;
360 
361  bool
363  {
365  a.data(), b.data(), std::min( a.size(), b.size() ) );
366 
367  if( result == 0 )
368  {
369  const typename StringViewBase<C, STDS>::difference_type diff = a.size() - b.size();
370  return diff < 0;
371  }
372  return result < 0;
373  }
374  };
375 
378 
381 }
const C * pointer
Definition: StringView.h:31
const value_type * _str
Definition: StringView.h:254
size_type find(const StringViewBase &pattern, size_type pos=0) const noexcept
Definition: StringView.h:163
bool operator()(const StringViewBase< C, STDS > &a, const StringViewBase< C, STDS > &b) const
Definition: StringView.h:362
StringViewBase(const C *str, size_t size_) noexcept
Warning, size_ MUST be strlen(str).
Definition: StringView.h:71
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: StringView.h:37
StringViewBase & operator=(const std::basic_string< C > &string) noexcept
Definition: StringView.h:77
const_pointer c_str() const noexcept
Definition: StringView.h:124
Definition: StringView.h:27
const_iterator cend() const noexcept
Definition: StringView.h:99
StringViewBase(const std::basic_string< C > &string) noexcept
Definition: StringView.h:66
size_type length() const noexcept
Definition: StringView.h:109
const C & reference
Definition: StringView.h:33
const_pointer data() const noexcept
Definition: StringView.h:114
iterator begin() const noexcept
Definition: StringView.h:84
bool empty() const noexcept
Definition: StringView.h:134
size_type rfind(value_type c, size_type pos=npos) const noexcept
Definition: StringView.h:183
static const size_type npos
Definition: StringView.h:41
StringViewBase(StringViewBase &&other) noexcept
Definition: StringView.h:49
const C * const_pointer
Definition: StringView.h:32
size_t operator()(const StringViewBase< C, STDS > &str) const noexcept
Definition: StringView.h:261
bool operator==(const StringViewBase &other) const noexcept
Definition: StringView.h:139
This version of the SDK is unstable, i-e, it may change with no warning.
Definition: AddCurveAction.h:20
StringViewBase< char, std::string > StringView
Definition: StringView.h:376
pointer c_str() noexcept
Definition: StringView.h:129
StringViewHasherBase< char, std::string > StringViewHasher
Definition: StringView.h:377
ptrdiff_t difference_type
Definition: StringView.h:40
StringViewBase() noexcept
Definition: StringView.h:43
iterator end() const noexcept
Definition: StringView.h:89
StringViewBase< wchar_t, std::wstring > WStringView
Definition: StringView.h:379
size_type _size
Definition: StringView.h:255
StringViewHasherBase< wchar_t, std::wstring > WStringViewHasher
Definition: StringView.h:380
std::char_traits< C > traits_type
Definition: StringView.h:29
bool operator!=(const C *str, const StringViewBase< C, STDS > &sv) noexcept
Definition: StringView.h:306
bool operator!=(const StringViewBase &other) const noexcept
Definition: StringView.h:145
bool operator==(const C *str, const StringViewBase< C, STDS > &sv) noexcept
Definition: StringView.h:274
const_pointer const_iterator
Definition: StringView.h:35
size_t size_type
Definition: StringView.h:39
Definition: StringView.h:357
value_type operator[](size_type position) const
Definition: StringView.h:243
Definition: StringView.h:259
const_iterator iterator
Definition: StringView.h:36
const_iterator cbegin() const noexcept
Definition: StringView.h:94
void is_transparent
Definition: StringView.h:359
const C & const_reference
Definition: StringView.h:34
pointer data() noexcept
Definition: StringView.h:119
const_reverse_iterator reverse_iterator
Definition: StringView.h:38
STDS substr(size_type pos=0, size_type n=npos) const
Definition: StringView.h:217
size_type find(value_type c, size_type pos=0) const noexcept
Definition: StringView.h:151
StringViewBase & operator=(const StringViewBase &other) noexcept=default
size_type rfind(const StringViewBase &pattern, size_type pos=npos) const noexcept
Definition: StringView.h:198
StringViewBase(const C *str) noexcept
Definition: StringView.h:62
C value_type
Definition: StringView.h:30
StringViewBase & operator=(StringViewBase &&other) noexcept
Definition: StringView.h:55
size_type size() const noexcept
Definition: StringView.h:104
std::vector< STDS > split(StringViewBase separator) const
Definition: StringView.h:226