Refactor menu
This commit is contained in:
parent
0c5d612867
commit
285ae2137f
2 changed files with 42 additions and 28 deletions
|
@ -72,6 +72,35 @@ CallbackMessage(const char(&)[N1]) -> CallbackMessage<N1, 0>;
|
||||||
|
|
||||||
template <Tuple storage = Tuple{}, typename... Fs>
|
template <Tuple storage = Tuple{}, typename... Fs>
|
||||||
struct Menu {
|
struct Menu {
|
||||||
|
private:
|
||||||
|
template <ConstexprString fmt, ConstexprString message, ConstexprString alignment, ConstexprString neededInput>
|
||||||
|
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<size>(data);
|
||||||
|
};
|
||||||
|
template <ConstexprString fmt, std::size_t I>
|
||||||
|
static consteval auto FormatMessageFor() {
|
||||||
|
constexpr ConstexprString message = Get<I>(storage).message;
|
||||||
|
constexpr ConstexprString neededInput = [&] {
|
||||||
|
if constexpr(Get<I>(storage).need) {
|
||||||
|
return *Get<I>(storage).need;
|
||||||
|
} else {
|
||||||
|
return ToString<I>();
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
constexpr ConstexprString alignment = CreateStringWith<GetMaxSize() - (Get<I>(storage).need ? Get<I>(storage).need->size() : CountDigits(I))>(' ');
|
||||||
|
return FormatMessage<fmt, message, alignment, neededInput>();
|
||||||
|
};
|
||||||
|
public:
|
||||||
Tuple<Fs...> functionStorage;
|
Tuple<Fs...> functionStorage;
|
||||||
|
|
||||||
static consteval auto GetMaxSize() -> std::size_t {
|
static consteval auto GetMaxSize() -> std::size_t {
|
||||||
|
@ -86,36 +115,11 @@ struct Menu {
|
||||||
};
|
};
|
||||||
template <ConstexprString fmt, ConstexprString enter = "|> ">
|
template <ConstexprString fmt, ConstexprString enter = "|> ">
|
||||||
inline constexpr auto Run(std::istream& in = std::cin, std::FILE* out = stdout) const -> std::size_t {
|
inline constexpr auto Run(std::istream& in = std::cin, std::FILE* out = stdout) const -> std::size_t {
|
||||||
using Cleared = std::remove_cvref_t<decltype(*this)>;
|
|
||||||
constexpr auto maxSize = Cleared::GetMaxSize();
|
|
||||||
return [&]<auto... Is>(std::index_sequence<Is...>) -> std::size_t {
|
return [&]<auto... Is>(std::index_sequence<Is...>) -> std::size_t {
|
||||||
constexpr auto message = ([&]<auto I>(Wrapper<I>){
|
constexpr auto message = ((FormatMessageFor<fmt, Is>() + ...) + enter);
|
||||||
constexpr auto message = Get<I>(storage);
|
|
||||||
constexpr std::size_t s = maxSize - (message.need ? message.need->size() : CountDigits(I));
|
|
||||||
constexpr auto str3 = CreateStringWith<s>(' ');
|
|
||||||
constexpr auto str2 = message.message;
|
|
||||||
constexpr auto str1 = [&] {
|
|
||||||
if constexpr(message.need) {
|
|
||||||
return *message.need;
|
|
||||||
} else {
|
|
||||||
return ToString<I>();
|
|
||||||
};
|
|
||||||
}();
|
|
||||||
// + 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<size>(data);
|
|
||||||
}(Wrapper<Is>{}) + ...) + enter;
|
|
||||||
auto result = std::fwrite(message.begin(), 1, message.size(), out);
|
auto result = std::fwrite(message.begin(), 1, message.size(), out);
|
||||||
if(result < message.size()) {
|
if(result < message.size()) {
|
||||||
return result;
|
return EOF;
|
||||||
};
|
};
|
||||||
if(std::fflush(out) != 0) {
|
if(std::fflush(out) != 0) {
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
|
@ -61,7 +61,17 @@ consteval auto Transform(TypeList<Ts...>, auto&& f) -> TypeList<decltype(f(TypeL
|
||||||
};
|
};
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
consteval auto Filter(TypeList<Ts...>, auto&& f) {
|
consteval auto Filter(TypeList<Ts...>, auto&& f) {
|
||||||
return ([](auto&& list){if constexpr(decltype(f(list))::kValue) {return list;} else {return kTypeList<>;}}(kType<Ts>) + ...);
|
return (
|
||||||
|
(kTypeList<>
|
||||||
|
+ [](auto&& list) {
|
||||||
|
if constexpr(decltype(f(list))::kValue) {
|
||||||
|
return list;
|
||||||
|
} else {
|
||||||
|
return kTypeList<>;
|
||||||
|
}
|
||||||
|
}(kType<Ts>)
|
||||||
|
)
|
||||||
|
+ ...);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue