33 #ifndef SIMPLE_ALGORITHMS_H_INCLUDED 34 #define SIMPLE_ALGORITHMS_H_INCLUDED 54 #if __has_cpp_attribute(fallthrough) 55 #define fallthrough fallthrough 56 #elif __has_cpp_attribute(clang::fallthrough) 57 #define fallthrough clang::fallthrough 58 #elif __has_cpp_attribute(gnu::fallthrough) 59 #define fallthrough gnu::fallthrough 61 #define fallthrough fallthrough 64 #if __has_cpp_attribute(maybe_unused) 65 #define maybe_unused maybe_unused 66 #elif __has_cpp_attribute(gnu::unused) 67 #define maybe_unused gnu::unused 68 #else // Just let the compiler show the warning 69 #define maybe_unused maybe_unused 77 inline T fromStr(
const std::string& val) {
78 std::stringstream ss(val);
80 if (!(ss >> ret).fail())
83 throw std::runtime_error(
"\"" + val +
"\" is not a " +
typeid(T).name());
86 inline std::string fromStr(
const std::string& val) {
91 inline T fromStr(
const std::string& val,
const char* type) {
92 std::stringstream ss(val);
94 if (!(ss >> ret).fail())
97 throw std::runtime_error(
"\"" + val +
"\" is not a " + type);
100 inline std::string fromStr(
const std::string& val,
101 [[maybe_unused]]
const char* type) {
104 #define pFromStr(type, val) fromStr<type>((val), #type) 106 template <
typename T>
107 inline std::string toStr(T val) {
108 std::stringstream ss;
115 #include <unicode/unistr.h> 117 template <
typename string = std::
string>
118 inline string toUTF8(
const icu::UnicodeString& s) {
120 return s.toUTF8String(res);
123 template <
typename string>
124 inline icu::UnicodeString fromUTF8(
string s) {
125 return icu::UnicodeString::fromUTF8(s);
128 template <
typename string = std::u32
string>
129 inline string toUTF32(
const icu::UnicodeString& s) {
130 string res(s.countChar32(),
'\0');
131 UErrorCode ec{U_ZERO_ERROR};
132 s.toUTF32(reinterpret_cast<UChar32*>(&res[0]), res.size(), ec);
139 template <
typename string>
140 inline icu::UnicodeString fromUTF32(
string s) {
141 return icu::UnicodeString::fromUTF32(s.data(), s.length());
144 inline std::ostream& operator<<(std::ostream& os,
145 const icu::UnicodeString& str) {
146 return os << toUTF8(str);
150 inline std::string operator+(std::string lhs,
const icu::UnicodeString& str) {
151 return str.toUTF8String(lhs);
157 std::string d_toUTF8(
const icu::UnicodeString& s);
158 icu::UnicodeString d_fromUTF8(std::string s);
160 template <
typename T>
161 inline T fromStr(
const icu::UnicodeString& val,
const char* type) {
162 return fromStr<T>(toUTF8(val), type);
165 template <
typename T>
166 inline T fromStr(
const icu::UnicodeString& val) {
167 return fromStr<T>(toUTF8(val));
173 template <
typename string,
typename vector>
174 inline string join(
const vector& in,
const string& joiner = {}) {
175 if (in.size() == 0) {
177 }
else if (in.size() == 1) {
180 return std::accumulate(
181 std::next(std::begin(in)), std::end(in), *in.begin(),
182 [&joiner](
const string& a,
const string& b) ->
string {
183 return a + joiner + b;
188 template <
typename string>
189 inline string reverseStr(
string val) {
190 std::reverse(val.begin(), val.end());
194 template <
typename string>
195 inline string toLower(
string str) {
196 std::transform(str.begin(), str.end(), str.begin(), ::tolower);
200 template <
typename string>
201 inline string toUpper(
string str) {
202 std::transform(str.begin(), str.end(), str.begin(), ::toupper);
209 template <
typename T>
210 inline std::vector<T> listToVec(std::string list) {
212 std::stringstream ss(list);
214 while (!(ss >> tmp).fail()) {
215 ret.push_back(fromStr<T>(tmp));
231 template <
typename string>
232 inline string repeat(
string val,
int count) {
234 for (
int i = 0; i < count; ++i) {
240 inline std::string repeat(
char val,
int count) {
241 return std::string(count, val);
247 template <
typename Container,
typename InputIt,
typename UnaryFunction>
248 inline Container build(InputIt first, InputIt last, UnaryFunction f) {
250 std::transform(first, last, std::back_inserter(out), f);
254 template <
typename Container,
typename InputIt,
typename InputIt2,
255 typename BinaryFunction>
256 inline Container build(InputIt first, InputIt last, InputIt2 first2,
259 std::transform(first, last, first2, std::back_inserter(out), f);
263 template <
typename Container,
typename ExecutionPolicy,
typename InputIt,
264 typename UnaryFunction>
265 inline Container build(ExecutionPolicy&& policy, InputIt first, InputIt last,
268 std::transform(policy, first, last, std::back_inserter(out), f);
272 template <
typename Container,
typename ExecutionPolicy,
typename InputIt,
273 typename InputIt2,
typename BinaryFunction>
274 inline Container build(ExecutionPolicy&& policy, InputIt first, InputIt last,
275 InputIt2 first2, BinaryFunction f) {
277 std::transform(policy, first, last, first2, std::back_inserter(out), f);
282 template <
typename Number>
283 constexpr
inline int digitsOf(Number val) {
284 return std::ceil(std::log10(val));
287 template <
typename Number>
288 constexpr
inline int digitsOf(Number val,
int base) {
289 return std::ceil(std::log(val) / std::log(base));
292 template <
typename ForwardIterator>
293 inline int digitsList(ForwardIterator first, ForwardIterator last) {
294 return digitsOf(*std::max_element(first, last));
297 template <
typename ForwardIterator>
298 inline int digitsList(ForwardIterator first, ForwardIterator last,
int base) {
299 return digitsOf(*std::max_element(first, last), base);
304 template <
typename ostream_type,
typename ForwardIterator>
305 inline ostream_type& padList(ostream_type& os, ForwardIterator first,
306 ForwardIterator last,
char fill =
' ',
312 char fills = os.fill();
313 std::streamsize widths = os.width();
315 os << std::setw(digitsList(first, last, base)) << std::setfill(fill);
317 for (ForwardIterator it = first; it != last; ++it) {
321 os << std::setw(widths) << std::setfill(fills);
326 inline std::istream& eatWord(std::istream& is) {
329 }
while (!isspace(is.peek()));
334 inline std::istream& eatSpace(std::istream& is) {
335 while (isspace(is.peek()))
340 inline std::string url_encode(
const std::string& value) {
341 std::ostringstream escaped;
345 for (std::string::const_iterator i = value.begin(), n = value.end(); i != n;
347 std::string::value_type c = (*i);
350 if (isalnum(c) || c ==
'-' || c ==
'_' || c ==
'.' || c ==
'~') {
356 escaped << std::uppercase;
357 escaped <<
'%' << std::setw(2) << int((
unsigned char)c);
358 escaped << std::nouppercase;
361 return escaped.str();
364 template <
typename string>
365 inline std::string get_file_contents(
string filename) {
367 in.exceptions(std::ios::badbit);
368 in.open(filename, std::ios::in | std::ios::binary);
369 std::string contents;
370 std::array<char, 128> buf;
372 in.read(buf.begin(), buf.size());
373 contents.append(buf.begin(), in.gcount());
378 template <
typename T,
typename F>
379 inline constexpr T quantizeRange(F min, F delta, F val) {
380 return static_cast<T
>((val - min) * std::numeric_limits<T>::max() * delta);
385 template <
typename T>
388 template <
typename T>
389 using PtrToConst = T
const*;
391 template <
typename T>
392 using ConstPtr = T*
const;
394 template <
typename T>
395 using ConstPtrToConst = T
const*
const;
397 #endif // SIMPLE_ALGORITHMS_H_INCLUDED