6 #include <boost/range/algorithm/mismatch.hpp>
7 #include <boost/algorithm/string/predicate.hpp>
21 template <
typename GenSet>
22 class wordset:
public detail::genset_labelset<GenSet>
31 using word_t =
typename genset_t::word_t;
43 :
wordset{std::make_shared<const genset_t>(gs)}
46 wordset(
const std::initializer_list<letter_t>& letters)
63 auto gs = genset_t::make(is);
73 return this->
genset().open(o);
82 template <
typename... Args>
85 return value_t{std::forward<Args>(args)...};
127 return genset_t::less(l, r);
133 return genset_t::template special<value_t>();
151 static constexpr
bool
157 static constexpr
bool
163 static constexpr
bool
172 return genset_t::empty_word();
178 return genset_t::is_empty_word(l);
199 template <
typename GenSet_>
210 *
this,
": conv: invalid label: ",
str_escape(v));
215 template <
typename LabelSet_>
227 conv(std::istream& i,
bool =
true)
const
229 return this->
genset().get_word(i);
238 template <
typename Fun>
239 void convs(std::istream& i, Fun fun)
const
251 this->
genset().print(l, o, fmt);
260 this->
genset().print_set(o, fmt);
266 this->
genset().print_set(o, fmt);
270 raise(*this, ": print_set: invalid format: ", fmt);
275 static value_t lgcd(const value_t& w1, const value_t& w2)
277 return {w1.begin(), boost::mismatch(w1, w2).first};
282 static value_t ldiv(const value_t& w1, const value_t& w2)
284 using boost::algorithm::starts_with;
285 require(starts_with(w2, w1),
286 sname(), ": ldiv: invalid arguments: ", str_escape(w1),
287 ", ", str_escape(w2));
288 return w2.substr(size(w1));
292 static value_t& ldiv_here(const value_t& w1, value_t& w2)
302 template <typename GenSet>
303 struct letterized_traits<wordset<GenSet>>
305 static constexpr bool is_letterized = false;
307 using labelset_t = nullableset<letterset<GenSet>>;
309 static labelset_t labelset(const wordset<GenSet>& ls)
311 return {ls.genset()};
316 template <typename GenSet>
317 struct nullableset_traits<wordset<GenSet>>
319 using type = wordset<GenSet>;
320 static type value(const wordset<GenSet>& ls)
326 template <typename GenSet>
327 struct law_traits<wordset<GenSet>>
329 using type = wordset<GenSet>;
330 static type value(const wordset<GenSet>& ls)
341 #define DEFINE(Lhs, Rhs) \
342 template <typename GenSet> \
343 struct join_impl<Lhs, Rhs> \
346 static type join(const Lhs& lhs, const Rhs& rhs) \
348 return {get_union(lhs.genset(), rhs.genset())}; \
353 DEFINE(letterset<GenSet>, wordset<GenSet>);
354 DEFINE(nullableset<letterset<GenSet>>, wordset<GenSet>);
355 DEFINE(wordset<GenSet>, wordset<GenSet>);
360 // FIXME: Factor in genset_labelset?
361 template <typename GenSet>
363 meet(const wordset<GenSet>& lhs, const wordset<GenSet>& rhs)
365 return {intersection(lhs.genset(), rhs.genset())};
static bool is_one(const value_t &l) ATTRIBUTE_PURE
static word_t letters_of_padded(const value_t &v, letter_t)
Prepare to iterate over the letters of v.
std::ostream & str_escape(std::ostream &os, const std::string &str)
Output a string, escaping special characters.
Implementation of labels are letters.
word_t word(const value_t &v) const
Convert to a word.
weightset_mixin< detail::r_impl > r
This class has no modeling purpose, it only serves to factor code common to letterset, nullableset and wordset.
static constexpr bool has_one()
ATTRIBUTE_PURE auto has(Args &&...args) const -> decltype(this->genset().has(std::forward< Args >(args)...))
typename genset_t::letters_t letters_t
wordset(const std::initializer_list< letter_t > &letters)
typename helper_t::value_t value_t
std::istringstream is
The input stream: the specification to translate.
char eat(std::istream &is, char c)
Check lookahead character and advance.
static size_t hash(const value_t &v)
value_t conv(std::istream &i, bool=true) const
bool open(bool o) const
Whether unknown letters should be added, or rejected.
std::shared_ptr< const genset_t > genset_ptr
std::ostream & print_set(std::ostream &o, format fmt={}) const
wordset(const genset_t &gs={})
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
typename genset_t::word_t word_t
static bool is_special(const value_t &v)
value_t value(Args &&...args) const
Value constructor.
value_t conv(const nullableset< LabelSet_ > &ls, const typename nullableset< LabelSet_ >::value_t &v) const
const genset_t & genset() const
static ATTRIBUTE_PURE bool is_one(value_t l)
Provide a variadic mul on top of a binary mul(), and one().
static bool equal(const value_t &l, const value_t &r)
Whether l == r.
static bool is_special(value_t v) ATTRIBUTE_PURE
static constexpr bool is_expressionset()
void convs(std::istream &i, Fun fun) const
Process a range of labels.
static constexpr bool is_free()
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
const labelset_ptr labelset() const
value_t conv(self_t, const value_t &v) const
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
static size_t size(const value_t &v)
static bool less(const value_t &l, const value_t &r)
Whether l < r.
value_t conv(const letterset< GenSet_ > &ls, typename letterset< GenSet_ >::value_t v) const
bool is_valid(const value_t &v) const
static constexpr bool is_letterized()
wordset(const genset_ptr &gs)
std::ostream & print(const value_t &l, std::ostream &o, format fmt={}) const
static wordset make(std::istream &is)
Build from the description in is.
static labelset_t::value_t get_value(const value_t &v)
The (inner) value when it (the outer value) is not one.
typename genset_t::letter_t letter_t
static word_t letters_of(const value_t &v)
Prepare to iterate over the letters of v.
Implementation of labels are words.
void convs_(std::istream &i, Fun fun) const
Read and process a class of letters.
Implementation of labels are nullables (letter or empty).