Maze Builder Docs 8.2.1
Loading...
Searching...
No Matches
string_utils.h
Go to the documentation of this file.
1#ifndef STRING_UTILS_H
2#define STRING_UTILS_H
3
4#include <algorithm>
5#include <string_view>
6#include <string>
7#include <type_traits>
8
11namespace mazes
12{
18 {
19 public:
24 static std::string concat(const std::string& a, const std::string& b) noexcept;
25
30 static bool contains(const std::string& str, const std::string& substr) noexcept;
31
35 static std::string get_file_extension(const std::string& filename) noexcept;
36
41 static bool ends_with(const std::string& str, const std::string& suffix) noexcept;
42
47 static bool find(std::string_view sv, char c) noexcept;
48
53 static std::string_view find_first_of(const std::string_view& s, const std::string_view& chars) noexcept;
54
55 private:
56 // Helper trait to detect if a type has push_back method - local to this function
57 template <typename T, typename = void>
58 struct has_push_back : std::false_type
59 {
60 };
61
62 template <typename T>
63 struct has_push_back<T, std::void_t<decltype(std::declval<T>().push_back(std::declval<typename T::value_type>())
64 )>> : std::true_type
65 {
66 };
67
69 static constexpr auto eq = []<typename T0, typename T1>(const T0& el, const T1& sep) -> bool
70 {
71 using std::is_convertible_v;
72 using std::is_same_v;
73
74 using ElType = std::decay_t<T0>;
75 using SepType = std::decay_t<T1>;
76
77 if constexpr (is_same_v<ElType, SepType>)
78 {
79 return el == sep;
80 }
81 else if constexpr (is_convertible_v<ElType, SepType>)
82 {
83 return static_cast<SepType>(el) == sep;
84 }
85 else if constexpr (is_convertible_v<SepType, ElType>)
86 {
87 return el == static_cast<ElType>(sep);
88 }
89 else
90 {
91 return false;
92 }
93 };
94
95 public:
107 template <typename It, typename Oc, typename V, typename Pred>
108 static It split(It it, const It end_it, Oc& dest, const V& sep, Pred f)
109 {
110 using std::is_same_v;
111 using std::string;
112
113 using SliceContainer = typename Oc::value_type;
114
115 while (it != end_it)
116 {
117 SliceContainer dest_elm{};
118
119 auto slice{it};
120
121 while (slice != end_it)
122 {
123 if (f(*slice, sep))
124 break;
125
126 // Handle string vs other containers
127 if constexpr (is_same_v<SliceContainer, string>)
128 {
129 dest_elm += *slice;
130 }
131 else if constexpr (has_push_back<SliceContainer>::value)
132 {
133 dest_elm.push_back(*slice);
134 }
135 else
136 {
137 // For types without push_back, provide a helpful error
138 static_assert(is_same_v<SliceContainer, string> || has_push_back<SliceContainer>::value,
139 "SliceContainer must be std::string or have a push_back method");
140 }
141 ++slice;
142 }
143
144 dest.push_back(dest_elm);
145
146 if (slice == end_it)
147 {
148 return end_it;
149 }
150
151 it = ++slice;
152 }
153 return it;
154 }
155
165 template <typename It, typename Oc, typename V>
166 static It split(It it, const It end_it, Oc& dest, const V& sep)
167 {
168 return split(it, end_it, dest, sep, eq);
169 }
170
179 template <typename Cin, typename Cout, typename V>
180 static Cout& strsplit(const Cin& str, Cout& dest, const V& sep)
181 {
182 split(str.begin(), str.end(), dest, sep, eq);
183 return dest;
184 }
185
190 template <typename T>
191 static bool is_whitespace(const T& c)
192 {
193 using std::is_same_v;
194 using std::string_view;
195
196 // Use std::string_view for safer character comparison
197 constexpr string_view whitespace_chars = " \t\r\n\v\f";
198
199 // For character types, convert to char for comparison
200 if constexpr (is_same_v<T, char>)
201 {
202 return whitespace_chars.find(c) != string_view::npos;
203 }
204 else
205 {
206 // For other types, do individual comparisons
207 return c == static_cast<T>(' ') ||
208 c == static_cast<T>('\t') ||
209 c == static_cast<T>('\r') ||
210 c == static_cast<T>('\n') ||
211 c == static_cast<T>('\v') ||
212 c == static_cast<T>('\f');
213 }
214 }
215
219 static std::string strip_whitespace(const std::string& s)
220 {
221 using std::string;
222 using std::unique;
223
224 string outputString{s};
225
226 const auto its = unique(outputString.begin(), outputString.end(),
227 [](const auto& a, const auto& b)
228 {
229 return is_whitespace(a) && is_whitespace(b);
230 });
231
232 outputString.erase(its, outputString.end());
233
234 outputString.shrink_to_fit();
235
236 return outputString;
237 }
238
244 template <typename... Args>
245 static std::string format(std::string_view format_str, const Args&... args) noexcept;
246 }; // class
247} // namespace
248
249#endif // STRING_UTILS_H
Command-line argument handler with JSON support.
Definition args.h:19
String helper class.
Definition string_utils.h:18
static std::string get_file_extension(const std::string &filename) noexcept
Extract file extension from a filename.
static bool find(std::string_view sv, char c) noexcept
Find a character in a string_view.
static bool contains(const std::string &str, const std::string &substr) noexcept
Check if a string contains a substring.
static std::string_view find_first_of(const std::string_view &s, const std::string_view &chars) noexcept
Find the first occurrence of any character from a set in a string view.
static std::string concat(const std::string &a, const std::string &b) noexcept
Combine and return two strings.
static bool is_whitespace(const T &c)
Checks if a character is a whitespace character.
Definition string_utils.h:191
static std::string format(std::string_view format_str, const Args &... args) noexcept
Simple wrapper for fmt::format using runtime format strings (string_view)
static Cout & strsplit(const Cin &str, Cout &dest, const V &sep)
High-level string split function using containers.
Definition string_utils.h:180
static bool ends_with(const std::string &str, const std::string &suffix) noexcept
Check if a string ends with a specific suffix.
static std::string strip_whitespace(const std::string &s)
Removes consecutive whitespace characters from a string, leaving only single whitespace between non-w...
Definition string_utils.h:219
static It split(It it, const It end_it, Oc &dest, const V &sep, Pred f)
Splits a range into slices based on a separator and stores the results in a destination container.
Definition string_utils.h:108
static It split(It it, const It end_it, Oc &dest, const V &sep)
Generic split function with default equality predicate.
Definition string_utils.h:166