#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/flyweight/no_tracking.hpp> #include <boost/circular_buffer.hpp> #include "fmt/core.h" #include "utf8.hpp" #include "utf8string.hpp" namespace util { using String = boost::flyweights::flyweight<std::string,boost::flyweights::no_tracking>; constexpr float float2longScale = 10000; 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(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(); long float2long(float f); float long2float(long l); std::vector<std::vector<std::string>> readTSV(std::string_view tsvFilename); template <typename T> std::size_t getSize(const std::vector<T> & s) { return s.size(); } template <typename T> std::size_t getSize(const boost::flyweights::flyweight<T> & s) { return getSize(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 lowerInPlace(utf8string & s); utf8string lower(const utf8string & s); utf8char lower(const utf8char & c); void lowerInPlace(utf8char & c); std::string upper(const std::string & s); void upper(utf8string & s); utf8string upper(const utf8string & s); void upper(utf8char & c); std::vector<utf8string> readFileAsUtf8(std::string_view filename, bool lineByLine); 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::flyweights::flyweight<T>> //{ // constexpr auto parse(format_parse_context & ctx) { return ctx.begin(); } // // template <typename FormatContext> // auto format(const boost::flyweights::flyweight<T> & s, FormatContext & ctx) // { // return format_to(ctx.out(), "{}", s.get()); // } //}; #endif