2#include "fmt/color.hpp"
19inline std::string
fstring(
const std::string format, ...) {
20 constexpr std::size_t size = 256;
22 fmt_str.resize(size + 1);
28 va_start(args, format);
29 vsnprintf(&fmt_str[0], fmt_str.size(), format.c_str(), args);
33 fmt_str.erase(std::find(fmt_str.begin(), fmt_str.end(),
'\0'), fmt_str.end());
39inline std::string
fstring(
const std::size_t size,
const std::string format,
44 fmt_str.resize(size + 1);
50 va_start(args, format);
51 vsnprintf(&fmt_str[0], fmt_str.size(), format.c_str(), args);
55 fmt_str.erase(std::find(fmt_str.begin(), fmt_str.end(),
'\0'), fmt_str.end());
65 const auto wc = std::find(s2.cbegin(), s2.cend(),
'*');
69 const auto pos_wc = std::size_t(std::distance(s2.cbegin(), wc));
71 const auto s1_front = s1.substr(0, pos_wc);
72 const auto s2_front = s2.substr(0, pos_wc);
75 const auto len_back = std::size_t(std::distance(wc + 1, s2.cend()));
77 const auto pos_1_back = s1.length() > len_back ? s1.length() - len_back : 0;
78 const auto s1_back = s1.substr(pos_1_back, std::string::npos);
79 const auto s2_back = s2.substr(pos_wc + 1, std::string::npos);
81 return s1_front == s2_front && s1_back == s2_back;
88 return static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
91inline std::string
tolower(std::string t_string) {
92 for (
auto &c : t_string) {
100inline bool contains(std::string_view the_string, std::string_view sub_string) {
101 return the_string.find(sub_string) != std::string::npos;
106 const std::string &sub_string) {
107 return tolower(the_string).find(
tolower(sub_string)) != std::string::npos;
112 const std::vector<std::string> &sub_strings) {
113 for (
const auto &substr : sub_strings) {
122 const std::vector<std::string> &sub_strings) {
123 for (
const auto &substr : sub_strings) {
132inline bool ci_compare(std::string_view s1, std::string_view s2) {
134 s1.cbegin(), s1.cend(), s2.cbegin(), s2.cend(),
135 [](
char c1,
char c2) { return qip::tolower(c1) == qip::tolower(c2); });
142 const auto wc = std::find(s2.cbegin(), s2.cend(),
'*');
146 const auto pos_wc = std::size_t(std::distance(s2.cbegin(), wc));
148 const auto s1_front = s1.substr(0, pos_wc);
149 const auto s2_front = s2.substr(0, pos_wc);
152 const auto len_back = std::size_t(std::distance(wc + 1, s2.cend()));
154 const auto pos_1_back = s1.length() > len_back ? s1.length() - len_back : 0;
155 const auto s1_back = s1.substr(pos_1_back, std::string::npos);
156 const auto s2_back = s2.substr(pos_wc + 1, std::string::npos);
164inline auto Levenstein(std::string_view a, std::string_view b) {
167 std::vector<size_t> d_t((a.size() + 1) * (b.size() + 1),
size_t(-1));
168 auto d = [&](
size_t ia,
size_t ib) ->
size_t & {
169 return d_t[ia * (b.size() + 1) + ib];
171 std::function<size_t(
size_t,
size_t)> LevensteinInt =
172 [&](
size_t ia,
size_t ib) ->
size_t {
173 if (d(ia, ib) != size_t(-1))
177 dist = a.size() - ia;
178 else if (ia >= a.size())
179 dist = b.size() - ib;
180 else if (a[ia] == b[ib])
181 dist = LevensteinInt(ia + 1, ib + 1);
183 dist = 1 + std::min(std::min(LevensteinInt(ia, ib + 1),
184 LevensteinInt(ia + 1, ib)),
185 LevensteinInt(ia + 1, ib + 1));
189 return LevensteinInt(0, 0);
195 std::vector<size_t> d_t((a.size() + 1) * (b.size() + 1),
size_t(-1));
196 auto d = [&](
size_t ia,
size_t ib) ->
size_t & {
197 return d_t[ia * (b.size() + 1) + ib];
199 std::function<size_t(
size_t,
size_t)> LevensteinInt =
200 [&](
size_t ia,
size_t ib) ->
size_t {
201 if (d(ia, ib) != size_t(-1))
205 dist = a.size() - ia;
206 else if (ia >= a.size())
207 dist = b.size() - ib;
209 dist = LevensteinInt(ia + 1, ib + 1);
211 dist = 1 + std::min(std::min(LevensteinInt(ia, ib + 1),
212 LevensteinInt(ia + 1, ib)),
213 LevensteinInt(ia + 1, ib + 1));
217 return LevensteinInt(0, 0);
222 const std::vector<std::string> &list) {
223 auto compare = [&test_string](
const auto &s1,
const auto &s2) {
226 return std::min_element(list.cbegin(), list.cend(),
compare);
232 const std::vector<std::string> &list) {
233 auto compare = [&test_string](
const auto &s1,
const auto &s2) {
237 using namespace std::string_literals;
238 return list.empty() ?
""s :
239 *std::min_element(list.cbegin(), list.cend(),
compare);
251 std::find_if(s.cbegin() + 1, s.cend(),
252 [](
auto c) { return !std::isdigit(c); }) == s.end() &&
254 (std::isdigit(s[0]) || ((s[0] ==
'-' || s[0] ==
'+') && s.size() > 1));
259inline std::vector<std::string>
split(
const std::string &s,
char delim =
' ') {
260 std::vector<std::string> out;
261 std::stringstream ss(s);
263 while (getline(ss, tmp, delim)) {
270inline std::string
concat(
const std::vector<std::string> &v,
271 const std::string &delim =
"") {
273 for (std::size_t i = 0; i < v.size(); ++i) {
275 if (i != v.size() - 1)
284inline std::string
wrap(
const std::string &input, std::size_t at = 80,
285 const std::string &prefix =
"") {
287 const auto length = at - prefix.size();
288 std::size_t ipos = 0;
289 std::size_t fpos = length;
290 while (ipos < input.length()) {
294 auto temp_pos_nl = input.find(
'\n', ipos);
295 if (temp_pos_nl > ipos && temp_pos_nl < fpos &&
296 temp_pos_nl != std::string::npos) {
297 output += prefix + input.substr(ipos, temp_pos_nl - ipos);
298 ipos = temp_pos_nl + 1;
299 fpos = ipos + length;
303 if (fpos >= input.length()) {
304 output += prefix + input.substr(ipos, fpos - ipos);
308 auto temp_pos = input.rfind(
' ', fpos);
309 if (temp_pos <= ipos || temp_pos == std::string::npos) {
310 output += prefix + input.substr(ipos, fpos - ipos);
312 fpos = ipos + length;
314 output += prefix + input.substr(ipos, temp_pos - ipos);
316 fpos = ipos + length;
328 return std::to_string(a);
329 static const std::string M[] = {
"",
"M",
"MM",
"MMM"};
330 static const std::string C[] = {
"",
"C",
"CC",
"CCC",
"CD",
331 "D",
"DC",
"DCC",
"DCCC",
"CM"};
332 static const std::string X[] = {
"",
"X",
"XX",
"XXX",
"XL",
333 "L",
"LX",
"LXX",
"LXXX",
"XC"};
334 static const std::string I[] = {
"",
"I",
"II",
"III",
"IV",
335 "V",
"VI",
"VII",
"VIII",
"IX"};
336 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:221
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:270
auto Levenstein(std::string_view a, std::string_view b)
A simple non-optimised implementation of the Levenshtein distance.
Definition String.hpp:164
std::string ci_closest_match(const 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:231
bool string_is_integer(std::string_view s)
Checks if a string-like s is integer-like (including -)
Definition String.hpp:248
std::vector< std::string > split(const std::string &s, char delim=' ')
Splits a string by delimeter into a vector.
Definition String.hpp:259
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:105
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:194
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:140
std::string int_to_roman(int a)
Converts integer, a, to Roman Numerals. Assumed that |a|<=4000.
Definition String.hpp:324
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:19
bool ci_compare(std::string_view s1, std::string_view s2)
Case insensitive string compare. Essentially: LowerCase(s1)==LowerCase(s2)
Definition String.hpp:132
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:63
bool contains(std::string_view the_string, std::string_view sub_string)
Checks if the_string (arg1) constaints sub_string (arg2)
Definition String.hpp:100
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
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:284
char tolower(char ch)
return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
Definition String.hpp:86