#ifndef wasm_analysis_lattice_h
#define wasm_analysis_lattice_h
#if __cplusplus >= 202002L
#include <concepts>
#endif
namespace wasm::analysis {
enum LatticeComparison { NO_RELATION, EQUAL, LESS, GREATER };
inline LatticeComparison reverseComparison(LatticeComparison comparison) {
if (comparison == LatticeComparison::LESS) {
return LatticeComparison::GREATER;
} else if (comparison == LatticeComparison::GREATER) {
return LatticeComparison::LESS;
} else {
return comparison;
}
}
#if __cplusplus >= 202002L
template<typename L>
concept Lattice = requires(const L& lattice,
const typename L::Element& constElem,
typename L::Element& elem) {
typename L::Element;
requires std::copyable<typename L::Element>;
{ lattice.getBottom() } noexcept -> std::same_as<typename L::Element>;
{
lattice.compare(constElem, constElem)
} noexcept -> std::same_as<LatticeComparison>;
{ lattice.join(elem, constElem) } noexcept -> std::same_as<bool>;
};
template<typename L>
concept FullLattice =
Lattice<L> && requires(const L& lattice,
const typename L::Element& constElem,
typename L::Element& elem) {
{ lattice.getTop() } noexcept -> std::same_as<typename L::Element>;
{ lattice.meet(elem, constElem) } noexcept -> std::same_as<bool>;
};
#else
#define Lattice typename
#define FullLattice typename
#endif
}
#endif