1 #ifndef VCSN_LABELSET_TUPLESET_HH
2 # define VCSN_LABELSET_TUPLESET_HH
9 # include <vcsn/config.hh>
29 template <
typename Enable = void,
typename... ValueSets>
38 template <
typename... ValueSets>
44 using letter_t = std::tuple<
typename ValueSets::letter_t...>;
45 using word_t = std::tuple<
typename ValueSets::word_t...>;
49 template <
typename... ValueSets>
56 template <
typename... ValueSets>
63 template <std::size_t... I>
67 template <std::
size_t I>
68 using valueset_t =
typename std::tuple_element<I, valuesets_t>::type;
74 using value_t = std::tuple<
typename ValueSets::value_t...>;
98 return sname_(indices);
101 std::string
vname(
bool full =
true)
const
103 return vname_(full, indices);
106 static constexpr std::size_t
size()
108 return sizeof...(ValueSets);
111 static constexpr
bool
114 return is_commutative_(indices);
117 static constexpr
bool
120 return is_idempotent_(indices);
128 auto res = make_(is, indices);
137 return join_(rhs, indices);
150 return std::get<I>(sets());
158 return open_(o, indices);
162 template <
typename... Args>
165 return value_(args, indices);
172 return genset_(indices);
177 return is_free_(indices);
182 template <
typename Value, std::size_t... I>
196 template <
typename Value>
199 -> decltype(letters_of_(v, indices))
201 return letters_of_(v, indices);
205 template <
typename... Args>
207 word(
const std::tuple<Args...>& v)
const
210 return word_(v, indices);
216 return equals_(l, r, indices);
223 return less_than_(l, r, indices);
229 return special_(indices);
235 return is_special_(l, indices);
241 return zero_(indices);
247 return is_zero_(l, indices);
250 static constexpr
bool
253 return has_one_(indices);
256 static constexpr
bool
259 return is_ratexpset_(indices);
262 static constexpr
bool
265 return is_letterized_(indices);
271 return one_(indices);
277 return is_one_(l, indices);
283 return show_one_(indices);
295 return add_(l, r, indices);
301 return mul_(l, r, indices);
307 return rdiv_(l, r, indices);
313 return ldiv_(l, r, indices);
317 typename valueset_t<0>::value_t
320 return lnormalize_here_(v, indices);
326 return star_(l, indices);
334 template <
typename Value>
338 return delimit_(l, indices);
342 template <
typename Value>
346 return undelimit_(l, indices);
355 template <
typename LhsValue,
typename RhsValue>
357 concat(
const LhsValue& l,
const RhsValue&
r)
const
359 return concat_(l, r, indices);
365 return transpose_(l, indices);
371 return hash_(v, indices);
387 template <
typename... VS>
392 return conv_(vs, v, indices);
396 template <
typename... VS>
401 return conv(*vs.labelset(), vs.get_value(v));
408 value_t res = conv_(i, indices);
413 std::set<value_t>
convs(std::istream&)
const
415 raise(
"tupleset: ranges not implemented");
421 return print_set_(o, format, indices);
428 return print_(l, o, format, indices);
432 template <std::size_t... I>
435 std::string res =
"lat<";
436 const char *sep =
"";
447 template <std::size_t... I>
450 std::string res =
"lat<";
451 const char *sep =
"";
452 for (
auto n: {set<I>().
vname(full)...})
462 template <std::size_t... I>
463 static constexpr
bool
466 return all_<valueset_t<I>::is_commutative()...>();
469 template <std::size_t... I>
470 static constexpr
bool
473 return all_<valueset_t<I>::is_idempotent()...>();
476 template <std::size_t... I>
479 # if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
480 return tupleset{(eat_separator_<I>(i,
'<',
','),
484 ((eat_separator_<
sizeof...(ValueSets)-1 -I>(i,
'<',
','),
485 valueset_t<
sizeof...(ValueSets)-1 -I>::make(i))...);
489 template <std::size_t... I>
492 using swallow =
int[];
493 (void) swallow { set<I>().open(o)... };
494 std::swap(o, open__);
498 template <
typename... Args, std::size_t... I>
501 return value_t{set<I>().value(std::get<I>(args))...};
504 template <std::size_t... I>
508 return cross(set<I>().genset()...);
511 template <std::size_t... I>
512 static constexpr
bool
515 return all_<valueset_t<I>::is_free()...>();
518 template <
typename... Args, std::size_t... I>
522 return word_t{set<I>().word(std::get<I>(l))...};
525 template <std::size_t... I>
536 template <std::size_t... I>
543 std::get<I>(l)))...})
551 template <std::size_t... I>
557 std::hash_combine(res, h);
561 template <std::size_t... I>
568 template <std::size_t... I>
578 template <std::size_t... I>
585 template <std::size_t... I>
589 for (
auto n: {set<I>().is_zero(std::get<I>(l))...})
595 template <std::size_t... I>
596 static constexpr
bool
599 return all_<valueset_t<I>::has_one()...>();
602 template <std::size_t... I>
603 static constexpr
bool
606 return all_<valueset_t<I>::is_ratexpset()...>();
609 template <std::size_t... I>
610 static constexpr
bool
613 return all_<valueset_t<I>::is_letterized()...>();
616 template <std::size_t... I>
623 template <std::size_t... I>
633 template <std::size_t... I>
643 template <std::size_t... I>
647 return value_t{set<I>().add(std::get<I>(l), std::get<I>(
r))...};
650 template <std::size_t... I>
654 return value_t{set<I>().mul(std::get<I>(l), std::get<I>(
r))...};
657 template <std::size_t... I>
661 return value_t{set<I>().rdiv(std::get<I>(l), std::get<I>(
r))...};
664 template <std::size_t... I>
668 return value_t{set<I>().
ldiv(std::get<I>(l), std::get<I>(
r))...};
671 template <std::size_t... I>
672 typename valueset_t<0>::value_t
676 for (
auto v: {std::get<I>(vs)...})
677 res = set<0>().lgcd(res, v);
678 using swallow =
int[];
679 (void) swallow { (set<0>().ldiv_here(res, std::get<I>(vs)), 0)... };
683 template <std::size_t... I>
690 template <
typename Value, std::size_t... I>
694 return Value{set<I>().delimit(std::get<I>(l))...};
697 template <
typename Value, std::size_t... I>
701 return Value{set<I>().undelimit(std::get<I>(l))...};
704 template <
typename LhsValue,
typename RhsValue, std::size_t... I>
708 return word_t{set<I>().concat(std::get<I>(l), std::get<I>(
r))...};
711 template <
typename... VS, std::size_t... I>
717 return value_t{set<I>().
conv(vs.template set<I>(), std::get<I>(v))...};
720 template <std::size_t... I>
724 # if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
725 return value_t{(eat_separator_<I>(i,
'(',
','),
726 set<I>().conv(i))...};
728 constexpr
auto S =
sizeof...(ValueSets)-1;
731 std::get<S - I>(sets_).
conv(i))...);
738 template <std::
size_t I>
742 eat(i, I == 0 ? first : tail);
743 while (isspace(i.peek()))
748 template <std::size_t... I>
755 using swallow =
int[];
758 (o << (I == 0 ?
'(' :
','),
759 set<I>().print(std::get<I>(l), o, format),
767 template <std::size_t... I>
772 const char *sep =
"";
773 if (format ==
"latex")
775 else if (format ==
"text")
781 raise(
"invalid format: ", format);
782 using swallow =
int[];
785 (o << (I == 0 ?
"" : sep),
786 set<I>().print_set(o, format),
789 if (format ==
"text")
794 template <std::size_t... I>
796 transpose_(value_t const& l, seq<I...>) const
798 return value_t{(set<I>().transpose(std::get<I>(l)))...};
802 template <std::size_t... I>
804 meet_(const tupleset& rhs, seq<I...>) const
806 return tupleset{meet(set<I>(), rhs.set<I>())...};
810 template <std::size_t... I>
812 join_(const tupleset& rhs, seq<I...>) const
814 return tupleset{vcsn::join(set<I>(), rhs.set<I>())...};
820 meet(const tupleset& lhs, const tupleset& rhs)
822 return lhs.meet_(rhs, indices);
828 meet(const tupleset& lhs, const b&)
836 meet(const b&, const tupleset& rhs)
842 mutable bool open__ = false;
847 template <typename T1, typename T2>
848 struct concat_tupleset;
850 template <typename... T1, typename... T2>
851 struct concat_tupleset<tupleset<T1...>, tupleset<T2...>>
853 using type = tupleset<T1..., T2...>;
857 template <typename... LabelSets>
858 struct nullableset_traits<tupleset<LabelSets...>,
859 enable_if_t<tupleset<LabelSets...>::has_one()>>
861 using labelset_t = tupleset<LabelSets...>;
862 using type = labelset_t;
863 static type value(const labelset_t& ls)
870 template <typename... LabelSets>
871 struct nullableset_traits<tupleset<LabelSets...>,
872 enable_if_t<!tupleset<LabelSets...>::has_one()>>
874 using labelset_t = tupleset<LabelSets...>;
875 using type = nullableset<labelset_t>;
877 static type value(const labelset_t& ls)
884 template <typename... LabelSets>
885 struct law_traits<tupleset<LabelSets...>>
887 using labelset_t = tupleset<LabelSets...>;
888 using type = tupleset<law_t<LabelSets>...>;
890 template <std::size_t... I>
891 static type value(const labelset_t& ls, detail::index_sequence<I...>)
893 return {make_wordset(ls.template set<I>())...};
896 static type value(const labelset_t& ls)
898 return value(ls, detail::make_index_sequence<sizeof...(LabelSets)>{});
902 template <typename... VS1, typename... VS2>
903 struct join_impl<tupleset<VS1...>, tupleset<VS2...>>
905 using type = tupleset<join_t<VS1, VS2>...>;
906 static type join(const tupleset<VS1...>& lhs, const tupleset<VS2...>& rhs)
908 return lhs.join(rhs);
914 #endif // !VCSN_LABELSET_TUPLESET_HH
variadic< type_t::ldiv, Context > ldiv
value_t star_(value_t const &l, seq< I...>) const
typename labelset_types< ValueSets...>::genset_t genset_t
A tuple of gensets if meaningful, void otherwise.
bool is_letter(const value_t &) const
static value_t conv(self_type, value_t v)
static bool less_than_(const value_t &l, const value_t &r, seq< I...>)
static constexpr bool has_one_(seq< I...>)
static size_t hash(const value_t &v)
genset_t genset_(seq< I...>) const
word_t word_(const std::tuple< Args...> &l, seq< I...>) const
value_t mul_(const value_t &l, const value_t &r, seq< I...>) const
static tupleset make_(std::istream &i, seq< I...>)
value_t value(const std::tuple< Args...> &args) const
Construct a value.
value_t add_(const value_t &l, const value_t &r, seq< I...>) const
A ValueSet which is a Cartesian product of ValueSets.
value_t conv(const tupleset< VS...> &vs, const typename tupleset< VS...>::value_t &v) const
Convert a value from tupleset<...> to value_t.
Value undelimit(const Value &l) const
Remove first and last characters, that must be "special".
typename labelset_types< ValueSets...>::word_t word_t
A tuple of words if meaningful, void otherwise.
std::ostream & print(const value_t &l, std::ostream &o, symbol format=symbol{"text"}) const
static std::size_t hash_(const value_t &v, seq< I...>)
static constexpr bool is_commutative()
bool open_(bool o, seq< I...>) const
A traits so that tupleset may define types that may exist.
static constexpr bool is_idempotent()
auto word(const std::tuple< Args...> &v) const -> word_t
Convert to a word.
static void eat_separator_(std::istream &i, char first, char tail)
Read the separator from the input stream i.
Implementation of labels are nullables (letter or empty).
letter_t value_type
To be iterable.
boost::flyweight< std::string, boost::flyweights::no_tracking > symbol
An internalized string.
bool is_zero_(const value_t &l, seq< I...>) const
std::ostream & print_(value_t const &l, std::ostream &o, symbol format, seq< I...>) const
std::tuple< typename ValueSets::value_t...> value_t
A tuple of values.
static constexpr bool is_letterized()
const valueset_t< I > & set() const
The Ith component valueset.
auto conv(const ValueSet &vs, const std::string &str, Args &&...args) -> decltype(vs.conv(std::declval< std::istream & >(), std::forward< Args >(args)...))
Parse str via vs.conv.
value_t ldiv(const value_t &l, const value_t &r) const
std::ostream & print_set(std::ostream &o, symbol format=symbol{"text"}) const
zip_sequences< Sequences...> zip(Sequences &&...seqs)
value_t rdiv(const value_t &l, const value_t &r) const
std::ostream & print_set_(std::ostream &o, symbol format, seq< I...>) const
value_t value_(const std::tuple< Args...> &args, seq< I...>) const
std::string vname_(bool full, seq< I...>) const
value_t add(const value_t &l, const value_t &r) const
typename labelset_types< ValueSets...>::letter_t letter_t
A tuple of letters if meaningful, void otherwise.
std::tuple< typename ValueSets::letter_t...> letter_t
static value_t one_(seq< I...>)
value_t transpose(const value_t &l) const
static constexpr star_status_t star_status()
static constexpr bool is_letterized_(seq< I...>)
genset_t genset() const
The generators. Meaningful for labelsets only.
join_impl< V1, V2 >::type join_(V1 v1, V2 v2, int)
Dealing with commutativity: two implementations of join_: forward and reversed, ordered by preference...
static std::string sname()
value_t star(const value_t &l) const
unary< type_t::star, Context > star
value_t rdiv_(const value_t &l, const value_t &r, seq< I...>) const
static bool is_one(const value_t &l)
static value_t special_(seq< I...>)
std::tuple< ValueSets...> valuesets_t
const valuesets_t & sets() const
The componants valuesets, as a tuple.
static constexpr bool is_ratexpset()
static constexpr bool is_commutative_(seq< I...>)
bool is_zero(const value_t &l) const
static tupleset make(std::istream &is)
Build from the description in is.
Value delimit(const Value &l) const
Add the special character first and last.
static constexpr bool has_one()
word_t concat_(const LhsValue &l, const RhsValue &r, seq< I...>) const
static constexpr bool is_ratexpset_(seq< I...>)
std::istringstream is
The input stream: the specification to translate.
value_t conv(std::istream &i) const
Read one label from i, return the corresponding value.
std::tuple< typename ValueSets::word_t...> word_t
Value delimit_(Value const &l, seq< I...>) const
static bool is_special(const value_t &l)
value_t conv(const nullableset< tupleset< VS...>> &vs, const typename nullableset< tupleset< VS...>>::value_t &v) const
Convert a value from nullableset> to value_t.
constant< type_t::one, Context > one
static constexpr bool is_idempotent_(seq< I...>)
static bool equals(const value_t &l, const value_t &r)
cross_sequences< Sequences...> cross(Sequences &&...seqs)
constant< type_t::zero, Context > zero
std::string vname(bool full=true) const
Provide a variadic mul on top of a binary mul(), and one().
static std::string sname_(seq< I...>)
static constexpr bool is_free_(seq< I...>)
valueset_t< 0 >::value_t lnormalize_here_(value_t &vs, seq< I...>) const
static bool is_special_(const value_t &l, seq< I...>)
static auto letters_of_(const Value &v, seq< I...>) -> decltype(zip(valueset_t< I >::letters_of(std::get< I >(v))...))
Must be declared before, as we use its result in decltype.
std::set< value_t > convs(std::istream &) const
value_t conv_(std::istream &i, seq< I...>) const
char eat(std::istream &is, char c)
Check lookahead character and advance.
static auto letters_of(const Value &v) -> decltype(letters_of_(v, indices))
Iterate over the letters of v.
value_t conv_(const tupleset< VS...> &vs, const typename tupleset< VS...>::value_t &v, seq< I...>) const
static constexpr bool is_free()
valueset_t< 0 >::value_t lnormalize_here(value_t &v) const
This tupleset must be homegeneous.
static bool show_one_(seq< I...>)
value_t conv(b, b::value_t v) const
static constexpr std::size_t size()
typename std::tuple_element< I, valuesets_t >::type valueset_t
The Ith valueset type.
word_t concat(const LhsValue &l, const RhsValue &r) const
value_t zero_(seq< I...>) const
value_t mul(const value_t &l, const value_t &r) const
static bool equals_(const value_t &l, const value_t &r, seq< I...>)
Value undelimit_(Value const &l, seq< I...>) const
value_t ldiv_(const value_t &l, const value_t &r, seq< I...>) const
variadic_mul_mixin< detail::r_impl > r
bool open(bool o) const
Whether unknown letters should be added, or rejected.
auto make_gcc_tuple(Ts &&...ts) -> decltype(reverse_tuple(std::make_tuple(std::forward< Ts >(ts)...)))
Same as make_tuple, unless the evaluation of arguments if right-to-left, in which case reverse the re...
static bool less_than(const value_t &l, const value_t &r)
Whether l < r.
static bool is_one_(const value_t &l, seq< I...>)
tupleset join(const tupleset &rhs) const
The join with another tupleset.