#ifndef UTIL__H #define UTIL__H #include <string> #include <vector> #include <array> #include <unordered_map> #include <regex> #include <filesystem> #include <experimental/source_location> #include <boost/flyweight.hpp> #include <boost/circular_buffer.hpp> #include "fmt/core.h" #include "utf8.hpp" #include "utf8string.hpp" namespace util { void warning(std::string_view message, const std::experimental::source_location & location = std::experimental::source_location::current()); void error(std::string_view message, const std::experimental::source_location & location = std::experimental::source_location::current()); void error(const std::exception & e, const std::experimental::source_location & location = std::experimental::source_location::current()); void myThrow(std::string_view message, const std::experimental::source_location & location = std::experimental::source_location::current()); std::vector<std::filesystem::path> findFilesByExtension(std::filesystem::path directory, std::string extension); std::string_view getFilenameFromPath(std::string_view s); std::vector<std::string> split(std::string_view s, char delimiter); utf8string splitAsUtf8(std::string_view s); std::string int2HumanStr(int number); std::string shrink(const std::string & s, int printedSize); std::string strip(const std::string & s); int printedLength(std::string_view s); bool isSeparator(utf8char c); bool isIllegal(utf8char c); bool isUppercase(utf8char c); bool isUrl(const std::string & s); bool isNumber(const std::string & s); std::string getTime(); template <typename T> bool isEmpty(const std::vector<T> & s) { return s.empty(); } template <typename T> bool isEmpty(const std::basic_string<T> & s) { return s.empty(); } template <typename T> std::size_t getSize(const std::vector<T> & s) { return s.size(); } template <typename T> std::size_t getSize(const boost::flyweight<T> & s) { return getSize(s.get()); } template <typename T> bool isEmpty(const boost::flyweight<T> & s) { return isEmpty(s.get()); } bool doIfNameMatch(const std::regex & reg, std::string_view name, const std::function<void(const std::smatch &)> & f); bool choiceWithProbability(float probability); std::string lower(const std::string & s); void lower(utf8string & s); utf8string lower(const utf8string & s); void lower(utf8char & c); std::string upper(const std::string & s); void upper(utf8string & s); utf8string upper(const utf8string & s); void upper(utf8char & c); template <typename T> std::string join(const std::string & delim, const std::vector<T> elems) { std::string result; for (unsigned int i = 0; i < elems.size(); i++) result = fmt::format("{}{}{}", result, elems[i], i == elems.size()-1 ? "" : delim); return result; } template <typename T> std::string join(const std::string & delim, const boost::circular_buffer<T> elems) { std::string result; for (unsigned int i = 0; i < elems.size(); i++) result = fmt::format("{}{}{}", result, elems[i], i == elems.size()-1 ? "" : delim); return result; } template <typename K, typename V> std::map<V, K> inverseMap(const std::map<K, V> & model) { std::map<V, K> res; for (auto & it : model) res[it.second] = it.first; return res; } }; template <> struct fmt::formatter<std::experimental::source_location> { constexpr auto parse(format_parse_context & ctx) { return ctx.begin(); } template <typename FormatContext> auto format(const std::experimental::source_location & d, FormatContext & ctx) { return format_to(ctx.out(), "{},l.{},'{}'", util::getFilenameFromPath(d.file_name()), d.line(), d.function_name()); } }; template <typename T> struct fmt::formatter<boost::flyweight<T>> { constexpr auto parse(format_parse_context & ctx) { return ctx.begin(); } template <typename FormatContext> auto format(const boost::flyweight<T> & s, FormatContext & ctx) { return format_to(ctx.out(), "{}", s.get()); } }; #endif