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  std::vector< STDS > split( StringViewBase separator ) const
226  {
227  std::vector< STDS > splitted;
228  size_type prev_pos = 0, pos = 0;
229  const auto separator_size = separator.size();
230  while( (pos = find( separator, pos ) ) != npos )
231  {
232  if( prev_pos != pos )
233  splitted.emplace_back( substr( prev_pos, pos - prev_pos ) );
234  pos += separator_size;
235  prev_pos = pos;
236  }
237  if( prev_pos != _size )
238  splitted.emplace_back( substr( prev_pos ) );
239  return splitted;
240  }
241 
242  value_type operator[]( size_type position ) const
243  {
244  return _str[ position ];
245  }
246 
247  operator STDS() const
248  {
249  return STDS( _str );
250  }
251 
252  protected:
253  const value_type* _str;
255  };
256 
257  template<class C, class STDS>
259 
260  size_t operator()( const StringViewBase<C, STDS>& str ) const noexcept
261  {
262  size_t result = static_cast<size_t>(0xc70f6907UL);
263  for( const auto& c : str )
264  {
265  hash_combine( result, c );
266  }
267  return result;
268  }
269  };
270 
271  template<class C, class STDS>
272  inline bool
273  operator==( const C* str, const StringViewBase<C, STDS>& sv ) noexcept
274  {
275  return sv.size() == StringViewBase<C, STDS>::traits_type::length( str )
276  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) == 0;
277  }
278 
279  template<class C, class STDS>
280  inline bool
281  operator==( const StringViewBase<C, STDS>& sv, const C* str ) noexcept
282  {
283  return sv.size() == StringViewBase<C, STDS>::traits_type::length( str )
284  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) == 0;
285  }
286 
287  template<class C, class STDS>
288  inline bool
289  operator==( const StringViewBase<C, STDS>& sv, const STDS& s ) noexcept
290  {
291  return sv.size() == s.size()
292  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) == 0;
293  }
294 
295  template<class C, class STDS>
296  inline bool
297  operator==( const STDS& s, const StringViewBase<C, STDS>& sv ) noexcept
298  {
299  return sv.size() == s.size()
300  && StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) == 0;
301  }
302 
303  template<class C, class STDS>
304  inline bool
305  operator!=( const C* str, const StringViewBase<C, STDS>& sv ) noexcept
306  {
307  return sv.size() != StringViewBase<C, STDS>::traits_type::length( str )
308  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) != 0;
309  }
310 
311  template<class C, class STDS>
312  inline bool
313  operator!=( const StringViewBase<C, STDS>& sv, const C* str ) noexcept
314  {
315  return sv.size() != StringViewBase<C, STDS>::traits_type::length( str )
316  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), str, sv.size() ) != 0;
317  }
318 
319  template<class C, class STDS>
320  inline bool
321  operator!=( const StringViewBase<C, STDS>& sv, const STDS& s ) noexcept
322  {
323  return sv.size() != s.size()
324  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) != 0;
325  }
326 
327  template<class C, class STDS>
328  inline bool
329  operator!=( const STDS& s, const StringViewBase<C, STDS>& sv ) noexcept
330  {
331  return sv.size() != s.size()
332  || StringViewBase<C, STDS>::traits_type::compare( sv.data(), s.data(), sv.size() ) != 0;
333  }
334 
335  template<class C, class STDS>
336  inline bool
337  operator<( const StringViewBase<C, STDS> &a, const StringViewBase<C, STDS>& b ) noexcept
338  {
340  a.data(), b.data(), std::min( a.size(), b.size() ) );
341  if( result == 0 )
342  return a.size() < b.size();
343  return result < 0;
344  }
345 
346  template<class _CharT, class _Traits, class C, class STDS>
347  std::basic_ostream<_CharT, _Traits>&
348  operator<<(std::basic_ostream<_CharT, _Traits>& os, const StringViewBase<C, STDS>& sv )
349  {
350  for( const auto& c : sv )
351  os << c;
352  return os;
353  }
354 
355  template<class C, class STDS>
357  {
358  using is_transparent = void;
359 
360  bool
362  {
364  a.data(), b.data(), std::min( a.size(), b.size() ) );
365 
366  if( result == 0 )
367  {
368  const typename StringViewBase<C, STDS>::difference_type diff = a.size() - b.size();
369  return diff < 0;
370  }
371  return result < 0;
372  }
373  };
374 
377 
380 }
const C * pointer
Definition: StringView.h:31
const value_type * _str
Definition: StringView.h:253
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:361
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:260
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:375
pointer c_str() noexcept
Definition: StringView.h:129
StringViewHasherBase< char, std::string > StringViewHasher
Definition: StringView.h:376
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:378
size_type _size
Definition: StringView.h:254
StringViewHasherBase< wchar_t, std::wstring > WStringViewHasher
Definition: StringView.h:379
std::char_traits< C > traits_type
Definition: StringView.h:29
bool operator!=(const C *str, const StringViewBase< C, STDS > &sv) noexcept
Definition: StringView.h:305
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:273
const_pointer const_iterator
Definition: StringView.h:35
size_t size_type
Definition: StringView.h:39
Definition: StringView.h:356
value_type operator[](size_type position) const
Definition: StringView.h:242
Definition: StringView.h:258
const_iterator iterator
Definition: StringView.h:36
const_iterator cbegin() const noexcept
Definition: StringView.h:94
void is_transparent
Definition: StringView.h:358
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:225