Gamedev Framework (gf)  0.12.0
A C++14 framework for 2D games
StringUtils.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2019 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_STRING_UTILS_H
22 #define GF_STRING_UTILS_H
23 
24 #include <cassert>
25 #include <cstdarg>
26 
27 #include <vector>
28 #include <string>
29 
30 #include "Portability.h"
31 #include "StringRef.h"
32 
33 namespace gf {
34 #ifndef DOXYGEN_SHOULD_SKIP_THIS
35 inline namespace v1 {
36 #endif
37 
48  GF_API std::string niceNum(float num, float precision);
49 
56  GF_API std::string formatString(const char *fmt, ...) GF_FORMAT(1, 2);
57 
65  GF_API std::string formatString(const char *fmt, va_list ap);
66 
78  GF_API std::string escapeString(StringRef str);
79 
89  GF_API std::vector<StringRef> splitInParagraphs(StringRef str);
90 
100  GF_API std::vector<StringRef> splitInWords(StringRef str);
101 
102 
109  struct GF_API CodepointRange {
111 
112  struct Iterator {
113  using difference_type = std::ptrdiff_t;
114  using value_type = char32_t;
117  using iterator_category = std::forward_iterator_tag;
118 
122  void swap(Iterator& other) noexcept {
123  std::swap(current, other.current);
124  }
125 
131  constexpr reference operator*() const noexcept {
132  return decode();
133  }
134 
140  constexpr pointer operator->() const noexcept {
141  return decode();
142  }
143 
149  constexpr Iterator& operator++() noexcept {
150  step();
151  return *this;
152  }
153 
159  constexpr Iterator operator++(int) noexcept {
160  Iterator copy = *this;
161  step();
162  return copy;
163  }
164 
171  constexpr bool operator!=(const Iterator& other) const noexcept {
172  return current != other.current;
173  }
174 
181  constexpr bool operator==(const Iterator& other) const noexcept {
182  return current == other.current;
183  }
184 
185  const char *current;
186 
187  private:
188  constexpr char32_t decode() const noexcept {
189  char32_t codepoint = 0;
190  uint8_t c = current[0];
191 
192  if ((c & 0b10000000) == 0b00000000) {
193  codepoint = c & 0b01111111;
194  } else if ((c & 0b11100000) == 0b11000000) {
195  codepoint = c & 0b00011111;
196  codepoint = (codepoint << 6) + (current[1] & 0b00111111);
197  } else if ((c & 0b11110000) == 0b11100000) {
198  codepoint = c & 0b00001111;
199  codepoint = (codepoint << 6) + (current[1] & 0b00111111);
200  codepoint = (codepoint << 6) + (current[2] & 0b00111111);
201  } else {
202  assert((c & 0b11111000) == 0b11110000);
203  codepoint = c & 0b00000111;
204  codepoint = (codepoint << 6) + (current[1] & 0b00111111);
205  codepoint = (codepoint << 6) + (current[2] & 0b00111111);
206  codepoint = (codepoint << 6) + (current[3] & 0b00111111);
207  }
208 
209  return codepoint;
210  }
211 
212  constexpr void step() noexcept {
213  uint8_t c = current[0];
214 
215  if ((c & 0b10000000) == 0b00000000) {
216  current += 1;
217  } else if ((c & 0b11100000) == 0b11000000) {
218  current += 2;
219  } else if ((c & 0b11110000) == 0b11100000) {
220  current += 3;
221  } else {
222  assert((c & 0b11111000) == 0b11110000);
223  current += 4;
224  }
225  }
226  };
227 
228  constexpr Iterator begin() const noexcept {
229  return Iterator{ ref.begin() };
230  }
231 
232  constexpr Iterator end() const noexcept {
233  return Iterator{ ref.end() };
234  }
235 
236  };
237 
242  inline
244  return CodepointRange{ ref };
245  }
246 
247 #ifndef DOXYGEN_SHOULD_SKIP_THIS
248 }
249 #endif
250 }
251 
252 #endif // GF_STRING_UTILS_H
std::vector< StringRef > splitInParagraphs(StringRef str)
Split a string in multiples paragraphs.
constexpr Iterator & operator++() noexcept
Increment operator (prefix)
Definition: StringUtils.h:149
constexpr bool operator==(const Iterator &other) const noexcept
Equality operator.
Definition: StringUtils.h:181
constexpr const_iterator begin() const noexcept
Get an iterator to the beginning of the string.
Definition: StringRef.h:158
constexpr Iterator end() const noexcept
Definition: StringUtils.h:232
std::forward_iterator_tag iterator_category
Definition: StringUtils.h:117
std::string formatString(const char *fmt,...)
Format a string like printf.
constexpr Iterator operator++(int) noexcept
Increment operator (postfix)
Definition: StringUtils.h:159
std::string escapeString(StringRef str)
Escape a string.
STL namespace.
A range over a sequence of codepoints in UTF-8.
Definition: StringUtils.h:109
value_type reference
Definition: StringUtils.h:116
char32_t value_type
Definition: StringUtils.h:114
constexpr const_iterator end() const noexcept
Get an iterator past the end of the string.
Definition: StringRef.h:169
constexpr CodepointRange codepoints(StringRef ref)
Create a range over codepoints from a string.
Definition: StringUtils.h:243
constexpr pointer operator->() const noexcept
Pointer operator.
Definition: StringUtils.h:140
value_type pointer
Definition: StringUtils.h:115
constexpr reference operator*() const noexcept
Dereference operator.
Definition: StringUtils.h:131
std::vector< StringRef > splitInWords(StringRef str)
Split a string in multiples words.
std::ptrdiff_t difference_type
Definition: StringUtils.h:113
StringRef ref
Definition: StringUtils.h:110
constexpr Iterator begin() const noexcept
Definition: StringUtils.h:228
The namespace for gf classes.
Definition: Action.h:35
void swap(Iterator &other) noexcept
Swap the iterator with another iterator.
Definition: StringUtils.h:122
const char * current
Definition: StringUtils.h:185
Definition: StringUtils.h:112
std::string niceNum(float num, float precision)
Create a string representation of a floating point number.
constexpr bool operator!=(const Iterator &other) const noexcept
Inequality operator.
Definition: StringUtils.h:171
A constant reference to a string and its size.
Definition: StringRef.h:41