diff --git a/include/compattable.h b/include/compattable.h new file mode 100644 index 0000000..048828e --- /dev/null +++ b/include/compattable.h @@ -0,0 +1,109 @@ +#pragma once +#include "actions.h" +#include "data.h" +#include + +template struct CompatTableS; + +template class A, template class D, class... Acts, class... Datas> struct CompatTableS, D> +{ + size_t static consteval StrLen(const char* str) { return *str ? 1 + StrLen(str + 1) : 0; } + + template static consteval size_t MaxNameLen() + { + if constexpr(sizeof...(Dd) == 0) + return StrLen(D1::name); + else + return std::max(StrLen(D1::name), MaxNameLen()); + } + + static constexpr size_t W = MaxNameLen(); + + template static consteval auto C2A(const char (&s)[N]) + { + std::array out; + for(size_t i = 0; i < N; i++) out[i] = s[i]; + return out; + } + + static constexpr auto em = C2A(""); + static constexpr auto sp = C2A(" "); + static constexpr auto nd = C2A("\n"); + + template static consteval auto N2A() + { + std::array out; + for(size_t i = 0; i <= StrLen(T::name); i++) out[i] = T::name[i]; + return out; + } + template static constexpr auto name = N2A(); + + template static consteval auto Merge(const std::array& arg1, const std::array& arg2, const T&... args) + { + if constexpr(sizeof...(T) == 0) + { + std::array out; + for(size_t i = 0; i < N - 1; i++) out[i] = arg1[i]; + for(size_t i = 0; i < M; i++) out[i + N - 1] = arg2[i]; + return out; + } + else + return Merge(arg1, Merge(arg2, args...)); + } + + template static consteval auto Spaces() + { + if constexpr(n == 0) + return em; + else + return Merge(sp, Spaces()); + } + + template static consteval auto AlignR(const T& s) + { + constexpr size_t len = std::tuple_size_v - 1; + if constexpr(len > n) return s; + return Merge(Spaces(), s); + } + + template static consteval auto AlignL(const T& s) + { + constexpr size_t len = std::tuple_size_v - 1; + if constexpr(len > n) return s; + return Merge(s, Spaces()); + } + + template static consteval auto MergeNames() + { + if constexpr(sizeof...(Aa) == 0) + return name; + else + return Merge(name, sp, MergeNames()); + } + + static constexpr auto header = Merge(Spaces(), MergeNames()); + + template static consteval auto MergeSup() + { + constexpr bool issup = A1::template IsSupported && !IsDisabled(); + constexpr auto v = Merge(Spaces(), C2A(issup ? "\033[32mY\033[0m" : "\033[31mN\033[0m")); + //constexpr auto v = AlignR(C2A(issup ? "X" : " ")); + if constexpr(sizeof...(Aa) == 0) + return v; + else + return Merge(v, sp, MergeSup()); + } + + template static consteval auto MergeRows() + { + constexpr auto r = Merge(AlignL(name), MergeSup()); + if constexpr(sizeof...(Dd) == 0) + return r; + else + return Merge(r, nd, MergeRows()); + } + + static constexpr auto value = Merge(header, nd, MergeRows()); +}; + +static constexpr auto CompatTable = CompatTableS::value.data(); diff --git a/include/odm.h b/include/odm.h index 7b798dd..06db38c 100644 --- a/include/odm.h +++ b/include/odm.h @@ -1,6 +1,5 @@ #pragma once -#include "actions.h" -#include "data.h" +#include "compattable.h" using michlib::errmessage; using michlib::message; diff --git a/src/odm.cpp b/src/odm.cpp index e2756ce..4cfbaf1 100644 --- a/src/odm.cpp +++ b/src/odm.cpp @@ -61,6 +61,12 @@ int main(int argc, char** argv) Usage(argv[0]); return 2; } + if(argc == 2 && (argv[1] == MString("table") || argv[1] == MString("compattable"))) + { + message(CompatTable); + return 2; + } + auto args = ParseArgs(argc, argv); MString action = args.contains("action") ? args["action"] : "info";