#pragma once #include #include #include #include namespace WebStat { template struct DeleteWith { auto operator()(auto obj) { return Deleter(obj); } }; template auto visit(auto && visitor, const std::tuple & values) { std::apply( [&](auto &&... value) { (visitor(value), ...); }, values); } using FilePtr = std::unique_ptr>; template void bindMany(const DB::CommandPtr & cmd, unsigned int firstParam, T &&... param) { (cmd->bindParam(firstParam++, std::forward(param)), ...); } namespace detail { template void add(std::chrono::duration & subtotal, Rep value) { if constexpr (requires { subtotal += AddPeriod {value}; }) { subtotal += AddPeriod {value}; } } } template std::chrono::duration parseDuration(std::string_view input) { static constexpr std::initializer_list< std::pair & subtotal, Rep value), std::string_view>> DURATION_UNITS { {detail::add, "ms"}, {detail::add, "s"}, {detail::add, "m"}, {detail::add, "h"}, {detail::add, "d"}, {detail::add, "w"}, }; std::chrono::duration out {}; auto inputSubRange = scn::ranges::subrange {input}; while (auto result = scn::scan(inputSubRange, "{}{:[a-z]}")) { const auto & [count, chars] = result->values(); if (auto unit = std::ranges::find( DURATION_UNITS, chars, &std::decay_t::second); unit != DURATION_UNITS.end()) { unit->first(out, count); } inputSubRange = result->range(); } return out; } }