#pragma once #include "move.hpp" #include "type_traits.hpp" #include #include namespace util { template inline constexpr auto format(std::string_view fmt, Ts&&... args) -> std::string { #if defined(__cpp_if_consteval) && defined(doesnt_work_yet_in_clang_14) if consteval { return std::format(fmt, args...); } else { return std::vformat(fmt, std::make_format_args(std::forward(args)...)); } #else return std::vformat(fmt, std::make_format_args(std::forward(args)...)); #endif } template using has_formatter = std::is_constructible>; template using is_formattable = has_formatter; template inline constexpr bool is_formattable_v = is_formattable::value; template concept formattable = is_formattable_v; } // namespace util #include template struct std::formatter> : public std::formatter { template auto format(const std::optional& option, FormatContext& ctx) -> decltype(ctx.out()) { auto fmt = ctx.out(); if (option.has_value()) { fmt = std::format_to(fmt, "Some("); ctx.advance_to(fmt); fmt = std::formatter::format(option.value(), ctx); *fmt++ = ')'; } else { fmt = std::format_to(fmt, "None"); } return fmt; } };