nlib
StringView.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_STRINGVIEW_H_
4 #define INCLUDE_NN_NLIB_STRINGVIEW_H_
5 
6 #include <algorithm>
7 #include <iterator>
8 
9 #include "nn/nlib/Config.h"
10 #include "nn/nlib/UniquePtr.h"
11 #include "nn/nlib/Cstring.h"
12 
13 NLIB_NAMESPACE_BEGIN
14 
15 class StringView {
16  public:
17  // types
18  typedef char charT;
19  typedef charT value_type;
20  typedef const charT* pointer;
21  typedef const charT* const_pointer;
22  typedef const charT& reference;
23  typedef const charT& const_reference;
24  typedef const_pointer const_iterator;
25  typedef const_iterator iterator;
26  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
27  typedef const_reverse_iterator reverse_iterator;
28  typedef size_t size_type;
29  typedef ptrdiff_t difference_type;
30  static const size_type npos = size_type(-1);
31 
32  // [string.view.cons], construct/copy
33  NLIB_CEXPR StringView() NLIB_NOEXCEPT : m_Len(0), m_Base("") {}
34  // this ctor calls strlen(), use StringView(str, len) if you know the the length of the string.
35  explicit StringView(const charT* str) NLIB_NOEXCEPT : m_Len(nlib_strlen(str)), m_Base(str) {
36  NLIB_ASSERT(this->IsValid_());
37  }
38  StringView(const charT* str, size_type len) NLIB_NOEXCEPT : m_Len(len), m_Base(str) {
39  NLIB_ASSERT(this->IsValid_());
40  }
41 
42  // [string.view.iterators], iterators
43  const_iterator begin() const NLIB_NOEXCEPT {
44  NLIB_ASSERT(this->IsValid_());
45  return m_Base;
46  }
47  const_iterator end() const NLIB_NOEXCEPT { return begin() + m_Len; }
48  const_iterator cbegin() const NLIB_NOEXCEPT { return begin(); }
49  const_iterator cend() const NLIB_NOEXCEPT { return cbegin() + m_Len; }
50 
51  const_reverse_iterator rbegin() const NLIB_NOEXCEPT { return const_reverse_iterator(end()); }
52  const_reverse_iterator rend() const NLIB_NOEXCEPT { return const_reverse_iterator(begin()); }
53  const_reverse_iterator crbegin() const NLIB_NOEXCEPT { return const_reverse_iterator(end()); }
54  const_reverse_iterator crend() const NLIB_NOEXCEPT { return const_reverse_iterator(begin()); }
55 
56  // [string.view.capacity], capacity
57  size_type size() const NLIB_NOEXCEPT {
58  NLIB_ASSERT(this->IsValid_());
59  return m_Len;
60  }
61  size_type length() const NLIB_NOEXCEPT {
62  NLIB_ASSERT(this->IsValid_());
63  return m_Len;
64  }
65  size_type max_size() const NLIB_NOEXCEPT { return static_cast<size_type>(-1) / sizeof(charT); }
66  bool empty() const NLIB_NOEXCEPT { return this->size() == 0; }
67 
68  // [string.view.access], element access
69  const charT& operator[](size_type pos) const {
70  NLIB_ASSERT(this->IsValid_());
71  return m_Base[pos];
72  }
73  const charT& at(size_type pos) const {
74  NLIB_ASSERT(this->IsValid_());
75  return m_Base[pos];
76  }
77  const charT& front() const { return (*this)[0]; }
78  const charT& back() const { return (*this)[this->length() - 1]; }
79  const charT* data() const NLIB_NOEXCEPT { return m_Base; }
80 
81  // [string.view.modifiers], modifiers:
83  m_Len = 0;
84  m_Base = "";
85  }
86  void remove_prefix(size_type n) NLIB_NOEXCEPT {
87  if (n >= m_Len) {
88  m_Base += m_Len;
89  m_Len = 0;
90  } else {
91  m_Base += n;
92  m_Len -= n;
93  }
94  }
95  void remove_suffix(size_type n) NLIB_NOEXCEPT {
96  if (n >= m_Len) {
97  m_Len = 0;
98  } else {
99  m_Len -= n;
100  }
101  }
102 
103  // [string.view.ops], string operations:
104  StringView substr(size_type pos, size_type n = npos) const NLIB_NOEXCEPT {
105  NLIB_ASSERT(this->IsValid_());
106  if (pos >= m_Len) return StringView(m_Base + m_Len, 0);
107  const charT* newBase = m_Base + pos;
108  size_type r = static_cast<size_type>(m_Len - pos);
109  size_type newLen = r > n ? n : r;
110  return StringView(newBase, newLen);
111  }
112  NLIB_VIS_PUBLIC int compare(const StringView& s) const NLIB_NOEXCEPT;
113  int compare(const charT* s) const NLIB_NOEXCEPT { return this->compare(StringView(s)); }
114  bool starts_with(const StringView& s) const NLIB_NOEXCEPT {
115  NLIB_ASSERT(this->IsValid_());
116  if (s.length() > this->length()) return false;
117  return nlib_memcmp(s.data(), m_Base, sizeof(*m_Base) * s.length()) == 0;
118  }
119  bool starts_with(charT c) const NLIB_NOEXCEPT { return front() == c; }
120  bool starts_with(const charT* s) const NLIB_NOEXCEPT {
121  return this->starts_with(StringView(s));
122  }
123  bool ends_with(const StringView& s) const NLIB_NOEXCEPT {
124  NLIB_ASSERT(this->IsValid_());
125  if (s.length() > m_Len) return false;
126  return nlib_memcmp(s.data(), m_Base + m_Len - s.length(), sizeof(*m_Base) * s.length()) ==
127  0;
128  }
129  bool ends_with(charT c) const NLIB_NOEXCEPT { return back() == c; }
130  bool ends_with(const charT* s) const NLIB_NOEXCEPT { return this->ends_with(StringView(s)); }
131 
132  NLIB_VIS_PUBLIC bool ToCstring(charT* str, size_type bufSize) const NLIB_NOEXCEPT;
133  template <size_type N>
134  bool ToCstring(charT (&str)[N]) const NLIB_NOEXCEPT {
135  return ToCstring(str, N);
136  }
137  NLIB_VIS_PUBLIC bool ToCstring(UniquePtr<charT[]>* str) const NLIB_NOEXCEPT;
138 
139  NLIB_VIS_PUBLIC errno_t ToInteger(int32_t* v, size_type* idx = NULL,
140  int base = 10) const NLIB_NOEXCEPT;
141  NLIB_VIS_PUBLIC errno_t ToInteger(int64_t* v, size_type* idx = NULL,
142  int base = 10) const NLIB_NOEXCEPT;
143  NLIB_VIS_PUBLIC errno_t ToInteger(uint32_t* v, size_type* idx = NULL,
144  int base = 10) const NLIB_NOEXCEPT;
145  NLIB_VIS_PUBLIC errno_t ToInteger(uint64_t* v, size_type* idx = NULL,
146  int base = 10) const NLIB_NOEXCEPT;
147  errno_t ToInteger(int8_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
148  errno_t ToInteger(int16_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
149  errno_t ToInteger(uint8_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
150  errno_t ToInteger(uint16_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
151  NLIB_VIS_PUBLIC errno_t ToFloat(float* v, size_type* idx = NULL) const NLIB_NOEXCEPT;
152  NLIB_VIS_PUBLIC errno_t ToDouble(double* v, size_type* idx = NULL) const NLIB_NOEXCEPT;
153 
154  NLIB_VIS_PUBLIC bool TrimLeft() NLIB_NOEXCEPT;
155  NLIB_VIS_PUBLIC bool TrimRight() NLIB_NOEXCEPT;
156  void Trim() NLIB_NOEXCEPT {
157  TrimLeft();
158  TrimRight();
159  }
160  NLIB_VIS_PUBLIC StringView GetLine() NLIB_NOEXCEPT;
161  bool Proceed(const StringView& kwd) NLIB_NOEXCEPT {
162  if (!this->starts_with(kwd)) return false;
163  m_Base += kwd.length();
164  m_Len -= kwd.length();
165  return true;
166  }
167  bool Proceed(const charT* kwd) NLIB_NOEXCEPT { return this->Proceed(StringView(kwd)); }
168  bool Proceed(charT ch) NLIB_NOEXCEPT;
169  StringView GetName() NLIB_NOEXCEPT;
170  /*
171  size_type find(const StringView& s) const {
172  StringView::iterator it = std::search(
173  begin(), end(), s.begin(), s.end());
174  return it == end() ? npos : it - begin();
175  }
176  size_type find(charT c) const;
177  size_type find(const charT* s) const;
178  size_type rfind(const StringView& s) const {
179  StringView::iterator it = std::find_end(
180  begin(), end(), s.begin(), s.end());
181  return it == end() ? npos : it - begin();
182  }
183  size_type rfind(charT c) const;
184  size_type rfind(const charT* s) const;
185  size_type find_first_of(const StringView& s) const {
186  StringView::iterator it = std::find_first_of(
187  begin(), end(), s.begin(), s.end());
188  return it == end() ? npos : it - begin();
189  }
190  size_type find_first_of(charT c) const;
191  size_type find_first_of(const charT* s) const;
192  size_type find_last_of(const StringView& s) const {
193  StringView::reverse_iterator it = std::find_first_of(
194  rbegin(), rend(), s.begin(), s.end());
195  return it == rend() ? std::string::npos : it.base() - 1 - begin();
196  }
197  size_type find_last_of(charT c) const;
198  size_type find_last_of(const charT* s) const;
199  size_type find_first_not_of(const StringView& s) const;
200  size_type find_first_not_of(charT c) const;
201  size_type find_first_not_of(const charT* s) const;
202  size_type find_last_not_of(const StringView& s) const;
203  size_type find_last_not_of(charT c) const;
204  size_type find_last_not_of(const charT* s) const;
205  */
206 
207  private:
208  bool IsValid_() const NLIB_NOEXCEPT {
209  if (!m_Base) return false;
210  return true;
211  }
212  size_type m_Len;
213  const charT* m_Base;
214 };
215 
216 inline errno_t StringView::ToInteger(int8_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
217  int32_t tmp;
218  errno_t e = ToInteger(&tmp, idx, base);
219  if (e != 0) return e;
220  if (tmp > 127 || tmp < -128) return ERANGE;
221  *v = static_cast<int8_t>(tmp);
222  return 0;
223 }
224 
225 inline errno_t StringView::ToInteger(int16_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
226  int32_t tmp;
227  errno_t e = ToInteger(&tmp, idx, base);
228  if (e != 0) return e;
229  if (tmp > 32767 || tmp < -32768) return ERANGE;
230  *v = static_cast<int16_t>(tmp);
231  return 0;
232 }
233 
234 inline errno_t StringView::ToInteger(uint8_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
235  uint32_t tmp;
236  errno_t e = ToInteger(&tmp, idx, base);
237  if (e != 0) return e;
238  if (tmp > 255) return ERANGE;
239  *v = static_cast<uint8_t>(tmp);
240  return 0;
241 }
242 
243 inline errno_t StringView::ToInteger(uint16_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
244  uint32_t tmp;
245  errno_t e = ToInteger(&tmp, idx, base);
246  if (e != 0) return e;
247  if (tmp > 65535) return ERANGE;
248  *v = static_cast<uint16_t>(tmp);
249  return 0;
250 }
251 
252 inline bool StringView::Proceed(charT ch) NLIB_NOEXCEPT {
253  if (this->starts_with(ch)) {
254  ++m_Base;
255  --m_Len;
256  return true;
257  } else {
258  return false;
259  }
260 }
261 
262 inline StringView StringView::GetName() NLIB_NOEXCEPT {
263  // isalpha()[isalnum()]*
264  NLIB_ASSERT(this->IsValid_());
265  const charT* s = m_Base;
266  const charT* s_end = m_Base + m_Len;
267  charT c = (s != s_end) ? *s : '\0';
268  if (!IsAlpha(c) && c != '_') return *this;
269  for (;;) {
270  ++s;
271  c = (s != s_end) ? *s : '\0';
272  if (!IsAlnum(c) && c != '_') break;
273  }
274  size_type len = s - m_Base;
275  StringView rval(m_Base, len);
276  m_Base = s;
277  m_Len = m_Len - len;
278  return rval;
279 }
280 
281 // [string.view.comparison], non-member StringView comparison functions
282 inline bool operator==(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
283  return lhs.compare(rhs) == 0;
284 }
285 inline bool operator!=(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
286  return !(lhs == rhs);
287 }
288 inline bool operator<(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
289  return lhs.compare(rhs) < 0;
290 }
291 inline bool operator>(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
292  return lhs.compare(rhs) > 0;
293 }
294 inline bool operator<=(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
295  return lhs.compare(rhs) <= 0;
296 }
297 inline bool operator>=(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
298  return lhs.compare(rhs) >= 0;
299 }
300 
301 NLIB_NAMESPACE_END
302 
303 #endif // INCLUDE_NN_NLIB_STRINGVIEW_H_
void remove_prefix(size_type n) noexcept
Removes the first n characters.
Definition: StringView.h:86
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Platform.h:2151
std::reverse_iterator< const_iterator > const_reverse_iterator
A string reverse iterator.
Definition: StringView.h:26
size_type max_size() const noexcept
Returns the maximum value for the string length.
Definition: StringView.h:65
size_t size_type
A non-negative integer type, currently defined in size_t using typedef.
Definition: StringView.h:28
const_iterator end() const noexcept
Returns the iterator pointing to the character following the last character.
Definition: StringView.h:47
void clear() noexcept
Sets an empty string.
Definition: StringView.h:82
ptrdiff_t difference_type
The type returned when you take the difference between iterators.
Definition: StringView.h:29
const_iterator cbegin() const noexcept
Returns the iterator pointing to the first character.
Definition: StringView.h:48
const charT & front() const
Gets the first character.
Definition: StringView.h:77
const_reverse_iterator crend() const noexcept
Returns the reverse iterator pointing to the character before the first character.
Definition: StringView.h:54
int nlib_memcmp(const void *buf1, const void *buf2, size_t n)
Compares the n bytes from the starts of buf1 and buf2 as unsigned char data.
bool starts_with(const StringView &s) const noexcept
Checks whether the string has s as its prefix.
Definition: StringView.h:114
size_type length() const noexcept
Returns the length of the string.
Definition: StringView.h:61
int IsAlnum(int c) noexcept
Returns std::isalnum(static_cast(c)).
Definition: Cstring.h:197
UniquePtr owns the pointer, and when it goes out of scope, the pointer is released by the destructor ...
Definition: UniquePtr.h:96
bool operator<=(const StringView &lhs, const StringView &rhs) noexcept
Compares strings in dictionary order.
Definition: StringView.h:294
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
Definition: NMalloc.h:101
Defines that class that is corresponding to std::unique_ptr.
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are not equal.
Definition: NMalloc.h:106
char charT
Currently a char-type specific class.
Definition: StringView.h:18
const charT & back() const
Gets the last character.
Definition: StringView.h:78
constexpr StringView() noexcept
Instantiates the object with default parameters (default constructor). Initialized as an empty string...
Definition: StringView.h:33
const charT & operator[](size_type pos) const
Gets the nth character, where n is specified by pos.
Definition: StringView.h:69
bool empty() const noexcept
Checks whether it is an empty string.
Definition: StringView.h:66
int IsAlpha(int c) noexcept
Returns std::isalpha(static_cast(c)).
Definition: Cstring.h:198
const charT * pointer
The type for a character pointer. The same as const_pointer.
Definition: StringView.h:20
const_iterator iterator
A string iterator. The same as const_iterator.
Definition: StringView.h:25
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
bool operator<(const StringView &lhs, const StringView &rhs) noexcept
Compares strings in dictionary order.
Definition: StringView.h:288
const charT & at(size_type pos) const
Gets the nth character, where n is specified by pos.
Definition: StringView.h:73
bool ToCstring(charT(&str)[N]) const noexcept
Definition: StringView.h:134
const_reverse_iterator reverse_iterator
A string reverse iterator. The same as const_reverse_iterator.
Definition: StringView.h:27
bool operator>=(const StringView &lhs, const StringView &rhs) noexcept
Compares strings in dictionary order.
Definition: StringView.h:297
const_reverse_iterator crbegin() const noexcept
Returns the reverse iterator pointing to the last character.
Definition: StringView.h:53
StringView(const charT *str, size_type len) noexcept
Initializes using the specified calculated string length.
Definition: StringView.h:38
A file that contains the configuration information for each development environment.
int compare(const charT *s) const noexcept
Compares strings.
Definition: StringView.h:113
StringView substr(size_type pos, size_type n=npos) const noexcept
Returns a substring [pos, pos + n).
Definition: StringView.h:104
const_pointer const_iterator
A character string iterator.
Definition: StringView.h:24
const charT * data() const noexcept
Returns the pointer to the first character.
Definition: StringView.h:79
The class for using the member functions of std::string without constructing std::string.
Definition: StringView.h:15
size_type size() const noexcept
Returns the length of the string.
Definition: StringView.h:57
bool operator>(const StringView &lhs, const StringView &rhs) noexcept
Compares strings in dictionary order.
Definition: StringView.h:291
const_reverse_iterator rbegin() const noexcept
Returns the reverse iterator pointing to the last character.
Definition: StringView.h:51
void remove_suffix(size_type n) noexcept
Removes the last n characters.
Definition: StringView.h:95
size_t nlib_strlen(const char *s)
Internally calls strlen(). In some cases, it may operate as an independent implementation.
const_iterator begin() const noexcept
Returns the iterator pointing to the first character.
Definition: StringView.h:43
const charT * const_pointer
The type for a character pointer.
Definition: StringView.h:21
const charT & const_reference
A reference to a character.
Definition: StringView.h:23
bool starts_with(charT c) const noexcept
Checks whether the string begins with the character specified for c.
Definition: StringView.h:119
Wraps functions like strlen and strcpy so they can be safely used.
bool ends_with(charT c) const noexcept
Checks whether the string ends with the character specified for c.
Definition: StringView.h:129
const_reverse_iterator rend() const noexcept
Returns the reverse iterator pointing to the character before the first character.
Definition: StringView.h:52
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:51
bool ends_with(const charT *s) const noexcept
Checks whether the string has s as its suffix.
Definition: StringView.h:130
charT value_type
The type for a character.
Definition: StringView.h:19
StringView(const charT *str) noexcept
Initialized to reference str. The string length is calculated internally.
Definition: StringView.h:35
const_iterator cend() const noexcept
Returns the iterator pointing to the character following the last character.
Definition: StringView.h:49
bool starts_with(const charT *s) const noexcept
Checks whether the string has s as its prefix.
Definition: StringView.h:120
bool ends_with(const StringView &s) const noexcept
Checks whether the string has s as its suffix.
Definition: StringView.h:123
bool Proceed(const charT *kwd) noexcept
Advances by the amount of the string length of kwd, providing that the prefix matches kwd...
Definition: StringView.h:167
const charT & reference
A reference to a character. The same as const_reference.
Definition: StringView.h:22
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24