Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
tuple-automaton.hh
Go to the documentation of this file.
1 #ifndef VCSN_CORE_TUPLE_AUTOMATON_HH
2 # define VCSN_CORE_TUPLE_AUTOMATON_HH
3 
4 # include <deque>
5 # include <iostream>
6 # include <map>
7 # include <utility>
8 
10 # include <vcsn/ctx/context.hh>
11 # include <vcsn/ctx/traits.hh>
12 # include <vcsn/misc/map.hh> // has
13 # include <vcsn/misc/tuple.hh>
14 
15 namespace vcsn
16 {
17  namespace detail
18  {
19  /*-------------------------------------.
20  | tuple_automaton_impl<Aut, Auts...>. |
21  `-------------------------------------*/
22 
29  template <typename Aut, typename... Auts>
31  : public automaton_decorator<Aut>
32  {
34  using automaton_t = Aut;
36 
37  public:
38  static std::string sname()
39  {
40  return "tuple_automaton" + sname_();
41  }
42 
43  std::string vname(bool full = true) const
44  {
45  return "tuple_automaton" + vname_(full);
46  }
47 
57 
58  using label_t = typename labelset_t::value_t;
59  using weight_t = typename weightset_t::value_t;
60 
61  public:
63  using automata_t = std::tuple<Auts...>;
64 
66  template <size_t I>
67  using input_automaton_t
69 
71  using super_t::aut_;
72 
73  tuple_automaton_impl(const automaton_t& aut, const Auts&... auts)
74  : super_t(aut)
75  , auts_(auts...)
76  {
77  pmap_[pre_()] = aut_->pre();
78  pmap_[post_()] = aut_->post();
79  }
80 
81  bool state_has_name(typename super_t::state_t s) const
82  {
83  return (s != super_t::pre()
84  && s != super_t::post()
85  && has(origins(), s));
86  }
87 
88  std::ostream&
89  print_state_name(typename super_t::state_t s, std::ostream& o,
90  const std::string& fmt = "text", bool delimit = false)
91  const
92  {
93  if (delimit)
94  o << '(';
95  print_state_name_(s, o, fmt, indices);
96  if (delimit)
97  o << ')';
98  return o;
99  }
100 
104  using state_name_t = std::tuple<state_t_of<Auts>...>;
105 
107  using origins_t = std::map<state_t, state_name_t>;
108 
110  const origins_t& origins() const
111  {
112  if (origins_.empty())
113  for (const auto& p: pmap_)
114  origins_.emplace(p.second, p.first);
115  return origins_;
116  }
117 
118  // FIXME: protected:
120  template <std::size_t... I>
122 
125  static constexpr indices_t indices{};
126 
128  static std::string sname_()
129  {
130  std::string res = "<" + Aut::element_type::sname() + ", ";
131  const char* sep = "";
132  using swallow = int[];
133  (void) swallow
134  {
135  (res += sep + Auts::element_type::sname(), sep = ", ", 0)...
136  };
137  res += ">";
138  return res;
139  }
140 
142  std::string vname_(bool full = true) const
143  {
144  return vname_(full, indices);
145  }
146 
147  template <size_t... I>
148  std::string vname_(bool full, seq<I...>) const
149  {
150  std::string res = "<" + aut_->vname(full) + ", ";
151  const char* sep = "";
152  using swallow = int[];
153  (void) swallow
154  {
155  (res += sep + std::get<I>(auts_)->vname(full), sep = ", ", 0)...
156  };
157  res += ">";
158  return res;
159  }
160 
163  {
164  return pre_(indices);
165  }
166 
167  template <size_t... I>
169  {
170  // clang 3.4 on top of libstdc++ wants this ctor to be
171  // explicitly called.
172  return state_name_t{(std::get<I>(auts_)->pre())...};
173  }
174 
177  {
178  return post_(indices);
179  }
180 
181  template <size_t... I>
183  {
184  // clang 3.4 on top of libstdc++ wants this ctor to be
185  // explicitly called.
186  return state_name_t{(std::get<I>(auts_)->post())...};
187  }
188 
196  {
197  auto lb = pmap_.lower_bound(state);
198  if (lb == pmap_.end() || pmap_.key_comp()(state, lb->first))
199  {
200  lb = pmap_.emplace_hint(lb, state, aut_->new_state());
201  todo_.emplace_back(state);
202  }
203  return lb->second;
204  }
205 
207  {
208  return state(std::make_tuple(ss...));
209  }
210 
211  template <size_t... I>
212  std::ostream&
213  print_state_name_(typename super_t::state_t s, std::ostream& o,
214  const std::string& fmt,
215  seq<I...>) const
216  {
217  auto i = origins().find(s);
218  if (i == std::end(origins()))
219  this->print_state(s, o);
220  else
221  {
222  const char* sep = "";
223  using swallow = int[];
224  (void) swallow
225  {
226  (o << sep,
227  std::get<I>(auts_)->print_state_name(std::get<I>(i->second),
228  o, fmt, true),
229  sep = ", ",
230  0)...
231  };
232  }
233  return o;
234  }
235 
238 
240  using map = std::map<state_name_t, state_t>;
242 
244  std::deque<state_name_t> todo_;
245 
247  };
248  }
249 
251  template <typename... Auts>
252  using tuple_automaton
253  = std::shared_ptr<detail::tuple_automaton_impl<Auts...>>;
254 
255  template <typename... Auts>
256  inline
257  auto
258  make_tuple_automaton(const Auts&... auts)
259  -> tuple_automaton<Auts...>
260  {
261  using res_t = tuple_automaton<Auts...>;
262  return make_shared_ptr<res_t>(auts...);
263  }
264 }
265 
266 #endif // !VCSN_CORE_TUPLE_AUTOMATON_HH
state_t state(state_t_of< Auts >...ss)
bool state_has_name(typename super_t::state_t s) const
std::tuple< state_t_of< Auts >...> state_name_t
State names: Tuple of states of input automata.
std::map< state_t, state_name_t > origins_t
A map from result state to tuple of original states.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
base_t< typename std::tuple_element< I, automata_t >::type > input_automaton_t
The type of the Ith input automaton, unqualified.
state_name_t post_() const
The name of the post of the output automaton.
const origins_t & origins() const
A map from result state to tuple of original states.
state_t state(state_name_t state)
The state in the product corresponding to a pair of states of operands.
auto make_tuple_automaton(const Auts &...auts) -> tuple_automaton< Auts...>
tuple_automaton_impl(const automaton_t &aut, const Auts &...auts)
typename context_t::weightset_t weightset_t
std::ostream & print_state_name(typename super_t::state_t s, std::ostream &o, const std::string &fmt="text", bool delimit=false) const
std::string sname()
Definition: name.hh:31
state_t_of< automaton_t > state_t
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
std::deque< state_name_t > todo_
Worklist of state tuples.
typename context_t::labelset_t labelset_t
An automaton whose states are tuples of states of automata.
Aggregate an automaton, and forward calls to it.
static std::string sname_()
The sname of the sub automata.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
state_name_t pre_() const
The name of the pre of the output automaton.
std::string vname(bool full=true) const
std::string vname_(bool full, seq< I...>) const
typename weightset_t::value_t weight_t
state_name_t post_(seq< I...>) const
std::map< state_name_t, state_t > map
Map state-tuple -> result-state.
state_name_t pre_(seq< I...>) const
static constexpr indices_t indices
std::string vname_(bool full=true) const
The vname of the sub automata.
static constexpr auto pre(Args &&...args) -> decltype(automaton_t::element_type::pre(std::forward< Args >(args)...))
std::ostream & print_state_name_(typename super_t::state_t s, std::ostream &o, const std::string &fmt, seq< I...>) const
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
std::shared_ptr< detail::tuple_automaton_impl< Auts...>> tuple_automaton
A product automaton as a shared pointer.
typename std::remove_cv< typename std::remove_reference< T >::type >::type base_t
T without reference or const/volatile qualifiers.
Definition: traits.hh:12
std::tuple< Auts...> automata_t
The type of input automata.
automata_t auts_
Input automata, supplied at construction time.
auto print_state(Args &&...args) const -> decltype(aut_-> print_state(std::forward< Args >(args)...))
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:35
static constexpr auto post(Args &&...args) -> decltype(automaton_t::element_type::post(std::forward< Args >(args)...))
Aut automaton_t
The type of automaton to wrap.
automaton_t aut_
The wrapped automaton, possibly const.