General Utility Library for C++14  2.8
substring_checks.h
Go to the documentation of this file.
1 
23 #ifndef GUL14_SUBSTRING_CHECKS_H_
24 #define GUL14_SUBSTRING_CHECKS_H_
25 
26 #include "gul14/case_ascii.h"
27 #include "gul14/internal.h"
28 #include "gul14/string_view.h"
29 
30 namespace gul14 {
31 
45 constexpr inline bool contains(string_view haystack, string_view needle) noexcept
46 {
47  return haystack.find(needle) != string_view::npos;
48 }
49 
62 constexpr inline bool contains(string_view haystack, char needle) noexcept
63 {
64  return haystack.find(needle) != string_view::npos;
65 }
66 
79 constexpr inline bool ends_with(string_view str, string_view suffix) noexcept
80 {
81  const auto hsl = str.length();
82  const auto sl = suffix.length();
83 
84  return hsl >= sl && str.compare(hsl - sl, sl, suffix) == 0;
85 }
86 
98 constexpr inline bool ends_with(string_view str, char c) noexcept
99 {
100  return !str.empty() && str.back() == c;
101 }
102 
115 constexpr inline bool starts_with(string_view str, string_view prefix) noexcept
116 {
117  const auto hsl = str.length();
118  const auto hl = prefix.length();
119 
120  return hsl >= hl && string_view{ str.data(), hl }.compare(prefix) == 0;
121 }
122 
134 constexpr inline bool starts_with(string_view str, char c) noexcept
135 {
136  return !str.empty() && str.front() == c;
137 }
138 
139 //
140 // Case insensitive variants following
141 //
142 
159 constexpr inline bool equals_nocase(string_view str1, string_view str2) noexcept
160 {
161  if (str1.size() != str2.size())
162  return false;
163 
164  // Hand-rolled version of std::equal() to maintain constexprness prior to C++20
165  auto it1 = str1.cbegin();
166  auto it2 = str2.cbegin();
167 
168  while (it1 != str1.cend())
169  {
170  if (lowercase_ascii(*it1) != lowercase_ascii(*it2))
171  return false;
172 
173  ++it1;
174  ++it2;
175  }
176 
177  return true;
178 }
179 
201 constexpr inline bool contains_nocase(string_view haystack, string_view needle) noexcept
202 {
203  auto const haysize = haystack.size();
204  auto const needlesize = needle.size();
205  if (haysize < needlesize)
206  return false;
207  for (std::size_t i = 0; i <= haysize - needlesize; ++i) {
208  auto j = needlesize;
209  while (j-- > 0) {
210  if (lowercase_ascii(haystack[j]) != lowercase_ascii(needle[j]))
211  break;
212  }
213  if (j == std::size_t(-1)) {
214  return true;
215  }
216  haystack.remove_prefix(1);
217  }
218  return false;
219 }
220 
235 constexpr inline bool contains_nocase(string_view haystack, char needle) noexcept
236 {
237  needle = lowercase_ascii(needle);
238  while (not haystack.empty()) {
239  if (lowercase_ascii(haystack.front()) == needle)
240  return true;
241  haystack.remove_prefix(1);
242  }
243  return false;
244 }
245 
261 constexpr inline bool ends_with_nocase(string_view str, string_view suffix) noexcept
262 {
263  while (not str.empty()) {
264  if (suffix.empty())
265  return true;
266  if (lowercase_ascii(str.back()) != lowercase_ascii(suffix.back()))
267  return false;
268  str.remove_suffix(1);
269  suffix.remove_suffix(1);
270  }
271  return suffix.empty();
272 }
273 
287 constexpr inline bool ends_with_nocase(string_view str, char c) noexcept
288 {
289  return !str.empty() && lowercase_ascii(str.back()) == lowercase_ascii(c);
290 }
291 
307 constexpr inline bool starts_with_nocase(string_view str, string_view prefix) noexcept
308 {
309  while (not str.empty()) {
310  if (prefix.empty())
311  return true;
312  if (lowercase_ascii(str.front()) != lowercase_ascii(prefix.front()))
313  return false;
314  str.remove_prefix(1);
315  prefix.remove_prefix(1);
316  }
317  return prefix.empty();
318 }
319 
333 constexpr inline bool starts_with_nocase(string_view str, char c) noexcept
334 {
335  return !str.empty() && lowercase_ascii(str.front()) == lowercase_ascii(c);
336 }
337 
338 } // namespace gul14
339 
340 #endif
341 
342 /* vim:set expandtab softtabstop=4 tabstop=4 shiftwidth=4 textwidth=90 cindent: */
Declarations of lowercase_ascii(), lowercase_ascii_inplace(), uppercase_ascii(), and uppercase_ascii_...
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
constexpr bool equals_nocase(string_view str1, string_view str2) noexcept
Determine whether a string is equal to another one, making no distinction between upper and lower cas...
Definition: substring_checks.h:159
constexpr bool ends_with(string_view str, string_view suffix) noexcept
Determine whether a string ends with another string.
Definition: substring_checks.h:79
constexpr char lowercase_ascii(char c) noexcept
Return the ASCII lowercase equivalent of the given character (or the unchanged character,...
Definition: case_ascii.h:41
constexpr bool contains_nocase(string_view haystack, string_view needle) noexcept
Determine whether a string contains another string.
Definition: substring_checks.h:201
constexpr bool starts_with_nocase(string_view str, string_view prefix) noexcept
Determine whether a string starts with another string.
Definition: substring_checks.h:307
constexpr bool ends_with_nocase(string_view str, string_view suffix) noexcept
Determine whether a string ends with another string.
Definition: substring_checks.h:261
constexpr bool starts_with(string_view str, string_view prefix) noexcept
Determine whether a string starts with another string.
Definition: substring_checks.h:115
constexpr bool contains(string_view haystack, string_view needle) noexcept
Determine whether a string contains another string.
Definition: substring_checks.h:45
Provides a gul14::string_view that is fully compatible with C++17's std::string_view.