66#include < limits>
77#include < string>
88#include < string_view>
9+ #include < utility>
910#include < vector>
1011
1112namespace OpenShock {
1213 bool FormatToString (std::string& out, const char * format, ...);
1314
14- constexpr std::string_view StringTrimLeft (std::string_view view) {
15+ constexpr std::string_view StringTrimLeft (std::string_view view)
16+ {
1517 if (view.empty ()) {
1618 return view;
1719 }
1820
1921 std::size_t pos = 0 ;
20- while (pos < view.size () && isspace (view[pos])) {
22+ while (pos < view.size () && isspace (view[pos]) != 0 ) {
2123 ++pos;
2224 }
2325
2426 return view.substr (pos);
2527 }
26- constexpr std::string_view StringTrimRight (std::string_view view) {
28+ constexpr std::string_view StringTrimRight (std::string_view view)
29+ {
2730 if (view.empty ()) {
2831 return view;
2932 }
3033
3134 std::size_t pos = view.size () - 1 ;
32- while (pos > 0 && isspace (view[pos])) {
35+ while (pos > 0 && isspace (view[pos]) != 0 ) {
3336 --pos;
3437 }
3538
3639 return view.substr (0 , pos + 1 );
3740 }
38- constexpr std::string_view StringTrim (std::string_view view) {
41+ constexpr std::string_view StringTrim (std::string_view view)
42+ {
3943 return StringTrimLeft (StringTrimRight (view));
4044 }
41- constexpr bool StringStartsWith (std::string_view view, std::string_view prefix) {
45+
46+ constexpr bool StringHasPrefix (std::string_view view, char prefix)
47+ {
48+ return !view.empty () && view.front () == prefix;
49+ }
50+ constexpr bool StringHasPrefix (std::string_view view, std::string_view prefix)
51+ {
4252 return view.size () >= prefix.size () && view.substr (0 , prefix.size ()) == prefix;
4353 }
54+ constexpr bool StringHasSuffix (std::string_view view, char suffix)
55+ {
56+ return !view.empty () && view.back () == suffix;
57+ }
58+ constexpr bool StringHasSuffix (std::string_view view, std::string_view suffix)
59+ {
60+ return view.size () >= suffix.size () && view.substr (view.size () - suffix.size (), view.size ()) == suffix;
61+ }
62+
63+ constexpr std::string_view StringRemovePrefix (std::string_view view, char prefix)
64+ {
65+ if (StringHasPrefix (view, prefix)) view.remove_prefix (1 );
66+ return view;
67+ }
68+ constexpr std::string_view StringRemovePrefix (std::string_view view, std::string_view prefix)
69+ {
70+ if (StringHasPrefix (view, prefix)) view.remove_prefix (prefix.length ());
71+ return view;
72+ }
73+ constexpr std::string_view StringRemoveSuffix (std::string_view view, char suffix)
74+ {
75+ if (StringHasSuffix (view, suffix)) view.remove_suffix (1 );
76+ return view;
77+ }
78+ constexpr std::string_view StringRemoveSuffix (std::string_view view, std::string_view suffix)
79+ {
80+ if (StringHasSuffix (view, suffix)) view.remove_prefix (suffix.length ());
81+ return view;
82+ }
83+
84+ constexpr std::string_view StringBeforeFirst (std::string_view view, char delimiter)
85+ {
86+ size_t pos = view.find (delimiter);
87+ if (pos == std::string_view::npos) return view;
88+ return view.substr (0 , pos);
89+ }
90+ constexpr std::string_view StringBeforeFirst (std::string_view view, std::string_view delimiter)
91+ {
92+ size_t pos = view.find (delimiter);
93+ if (pos == std::string_view::npos) return view;
94+ return view.substr (0 , pos);
95+ }
96+ constexpr std::string_view StringBeforeLast (std::string_view view, char delimiter)
97+ {
98+ size_t pos = view.find_last_of (delimiter);
99+ if (pos == std::string_view::npos) return view;
100+ return view.substr (0 , pos);
101+ }
102+ constexpr std::string_view StringBeforeLast (std::string_view view, std::string_view delimiter)
103+ {
104+ size_t pos = view.find_last_of (delimiter);
105+ if (pos == std::string_view::npos) return view;
106+ return view.substr (0 , pos);
107+ }
108+ constexpr std::string_view StringAfterFirst (std::string_view view, char delimiter)
109+ {
110+ size_t pos = view.find (delimiter);
111+ if (pos == std::string_view::npos) return view;
112+ return view.substr (pos + 1 );
113+ }
114+ constexpr std::string_view StringAfterFirst (std::string_view view, std::string_view delimiter)
115+ {
116+ size_t pos = view.find (delimiter);
117+ if (pos == std::string_view::npos) return view;
118+ return view.substr (pos + delimiter.length ());
119+ }
120+ constexpr std::string_view StringAfterLast (std::string_view view, char delimiter)
121+ {
122+ size_t pos = view.find_last_of (delimiter);
123+ if (pos == std::string_view::npos) return view;
124+ return view.substr (pos + 1 );
125+ }
126+ constexpr std::string_view StringAfterLast (std::string_view view, std::string_view delimiter)
127+ {
128+ size_t pos = view.find_last_of (delimiter);
129+ if (pos == std::string_view::npos) return view;
130+ return view.substr (pos + delimiter.length ());
131+ }
132+
44133 template <std::size_t N>
45- constexpr bool TryStringSplit (std::string_view view, char delimiter, std::string_view (&out)[N]) {
134+ constexpr bool TryStringSplit (std::string_view view, char delimiter, std::string_view (&out)[N])
135+ {
46136 std::size_t pos = 0 ;
47137 std::size_t idx = 0 ;
48138 while (pos < view.size () && idx < N) {
@@ -62,8 +152,30 @@ namespace OpenShock {
62152 std::vector<std::string_view> StringSplit (std::string_view view, bool (*predicate)(char delimiter), std::size_t maxSplits = std::numeric_limits<std::size_t>::max());
63153 std::vector<std::string_view> StringSplitNewLines (std::string_view view, std::size_t maxSplits = std::numeric_limits<std::size_t >::max());
64154 std::vector<std::string_view> StringSplitWhiteSpace (std::string_view view, std::size_t maxSplits = std::numeric_limits<std::size_t >::max());
155+ constexpr std::pair<std::string_view, std::string_view> StringSplitByFirst (std::string_view view, char delimiter)
156+ {
157+ size_t pos = view.find (delimiter);
158+ return std::make_pair (view.substr (0 , pos), pos == std::string_view::npos ? std::string_view () : view.substr (pos + 1 ));
159+ }
160+ constexpr std::pair<std::string_view, std::string_view> StringSplitByFirst (std::string_view view, std::string_view delimiter)
161+ {
162+ size_t pos = view.find (delimiter);
163+ return std::make_pair (view.substr (0 , pos), pos == std::string_view::npos ? std::string_view () : view.substr (pos + delimiter.length ()));
164+ }
165+ constexpr std::pair<std::string_view, std::string_view> StringSplitByLast (std::string_view view, char delimiter)
166+ {
167+ size_t pos = view.find_last_of (delimiter);
168+ return std::make_pair (view.substr (0 , pos), pos == std::string_view::npos ? std::string_view () : view.substr (pos + 1 ));
169+ }
170+ constexpr std::pair<std::string_view, std::string_view> StringSplitByLast (std::string_view view, std::string_view delimiter)
171+ {
172+ size_t pos = view.find_last_of (delimiter);
173+ return std::make_pair (view.substr (0 , pos), pos == std::string_view::npos ? std::string_view () : view.substr (pos + delimiter.length ()));
174+ }
65175
66176 bool StringIEquals (std::string_view a, std::string_view b);
177+ bool StringIContains (std::string_view haystack, std::string_view needle);
178+ bool StringHasPrefixIC (std::string_view view, std::string_view prefix);
67179
68180 String StringToArduinoString (std::string_view view);
69181} // namespace OpenShock
0 commit comments