18inline std::string
fstring(
const std::string format, ...) {
19 constexpr std::size_t size = 256;
21 fmt_str.resize(size + 1);
27 va_start(args, format);
28 vsnprintf(&fmt_str[0], fmt_str.size(), format.c_str(), args);
32 fmt_str.erase(std::find(fmt_str.begin(), fmt_str.end(),
'\0'), fmt_str.end());
38inline std::string
fstring(
const std::size_t size,
const std::string format,
43 fmt_str.resize(size + 1);
49 va_start(args, format);
50 vsnprintf(&fmt_str[0], fmt_str.size(), format.c_str(), args);
54 fmt_str.erase(std::find(fmt_str.begin(), fmt_str.end(),
'\0'), fmt_str.end());
64 const auto wc = std::find(s2.cbegin(), s2.cend(),
'*');
68 const auto pos_wc = std::size_t(std::distance(s2.cbegin(), wc));
70 const auto s1_front = s1.substr(0, pos_wc);
71 const auto s2_front = s2.substr(0, pos_wc);
74 const auto len_back = std::size_t(std::distance(wc + 1, s2.cend()));
76 const auto pos_1_back = s1.length() > len_back ? s1.length() - len_back : 0;
77 const auto s1_back = s1.substr(pos_1_back, std::string::npos);
78 const auto s2_back = s2.substr(pos_wc + 1, std::string::npos);
80 return s1_front == s2_front && s1_back == s2_back;
87 return static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
90inline std::string
tolower(std::string t_string) {
91 for (
auto &c : t_string) {
99inline bool contains(std::string_view the_string, std::string_view sub_string) {
100 return the_string.find(sub_string) != std::string::npos;
105 const std::string &sub_string) {
106 return tolower(the_string).find(
tolower(sub_string)) != std::string::npos;
111 const std::vector<std::string> &sub_strings) {
112 for (
const auto &substr : sub_strings) {
121 const std::vector<std::string> &sub_strings) {
122 for (
const auto &substr : sub_strings) {
131inline bool ci_compare(std::string_view s1, std::string_view s2) {
133 s1.cbegin(), s1.cend(), s2.cbegin(), s2.cend(),
134 [](
char c1,
char c2) { return qip::tolower(c1) == qip::tolower(c2); });
141 const auto wc = std::find(s2.cbegin(), s2.cend(),
'*');
145 const auto pos_wc = std::size_t(std::distance(s2.cbegin(), wc));
147 const auto s1_front = s1.substr(0, pos_wc);
148 const auto s2_front = s2.substr(0, pos_wc);
151 const auto len_back = std::size_t(std::distance(wc + 1, s2.cend()));
153 const auto pos_1_back = s1.length() > len_back ? s1.length() - len_back : 0;
154 const auto s1_back = s1.substr(pos_1_back, std::string::npos);
155 const auto s2_back = s2.substr(pos_wc + 1, std::string::npos);
163inline auto Levenstein(std::string_view a, std::string_view b) {
166 std::vector<size_t> d_t((a.size() + 1) * (b.size() + 1),
size_t(-1));
167 auto d = [&](
size_t ia,
size_t ib) ->
size_t & {
168 return d_t[ia * (b.size() + 1) + ib];
170 std::function<size_t(
size_t,
size_t)> LevensteinInt =
171 [&](
size_t ia,
size_t ib) ->
size_t {
172 if (d(ia, ib) != size_t(-1))
176 dist = a.size() - ia;
177 else if (ia >= a.size())
178 dist = b.size() - ib;
179 else if (a[ia] == b[ib])
180 dist = LevensteinInt(ia + 1, ib + 1);
182 dist = 1 + std::min(std::min(LevensteinInt(ia, ib + 1),
183 LevensteinInt(ia + 1, ib)),
184 LevensteinInt(ia + 1, ib + 1));
188 return LevensteinInt(0, 0);
194 std::vector<size_t> d_t((a.size() + 1) * (b.size() + 1),
size_t(-1));
195 auto d = [&](
size_t ia,
size_t ib) ->
size_t & {
196 return d_t[ia * (b.size() + 1) + ib];
198 std::function<size_t(
size_t,
size_t)> LevensteinInt =
199 [&](
size_t ia,
size_t ib) ->
size_t {
200 if (d(ia, ib) != size_t(-1))
204 dist = a.size() - ia;
205 else if (ia >= a.size())
206 dist = b.size() - ib;
208 dist = LevensteinInt(ia + 1, ib + 1);
210 dist = 1 + std::min(std::min(LevensteinInt(ia, ib + 1),
211 LevensteinInt(ia + 1, ib)),
212 LevensteinInt(ia + 1, ib + 1));
216 return LevensteinInt(0, 0);
221 const std::vector<std::string> &list) {
222 auto compare = [&test_string](
const auto &s1,
const auto &s2) {
225 return std::min_element(list.cbegin(), list.cend(),
compare);
231 const std::vector<std::string> &list) {
232 auto compare = [&test_string](
const auto &s1,
const auto &s2) {
236 return std::min_element(list.cbegin(), list.cend(),
compare);
248 std::find_if(s.cbegin() + 1, s.cend(),
249 [](
auto c) { return !std::isdigit(c); }) == s.end() &&
251 (std::isdigit(s[0]) || ((s[0] ==
'-' || s[0] ==
'+') && s.size() > 1));
256inline std::vector<std::string>
split(
const std::string &s,
char delim =
' ') {
257 std::vector<std::string> out;
258 std::stringstream ss(s);
260 while (getline(ss, tmp, delim)) {
267inline std::string
concat(
const std::vector<std::string> &v,
268 const std::string &delim =
"") {
270 for (std::size_t i = 0; i < v.size(); ++i) {
272 if (i != v.size() - 1)
281inline std::string
wrap(
const std::string &input, std::size_t at = 80,
282 const std::string &prefix =
"") {
284 const auto length = at - prefix.size();
285 std::size_t ipos = 0;
286 std::size_t fpos = length;
287 while (ipos < input.length()) {
291 auto temp_pos_nl = input.find(
'\n', ipos);
292 if (temp_pos_nl > ipos && temp_pos_nl < fpos &&
293 temp_pos_nl != std::string::npos) {
294 output += prefix + input.substr(ipos, temp_pos_nl - ipos);
295 ipos = temp_pos_nl + 1;
296 fpos = ipos + length;
300 if (fpos >= input.length()) {
301 output += prefix + input.substr(ipos, fpos - ipos);
305 auto temp_pos = input.rfind(
' ', fpos);
306 if (temp_pos <= ipos || temp_pos == std::string::npos) {
307 output += prefix + input.substr(ipos, fpos - ipos);
309 fpos = ipos + length;
311 output += prefix + input.substr(ipos, temp_pos - ipos);
313 fpos = ipos + length;
325 return std::to_string(a);
326 static const std::string M[] = {
"",
"M",
"MM",
"MMM"};
327 static const std::string C[] = {
"",
"C",
"CC",
"CCC",
"CD",
328 "D",
"DC",
"DCC",
"DCCC",
"CM"};
329 static const std::string X[] = {
"",
"X",
"XX",
"XXX",
"XL",
330 "L",
"LX",
"LXX",
"LXXX",
"XC"};
331 static const std::string I[] = {
"",
"I",
"II",
"III",
"IV",
332 "V",
"VI",
"VII",
"VIII",
"IX"};
333 return M[a / 1000] + C[(a % 1000) / 100] + X[(a % 100) / 10] + I[(a % 10)];
qip library: A collection of useful functions
Definition Array.hpp:9
auto closest_match(std::string_view test_string, const std::vector< std::string > &list)
Finds the closest match in list to test_string (return iterator)
Definition String.hpp:220
std::string concat(const std::vector< std::string > &v, const std::string &delim="")
Takes vector of strings, concats into single string, with optional delimeter.
Definition String.hpp:267
auto Levenstein(std::string_view a, std::string_view b)
A simple non-optimised implementation of the Levenshtein distance.
Definition String.hpp:163
bool string_is_integer(std::string_view s)
Checks if a string-like s is integer-like (including -)
Definition String.hpp:245
std::vector< std::string > split(const std::string &s, char delim=' ')
Splits a string by delimeter into a vector.
Definition String.hpp:256
bool ci_contains(const std::string &the_string, const std::string &sub_string)
Checks if the_string (arg1) constaints sub_string (arg2), case insensitive.
Definition String.hpp:104
auto ci_Levenstein(std::string_view a, std::string_view b)
A simple non-optimised implementation of the Levenshtein distance (case insensitive)
Definition String.hpp:193
bool ci_wc_compare(std::string_view s1, std::string_view s2)
Compares two strings, s1 and s2. s2 may contain ONE wildcard ('*') which will match anything....
Definition String.hpp:139
std::string int_to_roman(int a)
Converts integer, a, to Roman Numerals. Assumed that |a|<=4000.
Definition String.hpp:321
std::string fstring(const std::string format,...)
Returns a formatted std::string, with formatting printf-like commands. Note: maximum string lenth is ...
Definition String.hpp:18
bool ci_compare(std::string_view s1, std::string_view s2)
Case insensitive string compare. Essentially: LowerCase(s1)==LowerCase(s2)
Definition String.hpp:131
bool wildcard_compare(std::string_view s1, std::string_view s2)
Compares two strings, s1 and s2. s2 may contain ONE wildcard ('*') which will match anything.
Definition String.hpp:62
bool contains(std::string_view the_string, std::string_view sub_string)
Checks if the_string (arg1) constaints sub_string (arg2)
Definition String.hpp:99
auto compare(const std::vector< T > &first, const std::vector< T > &second)
Directly compare two arithmetic vectors of the same type and length. Returns pair {delta,...
Definition Vector.hpp:33
auto ci_closest_match(std::string_view test_string, const std::vector< std::string > &list)
Finds the closest match (case insensitive) in list to test_string (return iterator)
Definition String.hpp:230
std::string wrap(const std::string &input, std::size_t at=80, const std::string &prefix="")
Wraps the string, 'input', at line 'at'. Optionally appends a prefix 'prefix' to each line....
Definition String.hpp:281
char tolower(char ch)
return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
Definition String.hpp:85