diff --git a/include/utempl/menu.hpp b/include/utempl/menu.hpp index cfc8f2f..c5e8be0 100644 --- a/include/utempl/menu.hpp +++ b/include/utempl/menu.hpp @@ -72,6 +72,35 @@ CallbackMessage(const char(&)[N1]) -> CallbackMessage; template struct Menu { +private: + template + static consteval auto FormatMessage() { + // + 1 - NULL Terminator + constexpr auto size = fmt::formatted_size(FMT_COMPILE(fmt.data.begin()) + ,neededInput + ,message + ,alignment) + 1; + char data[size]{}; + fmt::format_to(data, FMT_COMPILE(fmt.data.begin()) + ,neededInput + ,message + ,alignment); + return ConstexprString(data); + }; + template + static consteval auto FormatMessageFor() { + constexpr ConstexprString message = Get(storage).message; + constexpr ConstexprString neededInput = [&] { + if constexpr(Get(storage).need) { + return *Get(storage).need; + } else { + return ToString(); + }; + }(); + constexpr ConstexprString alignment = CreateStringWith(storage).need ? Get(storage).need->size() : CountDigits(I))>(' '); + return FormatMessage(); + }; +public: Tuple functionStorage; static consteval auto GetMaxSize() -> std::size_t { @@ -86,36 +115,11 @@ struct Menu { }; template inline constexpr auto Run(std::istream& in = std::cin, std::FILE* out = stdout) const -> std::size_t { - using Cleared = std::remove_cvref_t; - constexpr auto maxSize = Cleared::GetMaxSize(); return [&](std::index_sequence) -> std::size_t { - constexpr auto message = ([&](Wrapper){ - constexpr auto message = Get(storage); - constexpr std::size_t s = maxSize - (message.need ? message.need->size() : CountDigits(I)); - constexpr auto str3 = CreateStringWith(' '); - constexpr auto str2 = message.message; - constexpr auto str1 = [&] { - if constexpr(message.need) { - return *message.need; - } else { - return ToString(); - }; - }(); - // + 1 - NULL Terminator - constexpr auto size = fmt::formatted_size(FMT_COMPILE(fmt.data.begin()) - ,str1 - ,str2 - ,str3) + 1; - char data[size] = {}; - fmt::format_to(data, FMT_COMPILE(fmt.begin()) - ,str1 - ,str2 - ,str3); - return ConstexprString(data); - }(Wrapper{}) + ...) + enter; + constexpr auto message = ((FormatMessageFor() + ...) + enter); auto result = std::fwrite(message.begin(), 1, message.size(), out); if(result < message.size()) { - return result; + return EOF; }; if(std::fflush(out) != 0) { return EOF; diff --git a/include/utempl/type_list.hpp b/include/utempl/type_list.hpp index 59fcc9e..09cbb3d 100644 --- a/include/utempl/type_list.hpp +++ b/include/utempl/type_list.hpp @@ -61,7 +61,17 @@ consteval auto Transform(TypeList, auto&& f) -> TypeList consteval auto Filter(TypeList, auto&& f) { - return ([](auto&& list){if constexpr(decltype(f(list))::kValue) {return list;} else {return kTypeList<>;}}(kType) + ...); + return ( + (kTypeList<> + + [](auto&& list) { + if constexpr(decltype(f(list))::kValue) { + return list; + } else { + return kTypeList<>; + } + }(kType) + ) + + ...); };