#ifndef ALSK_ALSK_UTILITY_H #define ALSK_ALSK_UTILITY_H #include #include #include #include namespace alsk { /** * @brief Tuple printer of ::size() */ namespace impl { template struct TupleElementImpl; template struct TupleElementImpl, std::enable_if_t<(I < sizeof...(Ts))>> { using type = typename std::tuple_element>::type; }; template struct TupleElementImpl, std::enable_if_t<(I >= sizeof...(Ts))>> { using type = void; }; template using TupleElement = typename TupleElementImpl::type; template struct HasSize: std::false_type {}; template struct HasSize>().size())>>: std::true_type {}; template struct PTuple; template struct PTuple>>{}>> { static void print(std::string const& lbl, T const& t) { PTuple::print(lbl, t); } }; template struct PTuple>>{}>>> { static void print(std::string const& lbl, T const& t) { std::printf("%s: %zu\n", lbl.c_str(), std::get(t).size()); PTuple::print(lbl, t); } }; template struct PTuple { static void print(std::string const&, T const&) {} }; } template void pTuple(std::string const& lbl, std::tuple const& t) { impl::PTuple<0, sizeof...(Ts), std::tuple>::print(lbl, t); } /* TODO: find a place */ struct Less { template bool operator()(T const& lhs, T const& rhs) const { return lhs < rhs; } }; template static auto max(T&& value) { return std::forward(value); } template* = nullptr> static constexpr auto max(T const& value, Ts&&... values) noexcept { auto m = max(std::forward(values)...); return std::max(m, value); } /** * helper to write recursive lambda functions */ template struct RecursiveLambda { F f; template void operator()(Args&&... args) const { f(std::ref(*this), std::forward(args)...); } }; template static RecursiveLambda> makeRecursiveLambda(F&& f) { return {std::forward(f)}; } } #endif