| /* |
| * Copyright (C) 2004-2023 Savoir-faire Linux Inc. |
| * |
| * This program is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation, either version 3 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program. If not, see <https://www.gnu.org/licenses/>. |
| */ |
| #pragma once |
| |
| #include <cstdint> |
| #include <string> |
| #include <vector> |
| #include <set> |
| #include <algorithm> |
| #include <regex> |
| #include <iterator> |
| #include <charconv> |
| |
| #ifdef _WIN32 |
| #include <WTypes.h> |
| #endif |
| |
| namespace dhtnet { |
| |
| constexpr static const char TRUE_STR[] = "true"; |
| constexpr static const char FALSE_STR[] = "false"; |
| |
| constexpr static const char* |
| bool_to_str(bool b) noexcept |
| { |
| return b ? TRUE_STR : FALSE_STR; |
| } |
| |
| std::string to_string(double value); |
| |
| #ifdef _WIN32 |
| std::wstring to_wstring(const std::string& str, int codePage = CP_UTF8); |
| std::string to_string(const std::wstring& wstr, int codePage = CP_UTF8); |
| #endif |
| |
| std::string to_hex_string(uint64_t id); |
| uint64_t from_hex_string(const std::string& str); |
| |
| template<typename T> |
| T |
| to_int(std::string_view str, T defaultValue) |
| { |
| T result; |
| auto [p, ec] = std::from_chars(str.data(), str.data()+str.size(), result); |
| if (ec == std::errc()) |
| return result; |
| else |
| return defaultValue; |
| } |
| |
| template<typename T> |
| T |
| to_int(std::string_view str) |
| { |
| T result; |
| auto [p, ec] = std::from_chars(str.data(), str.data()+str.size(), result); |
| if (ec == std::errc()) |
| return result; |
| if (ec == std::errc::invalid_argument) |
| throw std::invalid_argument("Can't parse integer: invalid_argument"); |
| else if (ec == std::errc::result_out_of_range) |
| throw std::out_of_range("Can't parse integer: out of range"); |
| throw std::system_error(std::make_error_code(ec)); |
| } |
| |
| static inline int |
| stoi(const std::string& str) |
| { |
| return std::stoi(str); |
| } |
| |
| static inline double |
| stod(const std::string& str) |
| { |
| return std::stod(str); |
| } |
| |
| template<typename... Args> |
| std::string concat(Args &&... args){ |
| static_assert((std::is_constructible_v<std::string_view, Args&&> && ...)); |
| std::string s; |
| s.reserve((std::string_view{ args }.size() + ...)); |
| (s.append(std::forward<Args>(args)), ...); |
| return s; |
| } |
| |
| std::string_view trim(std::string_view s); |
| |
| /** |
| * Split a string_view with an API similar to std::getline. |
| * @param str The input string stream to iterate on, trimed of line during iteration. |
| * @param line The output substring. |
| * @param delim The delimiter. |
| * @return True if line was set, false if the end of the input was reached. |
| */ |
| inline bool |
| getline_full(std::string_view& str, std::string_view& line, char delim = '\n') |
| { |
| if (str.empty()) |
| return false; |
| auto pos = str.find(delim); |
| line = str.substr(0, pos); |
| str.remove_prefix(pos < str.size() ? pos + 1 : str.size()); |
| return true; |
| } |
| |
| /** |
| * Similar to @getline_full but skips empty results. |
| */ |
| inline bool |
| getline(std::string_view& str, std::string_view& line, char delim = '\n') |
| { |
| do { |
| if (!getline_full(str, line, delim)) |
| return false; |
| } while (line.empty()); |
| return true; |
| } |
| |
| inline std::vector<std::string_view> |
| split_string(std::string_view str, char delim) |
| { |
| std::vector<std::string_view> output; |
| for (auto first = str.data(), second = str.data(), last = first + str.size(); |
| second != last && first != last; |
| first = second + 1) { |
| second = std::find(first, last, delim); |
| if (first != second) |
| output.emplace_back(first, second - first); |
| } |
| return output; |
| } |
| |
| inline std::vector<std::string_view> |
| split_string(std::string_view str, std::string_view delims = " ") |
| { |
| std::vector<std::string_view> output; |
| for (auto first = str.data(), second = str.data(), last = first + str.size(); |
| second != last && first != last; |
| first = second + 1) { |
| second = std::find_first_of(first, last, std::cbegin(delims), std::cend(delims)); |
| if (first != second) |
| output.emplace_back(first, second - first); |
| } |
| return output; |
| } |
| |
| std::vector<unsigned> split_string_to_unsigned(std::string_view s, char sep); |
| |
| void string_replace(std::string& str, const std::string& from, const std::string& to); |
| |
| } // namespace dhtnet |