WPILibC++ 2027.0.0-alpha-2
Loading...
Searching...
No Matches
StringExtras.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5//===- llvm/ADT/StringExtras.h - Useful string functions --------*- C++ -*-===//
6//
7// The LLVM Compiler Infrastructure
8//
9// This file is distributed under the University of Illinois Open Source
10// License. See LICENSE.TXT for details.
11//
12//===----------------------------------------------------------------------===//
13//
14// This file contains some functions that are useful when dealing with strings.
15//
16//===----------------------------------------------------------------------===//
17
18#pragma once
19
20#include <concepts>
21#include <iterator>
22#include <limits>
23#include <optional>
24#include <string>
25#include <string_view>
26#include <type_traits>
27#include <utility>
28
29#include <fmt/format.h>
30
31namespace wpi {
32
33template <typename T>
34class SmallVectorImpl;
35
36/// hexdigit - Return the hexadecimal character for the
37/// given number \p X (which should be less than 16).
38constexpr char hexdigit(unsigned X, bool LowerCase = false) noexcept {
39 const char HexChar = LowerCase ? 'a' : 'A';
40 return X < 10 ? '0' + X : HexChar + X - 10;
41}
42
43/// Interpret the given character \p C as a hexadecimal digit and return its
44/// value.
45///
46/// If \p C is not a valid hex digit, -1U is returned.
47constexpr unsigned hexDigitValue(char C) noexcept {
48 if (C >= '0' && C <= '9') {
49 return C - '0';
50 }
51 if (C >= 'a' && C <= 'f') {
52 return C - 'a' + 10U;
53 }
54 if (C >= 'A' && C <= 'F') {
55 return C - 'A' + 10U;
56 }
57 return (std::numeric_limits<unsigned>::max)();
58}
59
60/// Checks if character \p C is one of the 10 decimal digits.
61constexpr bool isDigit(char C) noexcept {
62 return C >= '0' && C <= '9';
63}
64
65/// Checks if character \p C is a hexadecimal numeric character.
66constexpr bool isHexDigit(char C) noexcept {
67 return hexDigitValue(C) != (std::numeric_limits<unsigned>::max)();
68}
69
70/// Checks if character \p C is a valid letter as classified by "C" locale.
71constexpr bool isAlpha(char C) noexcept {
72 return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z');
73}
74
75/// Checks whether character \p C is either a decimal digit or an uppercase or
76/// lowercase letter as classified by "C" locale.
77constexpr bool isAlnum(char C) noexcept {
78 return isAlpha(C) || isDigit(C);
79}
80
81/// Checks whether character \p C is valid ASCII (high bit is zero).
82constexpr bool isASCII(char C) noexcept {
83 return static_cast<unsigned char>(C) <= 127;
84}
85
86/// Checks whether character \p C is printable.
87///
88/// Locale-independent version of the C standard library isprint whose results
89/// may differ on different platforms.
90constexpr bool isPrint(char C) noexcept {
91 unsigned char UC = static_cast<unsigned char>(C);
92 return (0x20 <= UC) && (UC <= 0x7E);
93}
94
95/// Returns the corresponding lowercase character if \p x is uppercase.
96constexpr char toLower(char x) noexcept {
97 if (x >= 'A' && x <= 'Z') {
98 return x - 'A' + 'a';
99 }
100 return x;
101}
102
103/// Returns the corresponding uppercase character if \p x is lowercase.
104constexpr char toUpper(char x) noexcept {
105 if (x >= 'a' && x <= 'z') {
106 return x - 'a' + 'A';
107 }
108 return x;
109}
110
111inline std::string utohexstr(unsigned long long val, // NOLINT(runtime/int)
112 bool lowerCase = false) {
113 char buf[17];
114 char* bufptr = std::end(buf);
115
116 if (val == 0) {
117 *--bufptr = '0';
118 }
119
120 while (val) {
121 unsigned char mod = static_cast<unsigned char>(val) & 15;
122 *--bufptr = hexdigit(mod, lowerCase);
123 val >>= 4;
124 }
125
126 return std::string(bufptr, std::end(buf));
127}
128
129/**
130 * equals - Check for string equality, this is more efficient than
131 * compare() when the relative ordering of inequal strings isn't needed.
132 */
133constexpr bool equals(std::string_view lhs, std::string_view rhs) noexcept {
134 auto length = lhs.size();
135 return length == rhs.size() && std::string_view::traits_type::compare(
136 lhs.data(), rhs.data(), length) == 0;
137}
138
139/**
140 * compare_lower - Compare two strings, ignoring case.
141 */
142int compare_lower(std::string_view lhs, std::string_view rhs) noexcept;
143
144/**
145 * equals_lower - Check for string equality, ignoring case.
146 */
147constexpr bool equals_lower(std::string_view lhs,
148 std::string_view rhs) noexcept {
149 return lhs.size() == rhs.size() && compare_lower(lhs, rhs) == 0;
150}
151
152/**
153 * Search for the first character @p ch in @p str, ignoring case.
154 *
155 * @returns The index of the first occurrence of @p ch, or npos if not
156 * found.
157 */
158std::string_view::size_type find_lower(
159 std::string_view str, char ch,
160 std::string_view::size_type from = 0) noexcept;
161
162/**
163 * Search for the first string @p other in @p str, ignoring case.
164 *
165 * @returns The index of the first occurrence of @p other, or npos if not
166 * found.
167 */
169 std::string_view str, std::string_view other,
170 std::string_view::size_type from = 0) noexcept;
171
172/**
173 * Search for the first string @p other in @p str, ignoring case.
174 *
175 * @returns The index of the first occurrence of @p other, or npos if not
176 * found.
177 */
178inline std::string_view::size_type find_lower(
179 std::string_view str, const char* other,
180 std::string_view::size_type from = 0) noexcept {
181 return find_lower(str, std::string_view{other}, from);
182}
183
184/**
185 * Search for the last character @p ch in @p str, ignoring case.
186 *
187 * @returns The index of the last occurrence of @p ch, or npos if not
188 * found.
189 */
190std::string_view::size_type rfind_lower(
191 std::string_view str, char ch,
192 std::string_view::size_type from = std::string_view::npos) noexcept;
193
194/**
195 * Search for the last string @p other in @p str, ignoring case.
196 *
197 * @returns The index of the last occurrence of @p other, or npos if not
198 * found.
199 */
200std::string_view::size_type rfind_lower(std::string_view str,
201 std::string_view other) noexcept;
202
203/**
204 * Search for the last string @p other in @p str, ignoring case.
205 *
206 * @returns The index of the last occurrence of @p other, or npos if not
207 * found.
208 */
209inline std::string_view::size_type rfind_lower(std::string_view str,
210 const char* other) noexcept {
211 return rfind_lower(str, std::string_view{other});
212}
213
214/**
215 * Returns the substring of @p str from [start, start + n).
216 *
217 * @param start The index of the starting character in the substring; if
218 * the index is npos or greater than the length of the string then the
219 * empty substring will be returned.
220 *
221 * @param n The number of characters to included in the substring. If n
222 * exceeds the number of characters remaining in the string, the string
223 * suffix (starting with @p start) will be returned.
224 */
225constexpr std::string_view substr(
226 std::string_view str, std::string_view::size_type start,
227 std::string_view::size_type n = std::string_view::npos) noexcept {
228 auto length = str.size();
229 start = (std::min)(start, length);
230 return {str.data() + start, (std::min)(n, length - start)};
231}
232
233/**
234 * Checks if @p str starts with the given @p prefix.
235 */
236constexpr bool starts_with(std::string_view str,
237 std::string_view prefix) noexcept {
238 return substr(str, 0, prefix.size()) == prefix;
239}
240
241/**
242 * Checks if @p str starts with the given @p prefix.
243 */
244constexpr bool starts_with(std::string_view str, char prefix) noexcept {
245 return !str.empty() && std::string_view::traits_type::eq(str.front(), prefix);
246}
247
248/**
249 * Checks if @p str starts with the given @p prefix.
250 */
251constexpr bool starts_with(std::string_view str, const char* prefix) noexcept {
252 return starts_with(str, std::string_view(prefix));
253}
254
255/**
256 * Checks if @p str starts with the given @p prefix, ignoring case.
257 */
258bool starts_with_lower(std::string_view str, std::string_view prefix) noexcept;
259
260/**
261 * Checks if @p str starts with the given @p prefix, ignoring case.
262 */
263constexpr bool starts_with_lower(std::string_view str, char prefix) noexcept {
264 return !str.empty() && toLower(str.front()) == toLower(prefix);
265}
266
267/**
268 * Checks if @p str starts with the given @p prefix, ignoring case.
269 */
270inline bool starts_with_lower(std::string_view str,
271 const char* prefix) noexcept {
272 return starts_with_lower(str, std::string_view(prefix));
273}
274
275/**
276 * Checks if @p str ends with the given @p suffix.
277 */
278constexpr bool ends_with(std::string_view str,
279 std::string_view suffix) noexcept {
280 return str.size() >= suffix.size() &&
281 str.compare(str.size() - suffix.size(), std::string_view::npos,
282 suffix) == 0;
283}
284
285/**
286 * Checks if @p str ends with the given @p suffix.
287 */
288constexpr bool ends_with(std::string_view str, char suffix) noexcept {
289 return !str.empty() && std::string_view::traits_type::eq(str.back(), suffix);
290}
291
292/**
293 * Checks if @p str ends with the given @p suffix.
294 */
295constexpr bool ends_with(std::string_view str, const char* suffix) noexcept {
296 return ends_with(str, std::string_view(suffix));
297}
298
299/**
300 * Checks if @p str ends with the given @p suffix, ignoring case.
301 */
302bool ends_with_lower(std::string_view str, std::string_view suffix) noexcept;
303
304/**
305 * Checks if @p str ends with the given @p suffix, ignoring case.
306 */
307constexpr bool ends_with_lower(std::string_view str, char suffix) noexcept {
308 return !str.empty() && toLower(str.back()) == toLower(suffix);
309}
310
311/**
312 * Checks if @p str ends with the given @p suffix, ignoring case.
313 */
314inline bool ends_with_lower(std::string_view str, const char* suffix) noexcept {
315 return ends_with_lower(str, std::string_view(suffix));
316}
317
318/**
319 * Checks if @p str contains the substring @p other.
320 */
321constexpr bool contains(std::string_view str, std::string_view other) noexcept {
322 return str.find(other) != std::string_view::npos;
323}
324
325/**
326 * Checks if @p str contains the substring @p other.
327 */
328constexpr bool contains(std::string_view str, char ch) noexcept {
329 return str.find(ch) != std::string_view::npos;
330}
331
332/**
333 * Checks if @p str contains the substring @p other.
334 */
335constexpr bool contains(std::string_view str, const char* other) noexcept {
336 return str.find(other) != std::string_view::npos;
337}
338
339/**
340 * Checks if @p str contains the substring @p other, ignoring case.
341 */
342inline bool contains_lower(std::string_view str,
343 std::string_view other) noexcept {
344 return find_lower(str, other) != std::string_view::npos;
345}
346
347/**
348 * Checks if @p str contains the substring @p other, ignoring case.
349 */
350inline bool contains_lower(std::string_view str, char ch) noexcept {
351 return find_lower(str, ch) != std::string_view::npos;
352}
353
354/**
355 * Checks if @p str contains the substring @p other, ignoring case.
356 */
357inline bool contains_lower(std::string_view str, const char* other) noexcept {
358 return find_lower(str, other) != std::string_view::npos;
359}
360
361/**
362 * Return an optional containing @p str but with @p prefix removed if the string
363 * starts with the prefix. If the string does not start with the prefix, return
364 * an empty optional.
365 */
366constexpr std::optional<std::string_view> remove_prefix(std::string_view str, std::string_view prefix) noexcept {
367 if (str.starts_with(prefix)) {
368 str.remove_prefix(prefix.size());
369 return str;
370 }
371 return std::nullopt;
372}
373
374/**
375 * Return an optional containing @p str but with @p suffix removed if the
376 * string ends with the suffix. If the string does not end with the suffix,
377 * return an empty optional.
378 */
379constexpr std::optional<std::string_view> remove_suffix(std::string_view str, std::string_view suffix) noexcept {
380 if (str.ends_with(suffix)) {
381 str.remove_suffix(suffix.size());
382 return str;
383 }
384 return std::nullopt;
385}
386
387/**
388 * Return a string_view equal to @p str but with the first @p n elements
389 * dropped.
390 */
391constexpr std::string_view drop_front(
392 std::string_view str, std::string_view::size_type n = 1) noexcept {
393 str.remove_prefix(n);
394 return str;
395}
396
397/**
398 * Return a string_view equal to @p str but with the last @p n elements dropped.
399 */
400constexpr std::string_view drop_back(
401 std::string_view str, std::string_view::size_type n = 1) noexcept {
402 str.remove_suffix(n);
403 return str;
404}
405
406/**
407 * Returns a view equal to @p str but with only the first @p n
408 * elements remaining. If @p n is greater than the length of the
409 * string, the entire string is returned.
410 */
411constexpr std::string_view take_front(
412 std::string_view str, std::string_view::size_type n = 1) noexcept {
413 auto length = str.size();
414 if (n >= length) {
415 return str;
416 }
417 return drop_back(str, length - n);
418}
419
420/**
421 * Returns a view equal to @p str but with only the last @p n
422 * elements remaining. If @p n is greater than the length of the
423 * string, the entire string is returned.
424 */
425constexpr std::string_view take_back(
426 std::string_view str, std::string_view::size_type n = 1) noexcept {
427 auto length = str.size();
428 if (n >= length) {
429 return str;
430 }
431 return drop_front(str, length - n);
432}
433
434/**
435 * Returns a reference to the substring of @p str from [start, end).
436 *
437 * @param start The index of the starting character in the substring; if
438 * the index is npos or greater than the length of the string then the
439 * empty substring will be returned.
440 *
441 * @param end The index following the last character to include in the
442 * substring. If this is npos or exceeds the number of characters
443 * remaining in the string, the string suffix (starting with @p start)
444 * will be returned. If this is less than @p start, an empty string will
445 * be returned.
446 */
447constexpr std::string_view slice(std::string_view str,
448 std::string_view::size_type start,
449 std::string_view::size_type end) noexcept {
450 auto length = str.size();
451 start = (std::min)(start, length);
452 end = (std::min)((std::max)(start, end), length);
453 return {str.data() + start, end - start};
454}
455
456/**
457 * Splits @p str into two substrings around the first occurrence of a separator
458 * character.
459 *
460 * If @p separator is in the string, then the result is a pair (LHS, RHS)
461 * such that (str == LHS + separator + RHS) is true and RHS is
462 * maximal. If @p separator is not in the string, then the result is a
463 * pair (LHS, RHS) where (str == LHS) and (RHS == "").
464 *
465 * @param separator The character to split on.
466 * @returns The split substrings.
467 */
468constexpr std::pair<std::string_view, std::string_view> split(
469 std::string_view str, char separator) noexcept {
470 auto idx = str.find(separator);
471 if (idx == std::string_view::npos) {
472 return {str, {}};
473 }
474 return {slice(str, 0, idx), slice(str, idx + 1, std::string_view::npos)};
475}
476
477/**
478 * Splits @p str into two substrings around the first occurrence of a separator
479 * string.
480 *
481 * If @p separator is in the string, then the result is a pair (LHS, RHS)
482 * such that (str == LHS + separator + RHS) is true and RHS is
483 * maximal. If @p separator is not in the string, then the result is a
484 * pair (LHS, RHS) where (str == LHS) and (RHS == "").
485 *
486 * @param separator The string to split on.
487 * @return The split substrings.
488 */
489constexpr std::pair<std::string_view, std::string_view> split(
490 std::string_view str, std::string_view separator) noexcept {
491 auto idx = str.find(separator);
492 if (idx == std::string_view::npos) {
493 return {str, {}};
494 }
495 return {slice(str, 0, idx),
496 slice(str, idx + separator.size(), std::string_view::npos)};
497}
498
499/**
500 * Splits @p str into two substrings around the last occurrence of a separator
501 * character.
502 *
503 * If @p separator is in the string, then the result is a pair (LHS, RHS)
504 * such that (str == LHS + separator + RHS) is true and RHS is
505 * minimal. If @p separator is not in the string, then the result is a
506 * pair (LHS, RHS) where (str == LHS) and (RHS == "").
507 *
508 * @param separator The string to split on.
509 * @return The split substrings.
510 */
511constexpr std::pair<std::string_view, std::string_view> rsplit(
512 std::string_view str, char separator) noexcept {
513 auto idx = str.rfind(separator);
514 if (idx == std::string_view::npos) {
515 return {str, {}};
516 }
517 return {slice(str, 0, idx), slice(str, idx + 1, std::string_view::npos)};
518}
519
520/**
521 * Splits @p str into two substrings around the last occurrence of a separator
522 * string.
523 *
524 * If @p separator is in the string, then the result is a pair (LHS, RHS)
525 * such that (str == LHS + separator + RHS) is true and RHS is
526 * minimal. If @p separator is not in the string, then the result is a
527 * pair (LHS, RHS) where (str == LHS) and (RHS == "").
528 *
529 * @param separator The string to split on.
530 * @return The split substrings.
531 */
532constexpr std::pair<std::string_view, std::string_view> rsplit(
533 std::string_view str, std::string_view separator) noexcept {
534 auto idx = str.rfind(separator);
535 if (idx == std::string_view::npos) {
536 return {str, {}};
537 }
538 return {slice(str, 0, idx),
539 slice(str, idx + separator.size(), std::string_view::npos)};
540}
541
542/**
543 * Splits @p str into substrings around the occurrences of a separator string.
544 *
545 * Each substring is passed to the callback @p func. If @p maxSplit is >= 0, at
546 * most @p maxSplit splits are done and consequently <= @p maxSplit + 1
547 * elements are provided to the callback.
548 * If @p keepEmpty is false, empty strings are not included. They
549 * still count when considering @p maxSplit.
550 * An useful invariant is that
551 * separator.join(all callbacks) == str if keepEmpty == true.
552 *
553 * @param separator The string to split on.
554 * @param maxSplit The maximum number of times the string is split.
555 * @param keepEmpty True if empty substring should be added.
556 * @param func Function to call for each substring.
557 */
558template <std::invocable<std::string_view> F>
559void split(std::string_view str, std::string_view separator, int maxSplit,
560 bool keepEmpty, F&& func) {
561 std::string_view s = str;
562
563 // Count down from maxSplit. When maxSplit is -1, this will just split
564 // "forever". This doesn't support splitting more than 2^31 times
565 // intentionally; if we ever want that we can make maxSplit a 64-bit integer
566 // but that seems unlikely to be useful.
567 while (maxSplit-- != 0) {
568 auto idx = s.find(separator);
569 if (idx == std::string_view::npos) {
570 break;
571 }
572
573 // Provide this split.
574 if (keepEmpty || idx > 0) {
575 func(slice(s, 0, idx));
576 }
577
578 // Jump forward.
579 s = slice(s, idx + separator.size(), std::string_view::npos);
580 }
581
582 // Provide the tail.
583 if (keepEmpty || !s.empty()) {
584 func(s);
585 }
586}
587
588/**
589 * Splits @p str into substrings around the occurrences of a separator
590 * character.
591 *
592 * Each substring is passed to the callback @p func. If @p maxSplit is >= 0, at
593 * most @p maxSplit splits are done and consequently <= @p maxSplit + 1
594 * elements are provided to the callback.
595 * If @p keepEmpty is false, empty strings are not included. They
596 * still count when considering @p maxSplit.
597 * An useful invariant is that
598 * separator.join(all callbacks) == str if keepEmpty == true.
599 *
600 * @param separator The character to split on.
601 * @param maxSplit The maximum number of times the string is split.
602 * @param keepEmpty True if empty substring should be added.
603 * @param func Function to call for each substring.
604 */
605template <std::invocable<std::string_view> F>
606void split(std::string_view str, char separator, int maxSplit, bool keepEmpty,
607 F&& func) {
608 std::string_view s = str;
609
610 // Count down from maxSplit. When maxSplit is -1, this will just split
611 // "forever". This doesn't support splitting more than 2^31 times
612 // intentionally; if we ever want that we can make maxSplit a 64-bit integer
613 // but that seems unlikely to be useful.
614 while (maxSplit-- != 0) {
615 size_t idx = s.find(separator);
616 if (idx == std::string_view::npos) {
617 break;
618 }
619
620 // Provide this split.
621 if (keepEmpty || idx > 0) {
622 func(slice(s, 0, idx));
623 }
624
625 // Jump forward.
626 s = slice(s, idx + 1, std::string_view::npos);
627 }
628
629 // Provide the tail.
630 if (keepEmpty || !s.empty()) {
631 func(s);
632 }
633}
634
635/**
636 * Returns @p str with consecutive @p ch characters starting from the
637 * the left removed.
638 */
639constexpr std::string_view ltrim(std::string_view str, char ch) noexcept {
640 return drop_front(str, (std::min)(str.size(), str.find_first_not_of(ch)));
641}
642
643/**
644 * Returns @p str with consecutive characters in @p chars starting from
645 * the left removed.
646 */
647constexpr std::string_view ltrim(
648 std::string_view str, std::string_view chars = " \t\n\v\f\r") noexcept {
649 return drop_front(str, (std::min)(str.size(), str.find_first_not_of(chars)));
650}
651
652/**
653 * Returns @p str with consecutive @p Char characters starting from the
654 * right removed.
655 */
656constexpr std::string_view rtrim(std::string_view str, char ch) noexcept {
657 return drop_back(
658 str, str.size() - (std::min)(str.size(), str.find_last_not_of(ch) + 1));
659}
660
661/**
662 * Returns @p str with consecutive characters in @p chars starting from
663 * the right removed.
664 */
665constexpr std::string_view rtrim(
666 std::string_view str, std::string_view chars = " \t\n\v\f\r") noexcept {
667 return drop_back(
668 str,
669 str.size() - (std::min)(str.size(), str.find_last_not_of(chars) + 1));
670}
671
672/**
673 * Returns @p str with consecutive @p ch characters starting from the
674 * left and right removed.
675 */
676constexpr std::string_view trim(std::string_view str, char ch) noexcept {
677 return rtrim(ltrim(str, ch), ch);
678}
679
680/**
681 * Returns @p str with consecutive characters in @p chars starting from
682 * the left and right removed.
683 */
684constexpr std::string_view trim(
685 std::string_view str, std::string_view chars = " \t\n\v\f\r") noexcept {
686 return rtrim(ltrim(str, chars), chars);
687}
688
689namespace detail {
691 std::string_view str, unsigned radix,
692 unsigned long long& result) noexcept; // NOLINT(runtime/int)
693bool GetAsSignedInteger(std::string_view str, unsigned radix,
694 long long& result) noexcept; // NOLINT(runtime/int)
695
697 std::string_view& str, unsigned radix,
698 unsigned long long& result) noexcept; // NOLINT(runtime/int)
699bool ConsumeSignedInteger(std::string_view& str, unsigned radix,
700 long long& result) noexcept; // NOLINT(runtime/int)
701} // namespace detail
702
703/**
704 * Parses the string @p str as an integer of the specified radix. If
705 * @p radix is specified as zero, this does radix autosensing using
706 * extended C rules: 0 is octal, 0x is hex, 0b is binary.
707 *
708 * If the string is invalid or if only a subset of the string is valid,
709 * this returns nullopt to signify the error. The string is considered
710 * erroneous if empty or if it overflows T.
711 */
712template <typename T,
713 std::enable_if_t<std::numeric_limits<T>::is_signed, bool> = true>
714inline std::optional<T> parse_integer(std::string_view str,
715 unsigned radix) noexcept {
716 long long val; // NOLINT(runtime/int)
717 if (detail::GetAsSignedInteger(str, radix, val) ||
718 static_cast<T>(val) != val) {
719 return std::nullopt;
720 }
721 return val;
722}
723
724template <typename T,
725 std::enable_if_t<!std::numeric_limits<T>::is_signed, bool> = true>
726inline std::optional<T> parse_integer(std::string_view str,
727 unsigned radix) noexcept {
728 using Int = unsigned long long; // NOLINT(runtime/int)
729 Int val;
730 // The additional cast to unsigned long long is required to avoid the
731 // Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type
732 // 'unsigned __int64' when instantiating getAsInteger with T = bool.
733 if (detail::GetAsUnsignedInteger(str, radix, val) ||
734 static_cast<Int>(static_cast<T>(val)) != val) {
735 return std::nullopt;
736 }
737 return static_cast<T>(val);
738}
739
740/**
741 * Parses the string @p str as an integer of the specified radix. If
742 * @p radix is specified as zero, this does radix autosensing using
743 * extended C rules: 0 is octal, 0x is hex, 0b is binary.
744 *
745 * If the string does not begin with a number of the specified radix,
746 * this returns nullopt to signify the error. The string is considered
747 * erroneous if empty or if it overflows T.
748 * The portion of the string representing the discovered numeric value
749 * is removed from the beginning of the string.
750 */
751template <typename T,
752 std::enable_if_t<std::numeric_limits<T>::is_signed, bool> = true>
753inline std::optional<T> consume_integer(std::string_view* str,
754 unsigned radix) noexcept {
755 using Int = long long; // NOLINT(runtime/int)
756 Int val;
757 if (detail::ConsumeSignedInteger(*str, radix, val) ||
758 static_cast<Int>(static_cast<T>(val)) != val) {
759 return std::nullopt;
760 }
761 return val;
762}
763
764template <typename T,
765 std::enable_if_t<!std::numeric_limits<T>::is_signed, bool> = true>
766inline std::optional<T> consume_integer(std::string_view* str,
767 unsigned radix) noexcept {
768 using Int = unsigned long long; // NOLINT(runtime/int)
769 Int val;
770 if (detail::ConsumeUnsignedInteger(*str, radix, val) ||
771 static_cast<Int>(static_cast<T>(val)) != val) {
772 return std::nullopt;
773 }
774 return val;
775}
776
777/**
778 * Parses the string @p str as a floating point value.
779 *
780 * If the string is invalid or if only a subset of the string is valid,
781 * this returns nullopt to signify the error. The string is considered
782 * erroneous if empty or if it overflows T.
783 */
784template <typename T>
785std::optional<T> parse_float(std::string_view str) noexcept;
786
787template <>
788std::optional<float> parse_float<float>(std::string_view str) noexcept;
789template <>
790std::optional<double> parse_float<double>(std::string_view str) noexcept;
791template <>
792std::optional<long double> parse_float<long double>(
793 std::string_view str) noexcept;
794
795/**
796 * Unescapes a C-style string (reverse operation to raw_ostream::write_escaped).
797 * Scans through @p str until either the end is reached or an unescaped double
798 * quote character is found.
799 *
800 * @param str input string
801 * @param buf buffer for unescaped characters
802 * @return pair of the unescaped string and any remaining input
803 */
804std::pair<std::string_view, std::string_view> UnescapeCString(
805 std::string_view str, SmallVectorImpl<char>& buf);
806
807/**
808 * Like std::format_to_n() in that it writes at most n bytes to the output
809 * buffer, but also includes a terminating null byte in n.
810 *
811 * This is essentially a more performant replacement for std::snprintf().
812 *
813 * @param out The output buffer.
814 * @param n The size of the output buffer.
815 * @param fmt The format string.
816 * @param args The format string arguments.
817 */
818template <class OutputIt, class... Args>
819inline void format_to_n_c_str(OutputIt out, std::iter_difference_t<OutputIt> n,
820 fmt::format_string<Args...> fmt, Args&&... args) {
821 const auto result =
822 fmt::format_to_n(out, n - 1, fmt, std::forward<Args>(args)...);
823 *result.out = '\0';
824}
825
826} // namespace wpi
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or glfw and nanopb were modified for use in Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source including but not limited to compiled object generated and conversions to other media types Work shall mean the work of whether in Source or Object made available under the as indicated by a copyright notice that is included in or attached to the whether in Source or Object that is based or other modifications as a an original work of authorship For the purposes of this Derivative Works shall not include works that remain separable from
Definition ThirdPartyNotices.txt:140
FMT_CONSTEXPR void remove_prefix(size_t n) noexcept
Definition base.h:572
FMT_CONSTEXPR auto compare(basic_string_view other) const -> int
Definition base.h:588
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition sha1.h:30
detail namespace with internal helper functions
Definition input_adapters.h:32
Definition PointerIntPair.h:280
bool GetAsSignedInteger(std::string_view str, unsigned radix, long long &result) noexcept
bool ConsumeUnsignedInteger(std::string_view &str, unsigned radix, unsigned long long &result) noexcept
bool GetAsUnsignedInteger(std::string_view str, unsigned radix, unsigned long long &result) noexcept
bool ConsumeSignedInteger(std::string_view &str, unsigned radix, long long &result) noexcept
Definition ntcore_cpp.h:26
constexpr char hexdigit(unsigned X, bool LowerCase=false) noexcept
hexdigit - Return the hexadecimal character for the given number X (which should be less than 16).
Definition StringExtras.h:38
constexpr std::string_view slice(std::string_view str, std::string_view::size_type start, std::string_view::size_type end) noexcept
Returns a reference to the substring of str from [start, end).
Definition StringExtras.h:447
constexpr std::pair< std::string_view, std::string_view > split(std::string_view str, char separator) noexcept
Splits str into two substrings around the first occurrence of a separator character.
Definition StringExtras.h:468
int compare_lower(std::string_view lhs, std::string_view rhs) noexcept
compare_lower - Compare two strings, ignoring case.
constexpr std::optional< std::string_view > remove_prefix(std::string_view str, std::string_view prefix) noexcept
Return an optional containing str but with prefix removed if the string starts with the prefix.
Definition StringExtras.h:366
constexpr std::string_view ltrim(std::string_view str, char ch) noexcept
Returns str with consecutive ch characters starting from the the left removed.
Definition StringExtras.h:639
constexpr std::span< T > drop_back(std::span< T, N > in, typename std::span< T >::size_type n=1)
Drop the last N elements of the array.
Definition SpanExtras.h:22
constexpr std::span< T > drop_front(std::span< T, N > in, typename std::span< T >::size_type n=1)
Drop the first N elements of the array.
Definition SpanExtras.h:14
std::optional< double > parse_float< double >(std::string_view str) noexcept
constexpr bool isAlnum(char C) noexcept
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
Definition StringExtras.h:77
std::optional< T > consume_integer(std::string_view *str, unsigned radix) noexcept
Parses the string str as an integer of the specified radix.
Definition StringExtras.h:753
std::string_view::size_type find_lower(std::string_view str, char ch, std::string_view::size_type from=0) noexcept
Search for the first character ch in str, ignoring case.
constexpr bool isHexDigit(char C) noexcept
Checks if character C is a hexadecimal numeric character.
Definition StringExtras.h:66
constexpr bool isDigit(char C) noexcept
Checks if character C is one of the 10 decimal digits.
Definition StringExtras.h:61
std::optional< T > parse_integer(std::string_view str, unsigned radix) noexcept
Parses the string str as an integer of the specified radix.
Definition StringExtras.h:714
constexpr unsigned hexDigitValue(char C) noexcept
Interpret the given character C as a hexadecimal digit and return its value.
Definition StringExtras.h:47
constexpr char toLower(char x) noexcept
Returns the corresponding lowercase character if x is uppercase.
Definition StringExtras.h:96
constexpr std::optional< std::string_view > remove_suffix(std::string_view str, std::string_view suffix) noexcept
Return an optional containing str but with suffix removed if the string ends with the suffix.
Definition StringExtras.h:379
constexpr std::string_view trim(std::string_view str, char ch) noexcept
Returns str with consecutive ch characters starting from the left and right removed.
Definition StringExtras.h:676
constexpr char toUpper(char x) noexcept
Returns the corresponding uppercase character if x is lowercase.
Definition StringExtras.h:104
constexpr std::span< T > take_front(std::span< T, N > in, typename std::span< T >::size_type n=1)
Returns a span equal to in but with only the first n elements remaining.
Definition SpanExtras.h:34
constexpr bool contains(std::string_view str, std::string_view other) noexcept
Checks if str contains the substring other.
Definition StringExtras.h:321
bool ends_with_lower(std::string_view str, std::string_view suffix) noexcept
Checks if str ends with the given suffix, ignoring case.
std::string_view::size_type rfind_lower(std::string_view str, char ch, std::string_view::size_type from=std::string_view::npos) noexcept
Search for the last character ch in str, ignoring case.
bool starts_with_lower(std::string_view str, std::string_view prefix) noexcept
Checks if str starts with the given prefix, ignoring case.
constexpr bool equals_lower(std::string_view lhs, std::string_view rhs) noexcept
equals_lower - Check for string equality, ignoring case.
Definition StringExtras.h:147
std::optional< long double > parse_float< long double >(std::string_view str) noexcept
constexpr std::pair< std::string_view, std::string_view > rsplit(std::string_view str, char separator) noexcept
Splits str into two substrings around the last occurrence of a separator character.
Definition StringExtras.h:511
constexpr std::string_view substr(std::string_view str, std::string_view::size_type start, std::string_view::size_type n=std::string_view::npos) noexcept
Returns the substring of str from [start, start + n).
Definition StringExtras.h:225
constexpr bool equals(std::string_view lhs, std::string_view rhs) noexcept
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition StringExtras.h:133
constexpr T mod(U Numerator, V Denominator)
Returns the remainder of the Euclidean division of LHS by RHS.
Definition MathExtras.h:432
constexpr bool isPrint(char C) noexcept
Checks whether character C is printable.
Definition StringExtras.h:90
constexpr std::span< T > take_back(std::span< T, N > in, typename std::span< T >::size_type n=1)
Returns a span equal to in but with only the last n elements remaining.
Definition SpanExtras.h:49
std::pair< std::string_view, std::string_view > UnescapeCString(std::string_view str, SmallVectorImpl< char > &buf)
Unescapes a C-style string (reverse operation to raw_ostream::write_escaped).
void format_to_n_c_str(OutputIt out, std::iter_difference_t< OutputIt > n, fmt::format_string< Args... > fmt, Args &&... args)
Like std::format_to_n() in that it writes at most n bytes to the output buffer, but also includes a t...
Definition StringExtras.h:819
constexpr bool isASCII(char C) noexcept
Checks whether character C is valid ASCII (high bit is zero).
Definition StringExtras.h:82
constexpr bool isAlpha(char C) noexcept
Checks if character C is a valid letter as classified by "C" locale.
Definition StringExtras.h:71
constexpr std::string_view rtrim(std::string_view str, char ch) noexcept
Returns str with consecutive Char characters starting from the right removed.
Definition StringExtras.h:656
std::optional< T > parse_float(std::string_view str) noexcept
Parses the string str as a floating point value.
constexpr bool ends_with(std::string_view str, std::string_view suffix) noexcept
Checks if str ends with the given suffix.
Definition StringExtras.h:278
std::string utohexstr(unsigned long long val, bool lowerCase=false)
Definition StringExtras.h:111
std::optional< float > parse_float< float >(std::string_view str) noexcept
constexpr bool starts_with(std::string_view str, std::string_view prefix) noexcept
Checks if str starts with the given prefix.
Definition StringExtras.h:236
bool contains_lower(std::string_view str, std::string_view other) noexcept
Checks if str contains the substring other, ignoring case.
Definition StringExtras.h:342