#pragma once
#include <bitset>
#include <type_traits>
namespace detail {
template <typename ...>
struct List {};
template <typename ..._Terms> struct head_f;
template <typename ..._Terms> using Head = typename head_f<_Terms...>::value;
template <typename _Head, typename ..._Tail>
struct head_f<_Head, _Tail...> {
using value = _Head;
};
} // namespace detail
template <typename ..._Terms>
struct Minterm {
static_assert(
(std::is_same_v<bool, typename _Terms::Result> && ...),
"All Minterm Terms must have a Result type of bool"
);
using Operand = typename detail::Head<_Terms...>::Operand;
using Value = std::bitset<sizeof...(_Terms)>;
Value value;
constexpr
Minterm(Operand const &operand) {
populate<0>(value, operand, detail::List<_Terms...>{});
}
template <std::size_t _bit, typename _Head, typename ..._Tail>
constexpr
void populate(Value &minterm, Operand const &operand, detail::List<_Head, _Tail...>) const {
minterm[_bit] = _Head{}(operand);
if constexpr (sizeof...(_Tail)) {
populate<_bit + 1>(minterm, operand, detail::List<_Tail...>{});
}
}
};