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 
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 : len_(0), 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 : len_(nlib_strlen(str)), base_(str) {
36  NLIB_ASSERT(this->IsValid_());
37  }
38  StringView(const charT* str, size_type len) NLIB_NOEXCEPT : len_(len), 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 base_;
46  }
47  const_iterator end() const NLIB_NOEXCEPT { return begin() + len_; }
48  const_iterator cbegin() const NLIB_NOEXCEPT { return begin(); }
49  const_iterator cend() const NLIB_NOEXCEPT { return cbegin() + 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 len_;
60  }
61  size_type length() const NLIB_NOEXCEPT {
62  NLIB_ASSERT(this->IsValid_());
63  return 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 base_[pos];
72  }
73  const charT& at(size_type pos) const {
74  NLIB_ASSERT(this->IsValid_());
75  return 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 base_; }
80 
81  // [string.view.modifiers], modifiers:
83  len_ = 0;
84  base_ = "";
85  }
86  void remove_prefix(size_type n) NLIB_NOEXCEPT {
87  if (n >= len_) {
88  base_ += len_;
89  len_ = 0;
90  } else {
91  base_ += n;
92  len_ -= n;
93  }
94  }
95  void remove_suffix(size_type n) NLIB_NOEXCEPT {
96  if (n >= len_) {
97  len_ = 0;
98  } else {
99  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 >= len_) return StringView(base_ + len_, 0);
107  const charT* new_base = base_ + pos;
108  size_type r = static_cast<size_type>(len_ - pos);
109  size_type newLen = r > n ? n : r;
110  return StringView(new_base, newLen);
111  }
112  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(), base_, sizeof(*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() > len_) return false;
126  return nlib_memcmp(s.data(), base_ + len_ - s.length(), sizeof(*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  bool ToCstring(charT* str, size_type buf_size) const NLIB_NOEXCEPT;
132  template <size_type N>
133  bool ToCstring(charT (&str)[N]) const NLIB_NOEXCEPT {
134  return ToCstring(str, N);
135  }
136 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
137  template<class DUMMY = void>
138 #endif
139  bool ToCstring(UniquePtr<charT[]>& str) const NLIB_NOEXCEPT { // NOLINT
140  // to avoid crossing the DLL boundary
141  NLIB_ASSERT(this->IsValid_());
142  str.reset(new (std::nothrow) charT[len_ + 1]);
143  if (!str) return false;
144  return ToCstring(str.get(), len_ + 1);
145  }
146 
147  errno_t ToInteger(int32_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
148  errno_t ToInteger(int64_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
149  errno_t ToInteger(uint32_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
150  errno_t ToInteger(uint64_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
151  errno_t ToInteger(int8_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
152  errno_t ToInteger(int16_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
153  errno_t ToInteger(uint8_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
154  errno_t ToInteger(uint16_t* v, size_type* idx = NULL, int base = 10) const NLIB_NOEXCEPT;
155  errno_t ToFloat(float* v, size_type* idx = NULL) const NLIB_NOEXCEPT;
156  errno_t ToDouble(double* v, size_type* idx = NULL) const NLIB_NOEXCEPT;
157 
158  bool TrimLeft() NLIB_NOEXCEPT;
159  bool TrimRight() NLIB_NOEXCEPT;
160  void Trim() NLIB_NOEXCEPT {
161  TrimLeft();
162  TrimRight();
163  }
164  StringView GetLine() NLIB_NOEXCEPT;
165  bool Proceed(const StringView& kwd) NLIB_NOEXCEPT {
166  if (!this->starts_with(kwd)) return false;
167  base_ += kwd.length();
168  len_ -= kwd.length();
169  return true;
170  }
171  bool Proceed(const charT* kwd) NLIB_NOEXCEPT { return this->Proceed(StringView(kwd)); }
172  bool Proceed(charT ch) NLIB_NOEXCEPT;
173  StringView GetName() NLIB_NOEXCEPT;
174  /*
175  size_type find(const StringView& s) const {
176  StringView::iterator it = std::search(
177  begin(), end(), s.begin(), s.end());
178  return it == end() ? npos : it - begin();
179  }
180  size_type find(charT c) const;
181  size_type find(const charT* s) const;
182  size_type rfind(const StringView& s) const {
183  StringView::iterator it = std::find_end(
184  begin(), end(), s.begin(), s.end());
185  return it == end() ? npos : it - begin();
186  }
187  size_type rfind(charT c) const;
188  size_type rfind(const charT* s) const;
189  size_type find_first_of(const StringView& s) const {
190  StringView::iterator it = std::find_first_of(
191  begin(), end(), s.begin(), s.end());
192  return it == end() ? npos : it - begin();
193  }
194  size_type find_first_of(charT c) const;
195  size_type find_first_of(const charT* s) const;
196  size_type find_last_of(const StringView& s) const {
197  StringView::reverse_iterator it = std::find_first_of(
198  rbegin(), rend(), s.begin(), s.end());
199  return it == rend() ? std::string::npos : it.base() - 1 - begin();
200  }
201  size_type find_last_of(charT c) const;
202  size_type find_last_of(const charT* s) const;
203  size_type find_first_not_of(const StringView& s) const;
204  size_type find_first_not_of(charT c) const;
205  size_type find_first_not_of(const charT* s) const;
206  size_type find_last_not_of(const StringView& s) const;
207  size_type find_last_not_of(charT c) const;
208  size_type find_last_not_of(const charT* s) const;
209  */
210 
211  private:
212  bool IsValid_() const NLIB_NOEXCEPT {
213  if (!base_) return false;
214  return true;
215  }
216  size_type len_;
217  const charT* base_;
218 };
219 
220 
221 inline errno_t StringView::ToInteger(int8_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
222  int32_t tmp;
223  errno_t e = ToInteger(&tmp, idx, base);
224  if (e != 0) return e;
225  if (tmp > 127 || tmp < -128) return ERANGE;
226  *v = static_cast<int8_t>(tmp);
227  return 0;
228 }
229 
230 
231 inline errno_t StringView::ToInteger(int16_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
232  int32_t tmp;
233  errno_t e = ToInteger(&tmp, idx, base);
234  if (e != 0) return e;
235  if (tmp > 32767 || tmp < -32768) return ERANGE;
236  *v = static_cast<int16_t>(tmp);
237  return 0;
238 }
239 
240 
241 inline errno_t StringView::ToInteger(uint8_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
242  uint32_t tmp;
243  errno_t e = ToInteger(&tmp, idx, base);
244  if (e != 0) return e;
245  if (tmp > 255) return ERANGE;
246  *v = static_cast<uint8_t>(tmp);
247  return 0;
248 }
249 
250 
251 inline errno_t StringView::ToInteger(uint16_t* v, size_type* idx, int base) const NLIB_NOEXCEPT {
252  uint32_t tmp;
253  errno_t e = ToInteger(&tmp, idx, base);
254  if (e != 0) return e;
255  if (tmp > 65535) return ERANGE;
256  *v = static_cast<uint16_t>(tmp);
257  return 0;
258 }
259 
260 inline bool StringView::Proceed(charT ch) NLIB_NOEXCEPT {
261  if (this->starts_with(ch)) {
262  ++base_;
263  --len_;
264  return true;
265  } else {
266  return false;
267  }
268 }
269 
270 inline StringView StringView::GetName() NLIB_NOEXCEPT {
271  // isalpha()[isalnum()]*
272  NLIB_ASSERT(this->IsValid_());
273  const charT* s = base_;
274  const charT* s_end = base_ + len_;
275  charT c = (s != s_end) ? *s : '\0';
276  if (!nlib_isalpha(c) && c != '_') return *this;
277  for (;;) {
278  ++s;
279  c = (s != s_end) ? *s : '\0';
280  if (!nlib_isalnum(c) && c != '_') break;
281  }
282  size_type len = s - base_;
283  StringView rval(base_, len);
284  base_ = s;
285  len_ = len_ - len;
286  return rval;
287 }
288 
289 // [string.view.comparison], non-member StringView comparison functions
290 inline bool operator==(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
291  return lhs.compare(rhs) == 0;
292 }
293 inline bool operator!=(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
294  return !(lhs == rhs);
295 }
296 inline bool operator<(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
297  return lhs.compare(rhs) < 0;
298 }
299 inline bool operator>(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
300  return lhs.compare(rhs) > 0;
301 }
302 inline bool operator<=(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
303  return lhs.compare(rhs) <= 0;
304 }
305 inline bool operator>=(const StringView& lhs, const StringView& rhs) NLIB_NOEXCEPT {
306  return lhs.compare(rhs) >= 0;
307 }
308 
309 NLIB_NAMESPACE_END
310 
311 #endif // INCLUDE_NN_NLIB_STRINGVIEW_H_
void remove_prefix(size_type n) noexcept
Removes the first n characters.
Definition: StringView.h:86
bool ends_with(const StringView &s) const noexcept
Checks whether the string has s as its suffix.
Definition: StringView.h:123
std::reverse_iterator< const_iterator > const_reverse_iterator
A string reverse iterator.
Definition: StringView.h:26
const charT * data() const noexcept
Returns the pointer to the first character.
Definition: StringView.h:79
size_t size_type
A non-negative integer type, currently defined in size_t using typedef.
Definition: StringView.h:28
void clear() noexcept
Sets an empty string.
Definition: StringView.h:82
static int nlib_isalpha(int ch)
If ch is an ASCII character &#39;A&#39;-&#39;Z&#39; or &#39;a&#39;-&#39;z&#39;, the function returns non-zero. Othewise, the function returns 0.
Definition: Platform.h:3142
ptrdiff_t difference_type
The type returned when you take the difference between iterators.
Definition: StringView.h:29
bool empty() const noexcept
Checks whether it is an empty string.
Definition: StringView.h:66
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.
StringView substr(size_type pos, size_type n=npos) const noexcept
Returns a substring [pos, pos + n).
Definition: StringView.h:104
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 crbegin() const noexcept
Returns the reverse iterator pointing to the last character.
Definition: StringView.h:53
size_type length() const noexcept
Returns the length of the string.
Definition: StringView.h:61
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:302
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
Definition: NMalloc.h:110
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:115
char charT
Currently a char-type specific class.
Definition: StringView.h:18
bool starts_with(charT c) const noexcept
Checks whether the string begins with the character specified for c.
Definition: StringView.h:119
const charT & operator[](size_type pos) const
Gets the nth character, where n is specified by pos.
Definition: StringView.h:69
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:61
bool starts_with(const StringView &s) const noexcept
Checks whether the string has s as its prefix.
Definition: StringView.h:114
const charT & back() const
Gets the last character.
Definition: StringView.h:78
bool ends_with(const charT *s) const noexcept
Checks whether the string has s as its suffix.
Definition: StringView.h:130
constexpr StringView() noexcept
Instantiates the object with default parameters (default constructor). Initialized as an empty string...
Definition: StringView.h:33
const_iterator end() const noexcept
Returns the iterator pointing to the character following the last character.
Definition: StringView.h:47
const charT * pointer
The type for a character pointer. The same as const_pointer.
Definition: StringView.h:20
size_type max_size() const noexcept
Returns the maximum value for the string length.
Definition: StringView.h:65
const_iterator cend() const noexcept
Returns the iterator pointing to the character following the last character.
Definition: StringView.h:49
const_iterator iterator
A string iterator. The same as const_iterator.
Definition: StringView.h:25
int compare(const charT *s) const noexcept
Compares strings.
Definition: StringView.h:113
const charT & at(size_type pos) const
Gets the nth character, where n is specified by pos.
Definition: StringView.h:73
bool operator<(const StringView &lhs, const StringView &rhs) noexcept
Compares strings in dictionary order.
Definition: StringView.h:296
static int nlib_isalnum(int ch)
If ch is an ASCII character &#39;0&#39;-&#39;9&#39;, &#39;A&#39;-&#39;Z&#39;, or &#39;a&#39;-&#39;z&#39;, the function returns non-zero. Otherwise, the function returns 0.
Definition: Platform.h:3139
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:305
const_iterator begin() const noexcept
Returns the iterator pointing to the first character.
Definition: StringView.h:43
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:86
const_iterator cbegin() const noexcept
Returns the iterator pointing to the first character.
Definition: StringView.h:48
StringView(const charT *str, size_type len) noexcept
Initializes using the specified calculated string length.
Definition: StringView.h:38
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
Definition: Config.h:80
A file that contains the configuration information for each development environment.
const_reverse_iterator crend() const noexcept
Returns the reverse iterator pointing to the character before the first character.
Definition: StringView.h:54
const_pointer const_iterator
A character string iterator.
Definition: StringView.h:24
The class for using the member functions of std::string without constructing std::string.
Definition: StringView.h:15
bool starts_with(const charT *s) const noexcept
Checks whether the string has s as its prefix.
Definition: StringView.h:120
bool operator>(const StringView &lhs, const StringView &rhs) noexcept
Compares strings in dictionary order.
Definition: StringView.h:299
bool Proceed(const StringView &kwd) noexcept
Advances by the amount of the string length of kwd, providing that the prefix matches kwd...
Definition: StringView.h:165
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 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
Wraps functions like strlen and strcpy so they can be safely used.
const_reverse_iterator rbegin() const noexcept
Returns the reverse iterator pointing to the last character.
Definition: StringView.h:51
bool ToCstring(charT(&str)[N]) const noexcept
Definition: StringView.h:133
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 charT & front() const
Gets the first character.
Definition: StringView.h:77
size_type size() const noexcept
Returns the length of the string.
Definition: StringView.h:57
const_reverse_iterator rend() const noexcept
Returns the reverse iterator pointing to the character before the first character.
Definition: StringView.h:52
bool ToCstring(UniquePtr< charT[]> &str) const noexcept
Definition: StringView.h:139
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:171
void Trim() noexcept
Trims the white space from the start and the end of the string.
Definition: StringView.h:160
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