22 typedef std::char_traits<char> traits_type;
23 typedef char value_type;
25 typedef char* pointer;
26 typedef char const* const_pointer;
27 typedef char& reference;
28 typedef char const& const_reference;
30 typedef const_pointer iterator;
31 typedef const_pointer const_iterator;
32 typedef std::reverse_iterator< const_iterator > reverse_iterator;
33 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
35 typedef std::size_t size_type;
36 typedef std::ptrdiff_t difference_type;
38 string_view() noexcept
43 string_view(string_view
const& other)
noexcept =
default;
45 string_view(
char const* s, size_type count) noexcept
50 string_view(
char const* s) noexcept
52 , size_(traits_type::length(s))
55 string_view(
char const* s,
char const* e) noexcept
60 string_view(std::nullptr_t)
noexcept =
delete;
62 string_view& operator=(string_view
const& other)
noexcept =
default;
64 const_iterator begin() const noexcept {
return data_; }
65 const_iterator end() const noexcept {
return data_ + size_; }
67 const_iterator cbegin() const noexcept {
return begin(); }
68 const_iterator cend() const noexcept {
return end(); }
70 const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end()); }
71 const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin()); }
73 const_reverse_iterator crbegin() const noexcept {
return rbegin(); }
74 const_reverse_iterator crend() const noexcept {
return rend(); }
76 size_type size() const noexcept {
return size_; }
77 size_type length() const noexcept {
return size_; }
78 size_type max_size() const noexcept {
return (std::numeric_limits< size_type >::max)(); }
80 bool empty() const noexcept
85 const_reference operator[](size_type pos)
const
90 const_reference
at(size_type pos)
const
93 throw std::out_of_range(
"nonstring_view::at()");
97 const_reference front()
const {
return data_at(0); }
98 const_reference
back()
const {
return data_at(size() - 1); }
100 const_pointer data() const noexcept {
return data_; }
101 const_pointer data_end() const noexcept {
return data_ + size_; }
103 void remove_prefix(size_type n)
110 void remove_suffix(size_type n)
116 void swap(string_view& other)
noexcept
118 const string_view tmp(other);
123 size_type copy(
char* dest, size_type n, size_type pos = 0)
const
126 throw std::out_of_range(
"nonstring_view::copy()");
128 const size_type rlen = (std::min)(n, size() - pos);
129 (void)traits_type::copy(dest, data() + pos, rlen);
133 string_view
substr(size_type pos = 0, size_type n = npos)
const
136 throw std::out_of_range(
"nonstring_view::substr()");
137 return string_view{ data() + pos, (std::min)(n, size() - pos) };
142 int compare(string_view other)
const noexcept
144 if (
const int result = traits_type::compare(data(), other.data(), (std::min)(size(), other.size())))
147 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
150 int compare(size_type pos1, size_type n1, string_view other)
const
152 return substr(pos1, n1).compare(other);
155 int compare(size_type pos1, size_type n1, string_view other, size_type pos2, size_type n2)
const
157 return substr(pos1, n1).compare(other.substr(pos2, n2));
160 int compare(
char const* s)
const
162 return compare(string_view{ s });
165 int compare(size_type pos1, size_type n1,
char const* s)
const
167 return substr(pos1, n1).compare(string_view{ s });
170 int compare(size_type pos1, size_type n1,
char const* s, size_type n2)
const
172 return substr(pos1, n1).compare(string_view{ s, n2 });
175 bool starts_with(string_view v)
const noexcept
177 return size() >= v.size() && compare(0, v.size(), v) == 0;
180 bool starts_with(
char c)
const noexcept
182 return starts_with(string_view{ &c, 1 });
185 bool starts_with(
char const* s)
const
187 return starts_with(string_view{ s });
190 bool ends_with(string_view v)
const noexcept
192 return size() >= v.size() && compare(size() - v.size(), npos, v) == 0;
195 bool ends_with(
char c)
const noexcept
197 return ends_with(string_view{ &c, 1 });
200 bool ends_with(
char const* s)
const
202 return ends_with(string_view{ s });
205 size_type find(string_view v, size_type pos = 0) const noexcept
207 return assert(v.size() == 0 || v.data() !=
nullptr)
210 std::search(cbegin() + pos, cend(), v.cbegin(), v.cend(), traits_type::eq)
214 size_type find(
char c, size_type pos = 0) const noexcept
216 return find(string_view{ &c, 1 }, pos);
219 size_type find(
char const* s, size_type pos, size_type n)
const
221 return find(string_view{ s, n }, pos);
224 size_type find(
char const* s, size_type pos = 0)
const
226 return find(string_view{ s }, pos);
229 size_type rfind(string_view v, size_type pos = npos)
const noexcept
231 if (size() < v.size())
238 return (std::min)(size(), pos);
241 const_iterator last = cbegin() + (std::min)(size() - v.size(), pos) + v.size();
242 const_iterator result = std::find_end(cbegin(), last, v.cbegin(), v.cend(), traits_type::eq);
244 return result != last ? size_type(result - cbegin()) : npos;
247 size_type rfind(
char c, size_type pos = npos)
const noexcept
249 return rfind(string_view{ &c, 1 }, pos);
252 size_type rfind(
char const* s, size_type pos, size_type n)
const
254 return rfind(string_view{ s, n }, pos);
257 size_type rfind(
char const* s, size_type pos = npos)
const
259 return rfind(string_view{ s }, pos);
262 size_type find_first_of(string_view v, size_type pos = 0) const noexcept
266 : to_pos(std::find_first_of(cbegin() + pos, cend(), v.cbegin(), v.cend(), traits_type::eq));
269 size_type find_first_of(
char c, size_type pos = 0) const noexcept
271 return find_first_of(string_view{ &c, 1 }, pos);
274 size_type find_first_of(
char const* s, size_type pos, size_type n)
const
276 return find_first_of(string_view{ s, n }, pos);
279 size_type find_first_of(
char const* s, size_type pos = 0)
const
281 return find_first_of(string_view{ s }, pos);
284 size_type find_last_of(string_view v, size_type pos = npos)
const noexcept
289 ? find_last_of(v, size() - 1)
290 : to_pos(std::find_first_of(const_reverse_iterator(cbegin() + pos + 1), crend(), v.cbegin(), v.cend(), traits_type::eq));
293 size_type find_last_of(
char c, size_type pos = npos)
const noexcept
295 return find_last_of(string_view{ &c, 1 }, pos);
298 size_type find_last_of(
char const* s, size_type pos, size_type count)
const
300 return find_last_of(string_view{ s, count }, pos);
303 size_type find_last_of(
char const* s, size_type pos = npos)
const
305 return find_last_of(string_view{ s }, pos);
308 size_type find_first_not_of(string_view v, size_type pos = 0) const noexcept
312 : to_pos(std::find_if(cbegin() + pos, cend(), not_in_view(v)));
315 size_type find_first_not_of(
char c, size_type pos = 0) const noexcept
317 return find_first_not_of(string_view{ &c, 1 }, pos);
320 size_type find_first_not_of(
char const* s, size_type pos, size_type count)
const
322 return find_first_not_of(string_view{ s, count }, pos);
325 size_type find_first_not_of(
char const* s, size_type pos = 0)
const
327 return find_first_not_of(string_view{ s }, pos);
330 size_type find_last_not_of(string_view v, size_type pos = npos)
const noexcept
335 ? find_last_not_of(v, size() - 1)
336 : to_pos(std::find_if(const_reverse_iterator(cbegin() + pos + 1), crend(), not_in_view(v)));
339 size_type find_last_not_of(
char c, size_type pos = npos)
const noexcept
341 return find_last_not_of(string_view{ &c, 1 }, pos);
344 size_type find_last_not_of(
char const* s, size_type pos, size_type count)
const
346 return find_last_not_of(string_view{ s, count }, pos);
349 size_type find_last_not_of(
char const* s, size_type pos = npos)
const
351 return find_last_not_of(string_view{ s }, pos);
354 bool contains(
const string_view right)
const noexcept {
return find(right) != npos; }
355 bool contains(
const char right)
const noexcept {
return find(right) != npos; }
356 bool contains(
const char*
const right)
const {
return find(right) != npos; }
358 enum : size_type { npos = size_type(-1) };
363 const string_view& v;
365 explicit not_in_view(string_view& v_) : v(v_) {}
367 bool operator()(
char c)
const
369 return npos == v.find_first_of(c);
373 size_type to_pos(const_iterator it)
const
375 return it == cend() ? npos : size_type(it - cbegin());
378 size_type to_pos(const_reverse_iterator it)
const
380 return it == crend() ? npos : size_type(crend() - it - 1);
383 const_reference data_at(size_type pos)
const
385 return assert(pos < size()), data_[pos];
394 string_view(std::string
const& s) noexcept
399 explicit operator std::string()
const
404 std::string to_string()
const
406 return std::string(begin(), end());
410 bool is_inside(string_view bigger_string)
const
412 return bigger_string.data() - this->data() >= 0 && this->data_end() - bigger_string.data_end() >= 0;
416inline bool operator== (string_view lhs, string_view rhs)
noexcept {
return lhs.size() == rhs.size() && lhs.compare(rhs) == 0; }
417inline bool operator!= (string_view lhs, string_view rhs)
noexcept {
return !(lhs == rhs); }
418inline bool operator< (string_view lhs, string_view rhs)
noexcept {
return lhs.compare(rhs) < 0; }
419inline bool operator<= (string_view lhs, string_view rhs)
noexcept {
return lhs.compare(rhs) <= 0; }
420inline bool operator> (string_view lhs, string_view rhs)
noexcept {
return lhs.compare(rhs) > 0; }
421inline bool operator>= (string_view lhs, string_view rhs)
noexcept {
return lhs.compare(rhs) >= 0; }
423inline std::string to_string(string_view v) {
return { v.begin(), v.end() }; }
427 constexpr bool isalpha(
char32_t cp)
noexcept {
return (cp >= 65 && cp <= 90) || (cp >= 97 && cp <= 122); }
428 constexpr bool isdigit(
char32_t cp)
noexcept {
return cp >= 48 && cp <= 57; }
429 constexpr bool isodigit(
char32_t cp)
noexcept {
return cp >= 48 && cp <= 55; }
430 constexpr bool isxdigit(
char32_t d)
noexcept {
return (d >= 48 && d <= 57) || (d >= 65 && d <= 70) || (d >= 97 && d <= 102); }
431 constexpr bool isalnum(
char32_t cp)
noexcept {
return ascii::isdigit(cp) || ascii::isalpha(cp); }
432 constexpr bool isident(
char32_t cp)
noexcept {
return ascii::isdigit(cp) || ascii::isalpha(cp) || cp == 95; }
433 constexpr bool isidentstart(
char32_t cp)
noexcept {
return ascii::isalpha(cp) || cp == 95; }
434 constexpr bool isspace(
char32_t cp)
noexcept {
return (cp >= 9 && cp <= 13) || cp == 32; }
435 constexpr bool ispunct(
char32_t cp)
noexcept {
return (cp >= 33 && cp <= 47) || (cp >= 58 && cp <= 64) || (cp >= 91 && cp <= 96) || (cp >= 123 && cp <= 126); }
436 constexpr bool islower(
char32_t cp)
noexcept {
return cp >= 97 && cp <= 122; }
437 constexpr bool isupper(
char32_t cp)
noexcept {
return cp >= 65 && cp <= 90; }
438 constexpr bool iscntrl(
char32_t cp)
noexcept {
return cp == 0x7F || cp < 0x20; }
439 constexpr bool isblank(
char32_t cp)
noexcept {
return cp == 32 || cp == 9; }
440 constexpr bool isgraph(
char32_t cp)
noexcept {
return cp >= 33 && cp <= 126; }
441 constexpr bool isprint(
char32_t cp)
noexcept {
return cp >= 32 && cp <= 126; }
443 constexpr char32_t toupper(
char32_t cp)
noexcept {
return (cp >= 97 && cp <= 122) ? (cp ^ 0b100000) : cp; }
444 constexpr char32_t tolower(
char32_t cp)
noexcept {
return (cp >= 65 && cp <= 90) ? (cp | 0b100000) : cp; }
447 constexpr char32_t number_to_digit(
int v)
noexcept {
return char32_t(v) + 48; }
449 constexpr char32_t number_to_xdigit(
int v)
noexcept {
return (v > 9) ? (char32_t(v - 10) + 65) : (char32_t(v) + 48); }
452 constexpr int digit_to_number(
char32_t cp)
noexcept {
return int(cp - 48); }
455 constexpr int xdigit_to_number(
char32_t cp)
noexcept {
return isdigit(cp) ? int(cp - 48) : ((int(cp) & ~0b100000) - 55); }
462inline string_view trimmed_whitespace_right(string_view str)
noexcept {
return string_view(str.begin(), std::find_if_not(str.rbegin(), str.rend(), ascii::isspace).base()); }
463inline string_view trimmed_whitespace_left(string_view str)
noexcept {
return string_view(std::find_if_not(str.begin(), str.end(), ascii::isspace), str.end()); }
464inline string_view trimmed_whitespace(string_view str)
noexcept {
return trimmed_whitespace_left(trimmed_whitespace_right(str)); }
465inline string_view trimmed_until(string_view str,
char chr)
noexcept {
return string_view(std::find(str.begin(), str.end(), chr), str.end()); }
466inline string_view trimmed(string_view str,
char chr)
noexcept {
return string_view(std::find_if_not(str.begin(), str.end(), [chr](
char c) { return c == chr; }), str.end()); }
468inline std::string trimmed_whitespace_right(std::string str)
noexcept { str.erase(std::find_if_not(str.rbegin(), str.rend(), ascii::isspace).base(), str.end());
return str; }
469inline std::string trimmed_whitespace_left(std::string str)
noexcept { str.erase(str.begin(), std::find_if_not(str.begin(), str.end(), ascii::isspace));
return str; }
470inline std::string trimmed_whitespace(std::string str)
noexcept {
return trimmed_whitespace_left(trimmed_whitespace_right(std::move(str))); }
471inline std::string trimmed_until(std::string str,
char chr)
noexcept { str.erase(str.begin(), std::find(str.begin(), str.end(), chr));
return str; }
472inline std::string trimmed(std::string str,
char chr)
noexcept { str.erase(str.begin(), std::find_if_not(str.begin(), str.end(), [chr](
char c) { return c == chr; }));
return str; }
473template <
typename FUNC>
474inline string_view trimmed_while(string_view str, FUNC&& func)
noexcept { return ::ghassanpl::string_ops::string_view(std::find_if_not(str.begin(), str.end(), std::forward<FUNC>(func)), str.end()); }
476inline void trim_whitespace_right(string_view& str)
noexcept { str = string_view(str.begin(), std::find_if_not(str.rbegin(), str.rend(), ascii::isspace).base()); }
477inline void trim_whitespace_left(string_view& str)
noexcept { str = string_view(std::find_if_not(str.begin(), str.end(), ascii::isspace), str.end()); }
478inline void trim_whitespace(string_view& str)
noexcept { trim_whitespace_left(str); trim_whitespace_right(str); }
479inline void trim_until(string_view& str,
char chr)
noexcept { str = trimmed_until(str, chr); }
480inline void trim(string_view& str,
char chr)
noexcept { str = trimmed(str, chr); }
481template <
typename FUNC>
482inline void trim_while(string_view& str, FUNC&& func)
noexcept { str = trimmed_while(str, std::forward<FUNC>(func)); }
493inline char consume(string_view& str)
497 const auto result = str[0];
498 str.remove_prefix(1);
504inline bool consume(string_view& str,
char val)
506 if (str.starts_with(val))
508 str.remove_prefix(1);
516inline bool consume(string_view& str, string_view val)
518 if (str.starts_with(val))
520 str.remove_prefix(val.size());
528inline char consume_any(string_view& str, string_view chars)
530 if (!str.empty() && chars.contains(str[0]))
532 const auto result = str[0];
533 str.remove_prefix(1);
543 const auto start = str.begin();
544 while (!str.empty() && chars.contains(str[0]))
545 str.remove_prefix(1);
546 return string_view{ start, str.begin() };
551template <
typename PRED>
552inline char consume(string_view& str, PRED&& pred)
554 if (!str.empty() && pred(str[0]))
556 const auto result = str[0];
557 str.remove_prefix(1);
564inline char consume_or(string_view& str,
char or_else)
568 const auto result = str[0];
569 str.remove_prefix(1);
578 if (str.ends_with(val))
580 str.remove_suffix(1);
592 if (str.ends_with(val))
594 str.remove_suffix(val.size());
602template <
typename FUNC>
603inline string_view
consume_while(string_view& str, FUNC&& pred)
605 const auto start = str.begin();
606 while (!str.empty() && pred(str[0]))
607 str.remove_prefix(1);
608 return string_view(start, str.begin());
615 const auto start = str.begin();
616 while (str.starts_with(c))
617 str.remove_prefix(1);
618 return string_view(start, str.begin());
623template <
typename FUNC>
624inline string_view
consume_until(string_view& str, FUNC&& pred)
626 const auto start = str.begin();
627 while (!str.empty() && !pred(str[0]))
628 str.remove_prefix(1);
629 return string_view(start, str.begin());
636 const auto start = str.begin();
637 while (!str.empty() && str[0] != c)
638 str.remove_prefix(1);
639 return string_view(start, str.begin());
644inline string_view
consume_until(string_view& str, string_view end)
646 const auto it = std::search(str.begin(), str.end(), end.begin(), end.end());
647 const auto result = string_view(str.begin(), it);
648 str = { it, str.end() };
658 const auto start = str.begin();
659 while (!str.empty() && str[0] != c)
660 str.remove_prefix(1);
662 return string_view(start, str.begin());
667inline string_view
consume_n(string_view& str,
size_t n)
669 n = std::min(str.size(), n);
670 auto result = str.substr(0, n);
671 str.remove_prefix(n);
677template <
typename FUNC>
678inline string_view
consume_n(string_view& str,
size_t n, FUNC&& pred)
680 n = std::min(str.size(), n);
681 const auto start = str.begin();
682 while (n-- && !str.empty() && pred(str[0]))
683 str.remove_prefix(1);
684 return string_view(start, str.begin());
695template <
typename FUNC>
696void split(string_view source,
char delim, FUNC&& func)
699 while ((next = source.find_first_of(delim)) != std::string::npos)
701 func(source.substr(0, next),
false);
702 source.remove_prefix(next + 1);
710template <
typename FUNC>
711void split(string_view source, string_view delim, FUNC&& func)
713 const size_t delim_size = delim.size();
714 if (delim_size == 0)
return;
717 while ((next = source.find(delim)) != std::string::npos)
719 func(source.substr(0, next),
false);
720 source.remove_prefix(next + delim_size);
727inline std::pair<string_view, string_view>
single_split(string_view src,
char delim)
noexcept
729 size_t split_at = src.find_first_of(delim);
730 if (split_at == std::string::npos)
732 return { src.substr(0, split_at), src.substr(split_at + 1) };
739inline bool single_split(string_view src,
char delim, string_view* first, string_view* second)
noexcept
741 size_t split_at = src.find_first_of(delim);
742 if (split_at == std::string::npos)
744 if (first) *first = src.substr(0, split_at);
745 if (second) *second = src.substr(split_at + 1);
761std::string
join(T&& source)
763 std::stringstream strm{};
764 for (
auto&& p : std::forward<T>(source))
770template <
typename T,
typename DELIM>
771std::string
join(T&& source, DELIM
const& delim)
773 std::stringstream strm{};
775 for (
auto&& p : std::forward<T>(source))
777 if (!first) strm << delim;
787template <
typename T,
typename FUNC,
typename DELIM>
788std::string
join(T&& source, DELIM
const& delim, FUNC&& transform_func)
790 std::stringstream strm;
792 for (
auto&& p : source)
794 if (!first) strm << delim;
795 strm << transform_func(p);
805 struct from_chars_result
807 const char* ptr =
nullptr;
812 from_chars_result integer_from_chars(
const char*
const first,
const char*
const last, T& out_value,
const int base)
noexcept
814 assert(base >= 2 && base <= 36);
816 bool minus_sign =
false;
817 const char* next = first;
819 if (std::is_signed<T>::value && next != last && *next ==
'-')
825 using unsigned_t =
typename std::make_unsigned<T>::type;
827 const unsigned_t uint_max_val =
static_cast<unsigned_t
>(-1);
828 const unsigned_t int_max_val =
static_cast<unsigned_t
>(uint_max_val >> 1);
829 const unsigned_t abs_int_min_val =
static_cast<unsigned_t
>(int_max_val + 1);
831 unsigned_t risky_val{};
832 unsigned_t max_digit{};
834 if (std::is_signed<T>::value)
838 risky_val =
static_cast<unsigned_t
>(abs_int_min_val / base);
839 max_digit =
static_cast<unsigned_t
>(abs_int_min_val % base);
843 risky_val =
static_cast<unsigned_t
>(int_max_val / base);
844 max_digit =
static_cast<unsigned_t
>(int_max_val % base);
849 risky_val =
static_cast<unsigned_t
>(uint_max_val / base);
850 max_digit =
static_cast<unsigned_t
>(uint_max_val % base);
855 bool overflowed =
false;
857 for (; next != last; ++next)
859 const int digit = ascii::digit_to_number(
static_cast<char32_t>(*next));
864 if (value < risky_val || (value == risky_val &&
static_cast<unsigned_t
>(digit) <= max_digit))
866 value =
static_cast<unsigned_t
>(value * base + digit);
874 if (next - first ==
static_cast<ptrdiff_t
>(minus_sign))
875 return { first,
true };
878 return { next,
true };
880 if (std::is_signed<T>::value && minus_sign)
881 value =
static_cast<unsigned_t
>(0 - value);
883 out_value =
static_cast<T
>(value);
885 return { next,
false };
888 template <
typename T>
889 T string_to_number(string_view str,
size_t* idx =
nullptr,
int base = 10) noexcept
892 const auto res = integer_from_chars(str.data(), str.data_end(), value, base);
893 if (idx && !res.failed)
894 *idx = size_t(res.ptr - str.data());
898 template <
typename T>
899 inline T consume_num(string_view& str,
int base = 10) noexcept
902 const T result = detail::string_to_number<T>(str, &idx, base);
903 str.remove_prefix(idx);
911inline int stoi(string_view str,
size_t* idx =
nullptr,
int base = 10) noexcept {
return detail::string_to_number<int>(str, idx, base); }
912inline long stol(string_view str,
size_t* idx =
nullptr,
int base = 10) noexcept {
return detail::string_to_number<long>(str, idx, base); }
913inline long long stoll(string_view str,
size_t* idx =
nullptr,
int base = 10) noexcept {
return detail::string_to_number<long long>(str, idx, base); }
914inline unsigned long stoul(string_view str,
size_t* idx =
nullptr,
int base = 10) noexcept {
return detail::string_to_number<unsigned long>(str, idx, base); }
915inline unsigned long long stoull(string_view str,
size_t* idx =
nullptr,
int base = 10) noexcept {
return detail::string_to_number<unsigned long long>(str, idx, base); }
917inline int consume_int(string_view& str,
int base = 10) noexcept {
return detail::consume_num<int>(str, base); }
918inline long consume_long(string_view& str,
int base = 10) noexcept {
return detail::consume_num<long>(str, base); }
919inline long long consume_long_long(string_view& str,
int base = 10) noexcept {
return detail::consume_num<long long>(str, base); }
920inline unsigned long consume_unsigned_long(string_view& str,
int base = 10) noexcept {
return detail::consume_num<unsigned long>(str, base); }
921inline unsigned long long consume_usigned_long_long(string_view& str,
int base = 10) noexcept {
return detail::consume_num<unsigned long long>(str, base); }
924bool consume_num(string_view& str, T& out_val,
int base = 10) noexcept
926 const auto res = detail::integer_from_chars(str.data(), str.data_end(), value, base);
constexpr char32_t number_to_digit(int v) noexcept
Convert a number between 0 and 9 to its ASCII representation (only gives meaningful results with argu...
constexpr int digit_to_number(char32_t cp) noexcept
Convert an ASCII digit character to its numerical value (only gives meaningful results with valid dig...
constexpr char32_t number_to_xdigit(int v) noexcept
Convert a number between 0 and 15 to its ASCII representation (only gives meaningful results with arg...
constexpr int xdigit_to_number(char32_t cp) noexcept
Convert an ASCII xdigit to its numerical value (only gives meaningful results with valid xdigit argum...
constexpr auto join(std::array< T, Ns >... arrays)
Arrays.
constexpr decltype(auto) at(random_access_range auto &range, std::integral auto index)
Returns a reference to the value at index of range
constexpr std::pair< std::span< T >, std::span< T > > split_at(std::span< T, N > span, size_t index)
Span stuff.
constexpr __contains_fn contains
contains(range, el)
char consume_or(std::string_view &str, char or_else)
Consumes the first character from str, returning it, or or_else if string is empty.
std::string_view consume_while(std::string_view &str, FUNC &&pred)
Consumes characters from the beginning of str while they match pred(str[0]).
char consume_any(std::string_view &str, ARGS &&... args)
Consumes any of the characters in 'chars' if it's the first char of str.
std::string_view consume_until(std::string_view &str, FUNC &&pred)
Consumes characters from the beginning of str until one matches pred(str[0]), exclusive.
constexpr bool is_inside(std::string_view big_string, std::string_view smaller_string)
Checks if smaller_string is a true subset of big_string (true subset meaning they view over overlappi...
constexpr void split(std::string_view source, char delim, FUNC &&func) noexcept(noexcept(func(std::string_view{}, true)))
Performs a basic "split" operation, calling func for each part of source delimited by delim.
std::string_view consume_while_any(std::string_view &str, ARGS &&... args)
Consumes a run of any of the characters in 'chars' at the beginning of str.
char consume(std::string_view &str)
Consumes and returns the first character in the str, or \0 if no more characters.
std::string_view consume_until_delim(std::string_view &str, char c)
Consumes characters from the beginning of str until one is equal to c, inclusive.
constexpr std::pair< std::string_view, std::string_view > single_split(std::string_view src, char delim) noexcept
Splits src once on the first instance of delim
constexpr std::string_view back(std::string_view child_to_back_up, std::string_view parent, size_t n=1) noexcept
Creates a string_view with its beginning moved back by n characters, limited to a parent range.
bool consume_at_end(std::string_view &str, char val)
Consumes the last character from str if it matches val.
std::string_view substr(std::string_view str, intptr_t start, size_t count=std::string::npos) noexcept
Gets a substring of str starting at start and containing count characters.
std::string_view consume_n(std::string_view &str, size_t n)
Consumes at most n characters from the beginning of str.
The below code is based on Sun's libm library code, which is licensed under the following license: