mark_t useless(iterator begin, iterator end) const
{
mark_t::value_t u = 0U; // The set of useless marks.
for (unsigned x = 0; x < num_; ++x)
{
// Skip marks that are already known to be useless.
if (u & (1 << x))
continue;
unsigned all = all_ ^ (u | (1 << x));
for (iterator y = begin; y != end; ++y)
{
auto v = y->id;
if (v & (1 << x))
{
all &= v;
if (!all)
break;
}
}
u |= all;
}
return u;
}
protected:
mark_t::value_t mark_(unsigned u) const
{
assert(u < num_sets());
return 1U << u;
}
mark_t::value_t all_sets_() const
{
if (num_ == 0)
return 0;
return -1U >> (8 * sizeof(mark_t::value_t) - num_);
}
unsigned num_;
mark_t::value_t all_;
acc_code code_;
bool uses_fin_acceptance_ = false;
};
/// \brief Parse a string into an acc_code
///
/// The string should follow the following grammar:
///
///
/// acc ::= "t"
/// | "f"
/// | "Inf" "(" num ")"
/// | "Fin" "(" num ")"
/// | "(" acc ")"
/// | acc "&" acc
/// | acc "|" acc
///
///
/// Where num is an integer and "&" has priority over "|". Note that
/// "Fin(!x)" and "Inf(!x)" are not supported by this parser.
///
/// A spot::parse_error is thrown on syntax error.
SPOT_API acc_cond::acc_code parse_acc_code(const char* input);
}
namespace std
{
template<>
struct hash
{
size_t operator()(spot::acc_cond::mark_t m) const
{
std::hash h;
return h(m.id);
}
};
}