20#include <spdlog/sinks/stdout_color_sinks.h>
21#include <spdlog/spdlog.h>
32#define LOG_ERROR(fmt__, ...) \
33 spdlog::get("clanguml-logger") \
34 ->error(fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, \
35 __LINE__, ##__VA_ARGS__)
37#define LOG_WARN(fmt__, ...) \
38 spdlog::get("clanguml-logger") \
39 ->warn(fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, \
40 __LINE__, ##__VA_ARGS__)
42#define LOG_INFO(fmt__, ...) \
43 spdlog::get("clanguml-logger") \
44 ->info(fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, \
45 __LINE__, ##__VA_ARGS__)
47#define LOG_DBG(fmt__, ...) \
48 spdlog::get("clanguml-logger") \
49 ->debug(fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, \
50 __LINE__, ##__VA_ARGS__)
52#define LOG_TRACE(fmt__, ...) \
53 spdlog::get("clanguml-logger") \
54 ->trace(fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, \
55 __LINE__, ##__VA_ARGS__)
60 (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
70std::string
ltrim(
const std::string &s);
78std::string
rtrim(
const std::string &s);
86std::string
trim(
const std::string &s);
116std::string
get_env(
const std::string &name);
165template <
typename T,
typename S>
168 if (T *
const converted =
dynamic_cast<T *
>(p.get())) {
169 std::move(p).release();
170 return std::unique_ptr<T>{converted};
189std::vector<std::string>
split(
190 std::string str, std::string_view delimiter,
bool skip_empty =
true);
202template <
typename T,
typename F>
void erase_if(std::vector<T> &v, F &&f)
204 v.erase(std::remove_if(v.begin(), v.end(), std::forward<F>(f)), v.end());
215 const std::vector<std::string> &toks, std::string_view delimiter);
225template <
typename... Args>
226std::string
join(std::string_view delimiter, Args... args)
228 std::vector<std::string> coll{args...};
231 return s.find_first_not_of(
" \t") == std::string::npos;
234 return fmt::format(
"{}", fmt::join(coll, delimiter));
245std::string
abbreviate(
const std::string &s,
unsigned int max_length);
258 const std::string &input, std::tuple<std::string, size_t, size_t> &result);
267bool replace_all(std::string &input,
const std::string &pattern,
268 const std::string &replace_with);
277template <
typename T>
void append(std::vector<T> &l,
const std::vector<T> &r)
279 l.insert(l.end(), r.begin(), r.end());
290template <
typename T>
bool starts_with(
const T &col,
const T &prefix)
292 if (prefix.size() > col.size())
295 return std::search(col.begin(), col.end(), prefix.begin(), prefix.end()) ==
301 const std::filesystem::path &path,
const std::filesystem::path &prefix);
303template <>
bool starts_with(
const std::string &s,
const std::string &prefix);
305template <
typename T>
bool ends_with(
const T &value,
const T &suffix);
307template <>
bool ends_with(
const std::string &value,
const std::string &suffix);
310bool ends_with(
const std::vector<T> &col,
const std::vector<T> &suffix)
312 if (suffix.size() > col.size())
315 return std::vector<std::string>(suffix.rbegin(), suffix.rend()) ==
316 std::vector<std::string>(col.rbegin(), col.rbegin() + suffix.size());
332 col = std::vector<T>(col.begin() + prefix.size(), col.end());
344template <
typename T,
typename E>
347 if constexpr (std::is_pointer_v<E>) {
348 return std::find_if(container.begin(), container.end(),
349 [&element](
const auto &e) { return *e == *element; }) !=
352 else if constexpr (std::is_same_v<std::remove_cv_t<T>, std::string>) {
353 return container.find(element) != std::string::npos;
356 return std::find(container.begin(), container.end(), element) !=
361template <
typename T,
typename F>
void for_each(
const T &collection, F &&func)
363 std::for_each(std::begin(collection), std::end(collection),
364 std::forward<
decltype(func)>(func));
367template <
typename T,
typename C,
typename F>
370 std::for_each(std::begin(collection), std::end(collection),
371 [cond = std::forward<
decltype(cond)>(cond),
372 func = std::forward<
decltype(func)>(func)](
const auto &e) {
378template <
typename R,
typename T,
typename F>
379std::vector<R>
map(
const std::vector<T> &in, F &&f)
383 in.cbegin(), in.cend(), std::back_inserter(out), std::forward<F>(f));
387template <
typename T,
typename F,
typename FElse>
390 if (pointer !=
nullptr) {
391 std::forward<F>(func)(pointer);
394 std::forward<FElse>(func_else)();
398template <
typename T,
typename F>
void if_not_null(
const T *pointer, F &&func)
400 if_not_null(pointer, std::forward<F>(func), []() {});
403template <
typename F,
typename FElse>
404void _if(
const bool condition, F &&func, FElse &&func_else)
407 std::forward<F>(func)();
410 std::forward<FElse>(func_else)();
414template <
typename F>
void _if(
const bool condition, F &&func)
416 _if(condition, std::forward<F>(func), []() {});
436std::string
path_to_url(
const std::filesystem::path &p);
449 const std::filesystem::path &root = std::filesystem::current_path());
460 const std::filesystem::path &parent,
const std::filesystem::path &child);
466 const std::filesystem::path &path,
const std::filesystem::path &prefix);
469 const std::map<std::string, std::string> &m,
const std::string &prefix);