General Utility Library for C++17 26.5.0
substring_checks.h
Go to the documentation of this file.
1
26#ifndef GUL17_SUBSTRING_CHECKS_H_
27#define GUL17_SUBSTRING_CHECKS_H_
28
29#include <string_view>
30
31#include "gul17/case_ascii.h"
32#include "gul17/internal.h"
33
34namespace gul17 {
35
55constexpr inline bool contains(std::string_view haystack, std::string_view needle) noexcept
56{
57 return haystack.find(needle) != std::string_view::npos;
58}
59
72constexpr inline bool contains(std::string_view haystack, char needle) noexcept
73{
74 return haystack.find(needle) != std::string_view::npos;
75}
76
89constexpr inline bool ends_with(std::string_view str, std::string_view suffix) noexcept
90{
91 const auto hsl = str.length();
92 const auto sl = suffix.length();
93
94 return hsl >= sl && str.compare(hsl - sl, sl, suffix) == 0;
95}
96
108constexpr inline bool ends_with(std::string_view str, char c) noexcept
109{
110 return !str.empty() && str.back() == c;
111}
112
125constexpr inline bool starts_with(std::string_view str, std::string_view prefix) noexcept
126{
127 const auto hsl = str.length();
128 const auto hl = prefix.length();
129
130 return hsl >= hl && std::string_view{ str.data(), hl }.compare(prefix) == 0;
131}
132
144constexpr inline bool starts_with(std::string_view str, char c) noexcept
145{
146 return !str.empty() && str.front() == c;
147}
148
149//
150// Case insensitive std::variants following
151//
152
169constexpr inline bool equals_nocase(std::string_view str1, std::string_view str2) noexcept
170{
171 if (str1.size() != str2.size())
172 return false;
173
174 // Hand-rolled version of std::equal() to maintain constexprness prior to C++20
175 auto it1 = str1.cbegin();
176 auto it2 = str2.cbegin();
177
178 while (it1 != str1.cend())
179 {
181 return false;
182
183 ++it1;
184 ++it2;
185 }
186
187 return true;
188}
189
211constexpr inline bool contains_nocase(std::string_view haystack, std::string_view needle) noexcept
212{
213 auto const haysize = haystack.size();
214 auto const needlesize = needle.size();
215 if (haysize < needlesize)
216 return false;
217 for (std::size_t i = 0; i <= haysize - needlesize; ++i) {
218 auto j = needlesize;
219 while (j-- > 0) {
221 break;
222 }
223 if (j == std::size_t(-1)) {
224 return true;
225 }
226 haystack.remove_prefix(1);
227 }
228 return false;
229}
230
245constexpr inline bool contains_nocase(std::string_view haystack, char needle) noexcept
246{
248 while (not haystack.empty()) {
249 if (lowercase_ascii(haystack.front()) == needle)
250 return true;
251 haystack.remove_prefix(1);
252 }
253 return false;
254}
255
271constexpr inline bool ends_with_nocase(std::string_view str, std::string_view suffix) noexcept
272{
273 while (not str.empty()) {
274 if (suffix.empty())
275 return true;
276 if (lowercase_ascii(str.back()) != lowercase_ascii(suffix.back()))
277 return false;
278 str.remove_suffix(1);
279 suffix.remove_suffix(1);
280 }
281 return suffix.empty();
282}
283
297constexpr inline bool ends_with_nocase(std::string_view str, char c) noexcept
298{
299 return !str.empty() && lowercase_ascii(str.back()) == lowercase_ascii(c);
300}
301
317constexpr inline bool starts_with_nocase(std::string_view str, std::string_view prefix) noexcept
318{
319 while (not str.empty()) {
320 if (prefix.empty())
321 return true;
322 if (lowercase_ascii(str.front()) != lowercase_ascii(prefix.front()))
323 return false;
324 str.remove_prefix(1);
325 prefix.remove_prefix(1);
326 }
327 return prefix.empty();
328}
329
343constexpr inline bool starts_with_nocase(std::string_view str, char c) noexcept
344{
345 return !str.empty() && lowercase_ascii(str.front()) == lowercase_ascii(c);
346}
347
349
350} // namespace gul17
351
352#endif
353
354/* vim:set expandtab softtabstop=4 tabstop=4 shiftwidth=4 textwidth=90 cindent: */
Declarations of lowercase_ascii(), lowercase_ascii_inplace(), uppercase_ascii(), and uppercase_ascii_...
auto constexpr bit_set(unsigned bit) noexcept -> ReturnT
Set a bit in an integral type.
Definition bit_manip.h:124
constexpr char lowercase_ascii(char c) noexcept
Return the ASCII lowercase equivalent of the given character (or the unchanged character,...
Definition case_ascii.h:51
constexpr bool ends_with(std::string_view str, std::string_view suffix) noexcept
Determine whether a string ends with another string.
Definition substring_checks.h:89
constexpr bool contains_nocase(std::string_view haystack, std::string_view needle) noexcept
Determine whether a string contains another string.
Definition substring_checks.h:211
constexpr bool starts_with(std::string_view str, std::string_view prefix) noexcept
Determine whether a string starts with another string.
Definition substring_checks.h:125
constexpr bool equals_nocase(std::string_view str1, std::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:169
constexpr bool ends_with_nocase(std::string_view str, std::string_view suffix) noexcept
Determine whether a string ends with another string.
Definition substring_checks.h:271
constexpr bool starts_with_nocase(std::string_view str, std::string_view prefix) noexcept
Determine whether a string starts with another string.
Definition substring_checks.h:317
constexpr bool contains(std::string_view haystack, std::string_view needle) noexcept
Determine whether a string contains another string.
Definition substring_checks.h:55
Definition of macros used internally by GUL.
Namespace gul17 contains all functions and classes of the General Utility Library.
Definition doxygen.h:29