Browse Source

Added compile-time generated compatibility table for actions and sources

interpolate
Michael Uleysky 1 year ago
parent
commit
1c144c65c8
  1. 109
      include/compattable.h
  2. 3
      include/odm.h
  3. 6
      src/odm.cpp

109
include/compattable.h

@ -0,0 +1,109 @@
#pragma once
#include "actions.h"
#include "data.h"
#include <array>
template<class A, class D> struct CompatTableS;
template<template<class...> class A, template<class...> class D, class... Acts, class... Datas> struct CompatTableS<A<Acts...>, D<Datas...>>
{
size_t static consteval StrLen(const char* str) { return *str ? 1 + StrLen(str + 1) : 0; }
template<class D1, class... Dd> static consteval size_t MaxNameLen()
{
if constexpr(sizeof...(Dd) == 0)
return StrLen(D1::name);
else
return std::max(StrLen(D1::name), MaxNameLen<Dd...>());
}
static constexpr size_t W = MaxNameLen<Datas...>();
template<size_t N> static consteval auto C2A(const char (&s)[N])
{
std::array<char, N> 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<class T> static consteval auto N2A()
{
std::array<char, StrLen(T::name) + 1> out;
for(size_t i = 0; i <= StrLen(T::name); i++) out[i] = T::name[i];
return out;
}
template<class T> static constexpr auto name = N2A<T>();
template<size_t N, size_t M, class... T> static consteval auto Merge(const std::array<char, N>& arg1, const std::array<char, M>& arg2, const T&... args)
{
if constexpr(sizeof...(T) == 0)
{
std::array<char, N + M - 1> 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<size_t n> static consteval auto Spaces()
{
if constexpr(n == 0)
return em;
else
return Merge(sp, Spaces<n - 1>());
}
template<size_t n, class T> static consteval auto AlignR(const T& s)
{
constexpr size_t len = std::tuple_size_v<T> - 1;
if constexpr(len > n) return s;
return Merge(Spaces<n - len>(), s);
}
template<size_t n, class T> static consteval auto AlignL(const T& s)
{
constexpr size_t len = std::tuple_size_v<T> - 1;
if constexpr(len > n) return s;
return Merge(s, Spaces<n - len>());
}
template<class A1, class... Aa> static consteval auto MergeNames()
{
if constexpr(sizeof...(Aa) == 0)
return name<A1>;
else
return Merge(name<A1>, sp, MergeNames<Aa...>());
}
static constexpr auto header = Merge(Spaces<W>(), MergeNames<Acts...>());
template<class Dat, class A1, class... Aa> static consteval auto MergeSup()
{
constexpr bool issup = A1::template IsSupported<Dat> && !IsDisabled<A1, Dat>();
constexpr auto v = Merge(Spaces<StrLen(A1::name) - 1>(), C2A(issup ? "\033[32mY\033[0m" : "\033[31mN\033[0m"));
//constexpr auto v = AlignR<StrLen(A1::name)>(C2A(issup ? "X" : " "));
if constexpr(sizeof...(Aa) == 0)
return v;
else
return Merge(v, sp, MergeSup<Dat, Aa...>());
}
template<class D1, class... Dd> static consteval auto MergeRows()
{
constexpr auto r = Merge(AlignL<W>(name<D1>), MergeSup<D1, Acts...>());
if constexpr(sizeof...(Dd) == 0)
return r;
else
return Merge(r, nd, MergeRows<Dd...>());
}
static constexpr auto value = Merge(header, nd, MergeRows<Datas...>());
};
static constexpr auto CompatTable = CompatTableS<ActionVariants, DataVariants>::value.data();

3
include/odm.h

@ -1,6 +1,5 @@
#pragma once
#include "actions.h"
#include "data.h"
#include "compattable.h"
using michlib::errmessage;
using michlib::message;

6
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";

Loading…
Cancel
Save