Samchon Framework for CPP  1.0.0
WeakString.cpp
1 #include <samchon/WeakString.hpp>
2 
3 #include <list>
4 #include <queue>
5 #include <utility>
6 
7 #include <samchon/library/Math.hpp>
8 
9 using namespace std;
10 using namespace samchon;
11 using namespace samchon::library;
12 
13 const vector<std::string> WeakString::SPACE_ARRAY = { " ", "\t", "\r", "\n" };
14 
15 /* --------------------------------------------------------------------
16  CONSTRUCTORS
17 -------------------------------------------------------------------- */
18 WeakString::WeakString()
19 {
20  this->data_ = nullptr;
21  this->size_ = 0;
22 }
23 WeakString::WeakString(const char *data, size_t size)
24 {
25  this->data_ = data;
26  this->size_ = size;
27  // this->size_ = std::min<size_t>(std::char_traits<char>::length(data), size);
28 }
29 WeakString::WeakString(const char *begin, const char *end)
30  : WeakString(begin, end - begin)
31 {
32 }
34 {
35  this->data_ = data;
36 
37  if (data == nullptr)
38  this->size_ = 0;
39  else
40  this->size_ = std::char_traits<char>::length(data);
41 }
42 WeakString::WeakString(const char &ch)
43 {
44  this->data_ = &ch;
45  this->size_ = 1;
46 }
47 WeakString::WeakString(std::initializer_list<char> &il)
48 {
49  if (il.size() == 0)
50  this->data_ = nullptr;
51  else
52  this->data_ = il.begin();
53 
54  this->size_ = il.size();
55 }
56 WeakString::WeakString(const std::string &str)
57 {
58  this->data_ = str.data();
59  this->size_ = str.size();
60 }
61 
62 /* --------------------------------------------------------------------
63  ELEMENT ACCESSORS
64 -------------------------------------------------------------------- */
65 auto WeakString::data() const -> const char*
66 {
67  return data_;
68 }
69 auto WeakString::size() const -> size_t
70 {
71  return size_;
72 }
73 
74 auto WeakString::empty() const -> bool
75 {
76  return (size_ == 0 || data_ == nullptr);
77 }
78 
79 auto WeakString::at(size_t index) const -> const char&
80 {
81  return *(data_ + index);
82 }
83 auto WeakString::operator[](size_t index) const -> const char&
84 {
85  return *(data_ + index);
86 }
87 
88 /* --------------------------------------------------------------------
89  FINDERS
90 -------------------------------------------------------------------- */
91 auto WeakString::find(const WeakString &delim, size_t startIndex) const -> size_t
92 {
93  size_t j = 0;
94 
95  for (size_t i = startIndex; i < size_; i++)
96  if (data_[i] != delim[j++])
97  j = 0;
98  else if (j == delim.size())
99  return i - delim.size() + 1;
100 
101  return npos;
102 }
103 auto WeakString::rfind(const WeakString &delim, size_t endIndex) const -> size_t
104 {
105  if (empty() == true)
106  return npos;
107 
108  size_t j = delim.size() - 1;
109 
110  for (long long i = std::min(endIndex - 1, size_ - 1); i >= 0; i--)
111  if (data_[(size_t)i] != delim[j]) //NOT MATCHED
112  j = delim.size() - 1;
113  else if (j == 0) //FULLY MATCHED
114  return (size_t)i;
115  else //PARTIALLY MATCHED,
116  j--;
117 
118  return npos;
119 }
120 
121 auto WeakString::finds(const std::vector<std::string> &delims, size_t startIndex) const -> IndexPair<WeakString>
122 {
123  std::vector<WeakString> wdelims(delims.size());
124  for (size_t i = 0; i < delims.size(); i++)
125  wdelims[i] = delims[i];
126 
127  return finds(wdelims, startIndex);
128 }
129 auto WeakString::finds(const std::vector<WeakString> &delims, size_t startIndex) const -> IndexPair<WeakString>
130 {
131  std::vector<size_t> positionVector;
132  positionVector.reserve(delims.size());
133 
134  for (size_t i = 0; i < delims.size(); i++)
135  positionVector.push_back(find(delims[i], startIndex));
136 
137  IndexPair<size_t> &iPair = Math::minimum(positionVector);
138  return{ iPair.getIndex(), delims[iPair.getValue()] };
139 }
140 
141 auto WeakString::rfinds(const std::vector<std::string> &delims, size_t endIndex) const -> IndexPair<WeakString>
142 {
143  std::vector<WeakString> wdelims(delims.size());
144  for (size_t i = 0; i < delims.size(); i++)
145  wdelims[i] = delims[i];
146 
147  return rfinds(wdelims, endIndex);
148 }
149 auto WeakString::rfinds(const std::vector<WeakString> &delims, size_t endIndex) const -> IndexPair<WeakString>
150 {
151  vector<size_t> positionVector;
152  positionVector.reserve(delims.size());
153 
154  size_t position;
155 
156  for (size_t i = 0; i < delims.size(); i++)
157  {
158  position = rfind(delims[i], endIndex);
159 
160  if (position != wstring::npos)
161  positionVector.push_back(position);
162  }
163 
164  if (positionVector.empty() == true)
165  return{ wstring::npos, WeakString() };
166 
167  IndexPair<size_t> &iPair = Math::maximum(positionVector);
168  return{ iPair.getIndex(), delims[iPair.getValue()] };
169 }
170 
171 /* --------------------------------------------------------------------
172  FINDERS
173 -------------------------------------------------------------------- */
174 auto WeakString::substr(size_t startIndex, size_t size) const -> WeakString
175 {
176  if (size > size_ || startIndex + size > size_)
177  size = size_ - startIndex;
178 
179  return WeakString(data_ + startIndex, size);
180 }
181 auto WeakString::substring(size_t startIndex, size_t endIndex) const -> WeakString
182 {
183  if (startIndex > endIndex)
184  swap(startIndex, endIndex);
185 
186  if (startIndex == endIndex || startIndex > size_ - 1)
187  return WeakString();
188 
189  if (endIndex > size_)
190  endIndex = size_;
191 
192  return WeakString(data_ + startIndex, data_ + endIndex);
193 }
194 auto WeakString::between(const WeakString &start, const WeakString &end) const -> WeakString
195 {
196  if (start.empty() == true && end.empty() == true)
197  return *this;
198  else if (start.empty() == true)
199  return substr(0, find(end));
200  else if (end.empty() == true)
201  return substr(find(start) + start.size());
202  else
203  {
204  size_t startIndex = find(start);
205  return substring
206  (
207  startIndex + start.size(),
208  find(end, startIndex + start.size())
209  );
210  }
211 }
212 auto WeakString::split(const WeakString &delim) const -> std::vector<WeakString>
213 {
214  size_t startIndex = 0;
215  size_t x;
216 
217  //CONSTRUCT THE LIST OF QUOTES
218  std::queue<std::pair<size_t, size_t>> quoteList;
219  while ((x = find(delim, startIndex)) != npos)
220  {
221  quoteList.push({ startIndex, x });
222  startIndex = x + delim.size();
223  }
224  quoteList.push({ startIndex, size() });
225 
226  //ASSIGN THE STRING_VECTOR BY SUBSTRING
227  std::vector<WeakString> vec;
228  vec.reserve(quoteList.size());
229 
230  while (quoteList.empty() == false)
231  {
232  vec.push_back(substring(quoteList.front().first, quoteList.front().second));
233  quoteList.pop();
234  }
235  return vec;
236 }
237 auto WeakString::betweens(const WeakString &start, const WeakString &end) const -> std::vector<WeakString>
238 {
239  std::vector<WeakString> vec;
240 
241  if (start.empty() == true && end.empty() == true)
242  return vec;
243  else if (start == end) //NOT EMPTY, BUT EQUALS
244  {
245  std::queue<std::pair<size_t, size_t>> quoteList;
246 
247  size_t x, prevX = -1, n = 0;
248  while ((x = find(start, prevX + 1)) != npos)
249  {
250  if (++n % 2 == 0) //WHEN THE MATCHED NUMBER IS EVEN
251  quoteList.push({ prevX, x });
252  prevX = x;
253  }
254 
255  if (quoteList.size() == 0)
256  vec.push_back(*this);
257  else
258  {
259  vec.reserve(quoteList.size());
260  while (quoteList.empty() == false)
261  {
262  std::pair<size_t, size_t> &quote = quoteList.front();
263  vec.push_back(substring(quote.first + start.size()));
264 
265  quoteList.pop();
266  }
267  }
268  }
269  else //BEGIN AND END IS DIFFER
270  {
271  vec = split(start);
272  vec.erase(vec.begin());
273 
274  if (end.empty() == false)
275  for (long long i = (long long)vec.size() - 1; i >= 0; i--)
276  if (vec.at((size_t)i).find(end) == npos)
277  vec.erase(vec.begin() + (size_t)i);
278  else
279  vec[(size_t)i] = vec[(size_t)i].between("", end);
280  }
281  return vec;
282 }
283 
284 /* --------------------------------------------------------------------
285  TRIMS
286 -------------------------------------------------------------------- */
287 auto WeakString::trim(const std::vector<WeakString> &delims) const -> WeakString
288 {
289  return ltrim(delims).rtrim(delims);
290 }
291 auto WeakString::ltrim(const std::vector<WeakString> &delims) const-> WeakString
292 {
294  IndexPair<size_t> indexPair = { 0, 0 };
295 
296  while (str.empty() == false)
297  {
298  std::vector<size_t> indexVec;
299  indexVec.reserve(delims.size());
300 
301  for (size_t i = 0; i < delims.size(); i++)
302  indexVec.push_back(str.find(delims[i]));
303 
304  indexPair = Math::minimum(indexVec);
305  if (indexPair.getValue() == 0)
306  {
307  size_t size = delims[indexPair.getIndex()].size();
308 
309  str.data_ += size;
310  str.size_ -= size;
311  }
312  else
313  break;
314  }
315 
316  return str;
317 }
318 auto WeakString::rtrim(const std::vector<WeakString> &delims) const-> WeakString
319 {
321  IndexPair<size_t> pairIndex;
322 
323  while (str.empty() == false)
324  {
325  std::vector<size_t> indexVec;
326  indexVec.reserve(delims.size());
327 
328  for (size_t i = 0; i < delims.size(); i++)
329  {
330  size_t index = str.rfind(delims[i]);
331  if (index != npos)
332  indexVec.push_back(index);
333  }
334  if (indexVec.empty() == true)
335  break;
336 
337  pairIndex = Math::maximum(indexVec);
338  size_t size = delims[pairIndex.getIndex()].size();
339 
340  if (pairIndex.getValue() == str.size() - size)
341  str.size_ -= size;
342  else
343  break;
344  }
345  return str;
346 }
347 
348 auto WeakString::trim() const -> WeakString
349 {
350  return trim(SPACE_ARRAY);
351 }
352 auto WeakString::ltrim() const -> WeakString
353 {
354  return ltrim(SPACE_ARRAY);
355 }
356 auto WeakString::rtrim() const -> WeakString
357 {
358  return rtrim(SPACE_ARRAY);
359 }
360 
361 auto WeakString::trim(const WeakString &delim) const -> WeakString
362 {
363  return trim(vector<WeakString>({ delim }));
364 }
365 auto WeakString::ltrim(const WeakString &delim) const -> WeakString
366 {
367  return ltrim(vector<WeakString>({ delim }));
368 }
369 auto WeakString::rtrim(const WeakString &delim) const -> WeakString
370 {
371  return rtrim(vector<WeakString>({ delim }));
372 }
373 
374 auto WeakString::trim(const std::vector<std::string> &delims) const -> WeakString
375 {
376  std::vector<WeakString> wdelims(delims.size());
377  for (size_t i = 0; i < delims.size(); i++)
378  wdelims[i] = delims[i];
379 
380  return trim(wdelims);
381 }
382 auto WeakString::ltrim(const std::vector<std::string> &delims) const -> WeakString
383 {
384  std::vector<WeakString> wdelims(delims.size());
385  for (size_t i = 0; i < delims.size(); i++)
386  wdelims[i] = delims[i];
387 
388  return ltrim(wdelims);
389 }
390 auto WeakString::rtrim(const std::vector<std::string> &delims) const -> WeakString
391 {
392  std::vector<WeakString> wdelims(delims.size());
393  for (size_t i = 0; i < delims.size(); i++)
394  wdelims[i] = delims[i];
395 
396  return rtrim(wdelims);
397 }
398 
399 /* --------------------------------------------------------------------
400  REPLACERS
401 -------------------------------------------------------------------- */
402 auto WeakString::replace(const WeakString &before, const WeakString &after) const -> std::string
403 {
404  size_t index = find(before);
405  if (index == npos)
406  return str();
407 
408  std::string str;
409  str.reserve(size() - before.size() + after.size());
410 
411  str.append(substr(0, index).str());
412  str.append(after.str());
413  str.append(substr(index + before.size()).str());
414 
415  return str;
416 }
417 
418 auto WeakString::replaceAll(const WeakString &before, const WeakString &after) const -> std::string
419 {
420  //to replaceAll(vector<pair<string, string>>)
421  return replaceAll({ { before, after } });
422 }
423 auto WeakString::replaceAll(const std::vector<std::pair<std::string, std::string>> &pairs) const -> std::string
424 {
425  std::vector<std::pair<WeakString, WeakString>> wPairs(pairs.size());
426  for (size_t i = 0; i < pairs.size(); i++)
427  wPairs[i] = { pairs[i].first, pairs[i].second };
428 
429  return replaceAll(wPairs);
430 }
431 auto WeakString::replaceAll(const std::vector<std::pair<WeakString, WeakString>> &pairs) const -> std::string
432 {
433  if (pairs.empty() == true)
434  return this->str();
435 
436  std::list<std::pair<size_t, size_t>> foundPairList;
437  //1ST IS STR-INDEX FROM FIND
438  //2ND IS PAIR-INDEX
439 
440  size_t size = this->size();
441  size_t index;
442  size_t i;
443 
444  //FIND POSITION-INDEX IN ORIGINAL STRING
445  for (i = 0; i < pairs.size(); i++)
446  {
447  index = 0;
448 
449  while (true)
450  {
451  index = find(pairs[i].first, index);
452  if (index == npos)
453  break;
454 
455  size -= pairs[i].first.size();
456  size += pairs[i].second.size();
457 
458  foundPairList.push_back({ index++, i });
459  }
460  }
461 
462  if (foundPairList.empty() == true)
463  return str();
464 
465  foundPairList.sort();
466 
467  //REPLACE
468  std::string str;
469  str.reserve((size_t)size);
470 
471  index = 0;
472 
473  while (foundPairList.empty() == false)
474  {
475  auto it = foundPairList.begin();
476  auto &before = pairs[it->second].first;
477  auto &after = pairs[it->second].second;
478 
479  str.append(substring(index, it->first).str());
480  str.append(after.str());
481 
482  index = it->first + before.size();
483  foundPairList.pop_front();
484  }
485  if (index <= this->size() - 1)
486  str.append(substr(index).str());
487 
488  return str;
489 }
490 
491 auto WeakString::toLowerCase() const -> std::string
492 {
493  std::string &str = this->str();
494  for (size_t i = 0; i < str.size(); i++)
495  if ('A' <= str[i] && str[i] <= 'Z')
496  str[i] = tolower(str[i]);
497 
498  return str;
499 }
500 auto WeakString::toUpperCase() const -> std::string
501 {
502  std::string &str = this->str();
503  for (size_t i = 0; i < str.size(); i++)
504  if ('a' <= str[i] && str[i] <= 'z')
505  str[i] = toupper(str[i]);
506 
507  return str;
508 };
509 
510 /* --------------------------------------------------------------------
511  COMPARISONS
512 -------------------------------------------------------------------- */
513 auto WeakString::operator==(const WeakString &str) const -> bool
514 {
515  if (this->size() != str.size())
516  return false;
517 
518  for (size_t i = 0; i < size(); i++)
519  if (this->at(i) != str[i])
520  return false;
521 
522  return true;
523 };
524 auto WeakString::operator<(const WeakString &str) const -> bool
525 {
526  size_t minSize = std::min(size(), str.size());
527 
528  for (size_t i = 0; i < minSize; i++)
529  if (this->at(i) == str[i])
530  continue;
531  else if (this->at(i) < str[i])
532  return true;
533  else
534  return false;
535 
536  if (this->size() == minSize && this->size() != str.size())
537  return true;
538  else
539  return false;
540 };
541 OPERATOR_METHODS_BODY(WeakString, WeakString)
542 
543 /* --------------------------------------------------------------------
544  CONVERSIONS
545 -------------------------------------------------------------------- */
546 auto WeakString::str() const -> std::string
547 {
548  return std::string(data_, data_ + size_);
549 };
550 WeakString::operator std::string()
551 {
552  return str();
553 };
auto substr(size_t startIndex, size_t endIndex=SIZE_MAX) const -> WeakString
Generates a substring.
Definition: WeakString.cpp:174
auto empty() const -> bool
Tests wheter string is emtpy.
Definition: WeakString.cpp:74
auto size() const -> size_t
Returns size of the characters which are being referenced.
Definition: WeakString.cpp:69
auto toLowerCase() const -> std::string
Convert uppercase letters to lowercase.
Definition: WeakString.cpp:491
auto getValue() -> T &
Get reference of value.
Definition: IndexPair.hpp:91
Definition: RWMutex.hpp:4
auto split(const WeakString &delim) const -> std::vector< WeakString >
Generates substrings.
Definition: WeakString.cpp:212
auto str() const -> std::string
Get the string content.
Definition: WeakString.cpp:546
Package of libraries.
Definition: library.hpp:84
auto operator[](size_t index) const -> const char &
Get character of string Returns a const reference to the character at the specified position...
Definition: WeakString.cpp:83
static const std::vector< std::string > SPACE_ARRAY
An array containing whitespaces.
Definition: WeakString.hpp:38
auto find(const WeakString &delim, size_t startIndex=NULL) const -> size_t
Finds first occurence in string.
Definition: WeakString.cpp:91
static const size_t npos
Maximum value for size_t.
Definition: WeakString.hpp:53
const char * data_
Referenced characters&#39;s pointer of begining position.
Definition: WeakString.hpp:59
auto ltrim(const std::vector< std::string > &delims) const -> WeakString
Removes all designated characters from the beginning of the specified string.
Definition: WeakString.cpp:382
auto rfinds(const std::vector< std::string > &delims, size_t endIndex=SIZE_MAX) const -> IndexPair< WeakString >
Finds last occurence in string.
Definition: WeakString.cpp:141
auto rfind(const WeakString &delim, size_t endIndex=SIZE_MAX) const -> size_t
Finds last occurence in string.
Definition: WeakString.cpp:103
auto getIndex() const -> size_t
Get index.
Definition: IndexPair.hpp:81
auto finds(const std::vector< std::string > &delims, size_t startIndex=0) const -> IndexPair< WeakString >
Finds first occurence in string.
Definition: WeakString.cpp:121
auto toUpperCase() const -> std::string
Convert uppercase letters to lowercase.
Definition: WeakString.cpp:500
auto trim(const std::vector< std::string > &delims) const -> WeakString
Removes all designated characters from the beginning and end of the specified string.
Definition: WeakString.cpp:374
WeakString()
Default Constructor does not reference any character.
Definition: WeakString.cpp:18
auto substring(size_t startIndex, size_t size=SIZE_MAX) const -> WeakString
Generates a substring.
Definition: WeakString.cpp:181
auto at(size_t index) const -> const char &
Get character of string Returns a const reference to the character at the specified position...
Definition: WeakString.cpp:79
auto rtrim(const std::vector< std::string > &delims) const -> WeakString
Removes all designated characters from the end of the specified string.
Definition: WeakString.cpp:390
auto replaceAll(const WeakString &before, const WeakString &after) const -> std::string
Returns a string specified word is replaced.
Definition: WeakString.cpp:418
auto replace(const WeakString &before, const WeakString &after) const -> std::string
Replace portion of string once.
Definition: WeakString.cpp:402
size_t size_
(Specified) size of referenced characters
Definition: WeakString.hpp:64
A pair of index and its value(T)
Definition: IndexPair.hpp:29
auto betweens(const WeakString &start={}, const WeakString &end={}) const -> std::vector< WeakString >
Generates substrings.
Definition: WeakString.cpp:237
auto between(const WeakString &start={}, const WeakString &end={}) const -> WeakString
Generates a substring.
Definition: WeakString.cpp:194
Top level namespace of products built from samchon.
Definition: ByteArray.hpp:7
A string class only references characeters, reference only.
Definition: WeakString.hpp:32
auto data() const -> const char *
Get string data; referenced characeters.
Definition: WeakString.cpp:65