Vcsn  2.2a
Be Rational
name-automaton.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <stack>
5 #include <string>
6 #include <vector>
7 
8 #include <vcsn/core/fwd.hh>
10 #include <vcsn/misc/format.hh>
11 #include <vcsn/misc/map.hh>
12 #include <vcsn/misc/symbol.hh>
14 
15 //# define DEBUG 1
16 
17 #if DEBUG
18 # define DEBUG_IFELSE(Then, Else) Then
19 #else
20 # define DEBUG_IFELSE(Then, Else) Else
21 #endif
22 
23 #define DEBUG_IF(Then) DEBUG_IFELSE(Then,)
24 
25 namespace vcsn
26 {
27  namespace detail
28  {
30  template <Automaton Aut>
31  class name_automaton_impl
32  : public automaton_decorator<Aut>
33  {
34  public:
35  using automaton_t = Aut;
42 
44  : super_t(ctx)
45  {}
46 
48  static symbol sname()
49  {
50  static auto res = symbol{"name_automaton<"
52  return res;
53  }
54 
55  std::ostream& print_set(std::ostream& o, format fmt = {}) const
56  {
57  o << "name_automaton<";
58  super_t::print_set(o, fmt);
59  return o << '>';
60  }
61 
63  using smap = std::unordered_map<state_name_t, state_t>;
64 
67  state_t state(const state_name_t& r, state_t s)
68  {
69  map_[r] = s;
70  return s;
71  }
72 
75  state_t state(const state_name_t& r)
76  {
77  // Benches show that the map_.emplace technique is slower, and
78  // then that operator[] is faster than emplace.
79  state_t res;
80  auto i = map_.find(r);
81  if (i == std::end(map_))
82  res = state(r, super_t::new_state());
83  else
84  res = i->second;
85  return res;
86  }
87 
88  using super_t::add_transition;
89  void
90  add_transition(state_t src, state_name_t dst,
91  label_t l, const weight_t& w)
92  {
93  super_t::add_transition(src, state(dst), l, w);
94  }
95 
96  using super_t::new_transition;
97  void
98  new_transition(state_t src, state_name_t dst,
99  label_t l, const weight_t& w)
100  {
101  super_t::new_transition(src, state(dst), l, w);
102  }
103 
104  using super_t::set_initial;
105  void
106  set_initial(state_name_t s, const weight_t& w)
107  {
108  super_t::set_initial(state(s), w);
109  }
110 
111  bool state_has_name(state_t s) const
112  {
113  return has(origins(), s);
114  }
115 
116  std::ostream&
117  print_state_name(state_t s, std::ostream& o,
118  format = {},
119  bool = false) const
120  {
121  auto i = origins().find(s);
122  if (i == std::end(origins()))
123  this->print_state(s, o);
124  else
125  o << i->second;
126  return o;
127  }
128 
130  using origins_t = std::map<state_t, state_name_t>;
131  mutable origins_t origins_;
132  const origins_t&
133  origins() const
134  {
135  if (origins_.empty())
136  for (const auto& p: map_)
137  origins_[p.second] = p.first;
138  return origins_;
139  }
140 
142  smap map_;
143  };
144  }
145 }
symbol sname()
Definition: name.hh:67
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:54
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
static symbol sname()
Static name.
std::ostream & print_set(std::ostream &o, format fmt={}) const
auto print_set(Args &&...args) const -> decltype(aut_-> print_set(std::forward< Args >(args)...))
context_t_of< automaton_t > context_t
name_automaton_impl(const context_t &ctx)
weight_t_of< super_t > weight_t
Aggregate an automaton, and forward calls to it.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:58
An input/output format for valuesets.
Definition: format.hh:11
Definition: a-star.hh:8