Maze Builder Docs 7.5.6
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 <cstdint>
6#include <iterator>
7#include <list>
8#include <memory>
9#include <sstream>
10#include <string_view>
11#include <string>
12#include <tuple>
13#include <type_traits>
14#include <unordered_map>
15#include <vector>
16
17namespace mazes
18{
19
21
27 {
28 public:
29
34 static std::string concat(const std::string &a, const std::string &b) noexcept;
35
40 static bool contains(const std::string &str, const std::string &substr) noexcept;
41
45 static std::string get_file_extension(const std::string &filename) noexcept;
46
51 static bool ends_with(const std::string &str, const std::string &suffix) noexcept;
52
57 static bool find(std::string_view sv, char c) noexcept;
58
63 static std::string_view find_first_of(const std::string_view &s, const std::string_view &chars) noexcept;
64
69 static std::string_view strip(const std::string_view &s, const std::string_view &to_strip_from_s = " ") noexcept;
70
71 private:
72 // Helper trait to detect if a type has push_back method - local to this function
73 template <typename T, typename = void>
74 struct has_push_back : std::false_type
75 {
76 };
77
78 template <typename T>
79 struct has_push_back<T, std::void_t<decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))>> : std::true_type
80 {
81 };
82
84 static constexpr auto eq = [](const auto &el, const auto &sep) -> bool
85 {
86 using std::is_convertible_v;
87 using std::is_same_v;
88
89 using ElType = std::decay_t<decltype(el)>;
90 using SepType = std::decay_t<decltype(sep)>;
91
92 if constexpr (is_same_v<ElType, SepType>)
93 {
94
95 return el == sep;
96 }
97 else if constexpr (is_convertible_v<ElType, SepType>)
98 {
99
100 return static_cast<SepType>(el) == sep;
101 }
102 else if constexpr (is_convertible_v<SepType, ElType>)
103 {
104
105 return el == static_cast<ElType>(sep);
106 }
107 else
108 {
109
110 return false;
111 }
112 };
113
114 public:
126 template <typename It, typename Oc, typename V, typename Pred>
127 static It split(It it, const It end_it, Oc &dest, const V &sep, Pred f)
128 {
129
130 using std::is_same_v;
131 using std::string;
132
133 using SliceContainer = typename Oc::value_type;
134
135 while (it != end_it)
136 {
137
138 SliceContainer dest_elm{};
139
140 auto slice{it};
141
142 while (slice != end_it)
143 {
144
145 if (f(*slice, sep))
146 break;
147
148 // Handle string vs other containers
149 if constexpr (is_same_v<SliceContainer, string>)
150 {
151
152 dest_elm += *slice;
153 }
154 else if constexpr (has_push_back<SliceContainer>::value)
155 {
156
157 dest_elm.push_back(*slice);
158 }
159 else
160 {
161
162 // For types without push_back, provide a helpful error
163 static_assert(is_same_v<SliceContainer, string> || has_push_back<SliceContainer>::value,
164 "SliceContainer must be std::string or have a push_back method");
165 }
166 ++slice;
167 }
168
169 dest.push_back(dest_elm);
170
171 if (slice == end_it)
172 {
173
174 return end_it;
175 }
176
177 it = ++slice;
178 }
179 return it;
180 }
181
191 template <typename It, typename Oc, typename V>
192 static It split(It it, const It end_it, Oc &dest, const V &sep)
193 {
194
195 return split(it, end_it, dest, sep, eq);
196 }
197
206 template <typename Cin, typename Cout, typename V>
207 static Cout &strsplit(const Cin &str, Cout &dest, const V &sep)
208 {
209
210 split(str.begin(), str.end(), dest, sep, eq);
211
212 return dest;
213 }
214
219 template <typename T>
220 static bool is_whitespace(const T &c)
221 {
222
223 using std::is_same_v;
224 using std::string_view;
225
226 // Use std::string_view for safer character comparison
227 constexpr string_view whitespace_chars = " \t\r\n\v\f";
228
229 // For character types, convert to char for comparison
230 if constexpr (is_same_v<T, char>)
231 {
232 return whitespace_chars.find(c) != string_view::npos;
233 }
234 else
235 {
236 // For other types, do individual comparisons
237 return c == static_cast<T>(' ') ||
238 c == static_cast<T>('\t') ||
239 c == static_cast<T>('\r') ||
240 c == static_cast<T>('\n') ||
241 c == static_cast<T>('\v') ||
242 c == static_cast<T>('\f');
243 }
244 }
245
249 static std::string strip_whitespace(const std::string &s)
250 {
251
252 using std::string;
253 using std::unique;
254
255 string outputString{s};
256
257 auto its = unique(outputString.begin(), outputString.end(),
258 [](const auto &a, const auto &b)
259 {
260 return is_whitespace(a) && is_whitespace(b);
261 });
262
263 outputString.erase(its, outputString.end());
264
265 outputString.shrink_to_fit();
266
267 return outputString;
268 }
269
275 template <typename... Args>
276 static std::string format(std::string_view format_str, const Args &...args) noexcept;
277
278 }; // class
279
280} // namespace
281
282#endif // STRING_UTILS_H
Command-line argument handler with JSON support.
Definition args.h:20
String helper class.
Definition string_utils.h:27
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 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 std::string_view strip(const std::string_view &s, const std::string_view &to_strip_from_s=" ") noexcept
Strip specific characters from the beginning and end of 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:220
static Cout & strsplit(const Cin &str, Cout &dest, const V &sep)
High-level string split function using containers.
Definition string_utils.h:207
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:249
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:127
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:192
Namespace for the maze builder.
Definition algo_interface.h:6