Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
string.hh
Go to the documentation of this file.
1 #pragma once
2 #undef NDEBUG
3 #include <cassert>
4 #include <string>
5 #include <iostream>
6 
7 #include <vcsn/misc/escape.hh>
8 #include <vcsn/misc/flyweight.hh>
9 
10 namespace vcsn
11 {
19  {
20  public:
22  using letter_t
23  = boost::flyweight<std::string, boost::flyweights::no_tracking>;
24  using word_t = std::vector<letter_t>;
25 
26  static std::string sname()
27  {
28  return "string_letters";
29  }
30 
31  virtual std::string vname(bool = true) const
32  {
33  return sname();
34  }
35 
36  word_t
37  to_word(const letter_t l) const
38  {
39  return {l};
40  }
41 
42  const word_t&
43  to_word(const word_t& l) const
44  {
45  return l;
46  }
47 
48  word_t
49  concat(const letter_t l, const letter_t r) const
50  {
51  if (l == one_letter())
52  {
53  if (r == one_letter())
54  return {};
55  else
56  return {r};
57  }
58  else if (r == one_letter())
59  return {l};
60  else
61  return {l, r};
62  }
63 
64  word_t
65  concat(const word_t& l, const letter_t r) const
66  {
67  if (r == one_letter())
68  return l;
69  else
70  {
71  word_t res;
72  res.reserve(l.size() + 1);
73  res.insert(end(res), begin(l), end(l));
74  res.insert(end(res), r);
75  return res;
76  }
77  }
78 
79  word_t
80  concat(const letter_t l, const word_t& r) const
81  {
82  if (l == one_letter())
83  return r;
84  else
85  {
86  word_t res;
87  res.reserve(1 + r.size());
88  res.insert(end(res), l);
89  res.insert(end(res), begin(r), end(r));
90  return res;
91  }
92  }
93 
94  word_t
95  concat(const word_t& l, const word_t& r) const
96  {
97  if (is_empty_word(l))
98  return r;
99  else if (is_empty_word(r))
100  return l;
101  else
102  {
103  word_t res;
104  res.reserve(l.size() + r.size());
105  res.insert(end(res), begin(l), end(l));
106  res.insert(end(res), begin(r), end(r));
107  return res;
108  }
109  }
110 
112  word_t delimit(const word_t& w) const
113  {
114  return concat(concat(special_letter(), w), special_letter());
115  }
116 
118  word_t undelimit(const word_t& w) const
119  {
120  size_t s = w.size();
121  assert(2 <= s);
122  assert(w[0] == special_letter());
123  assert(w[s-1] == special_letter());
124  return {begin(w) + 1, begin(w) + (s - 1)};
125  }
126 
127  static word_t
129  {
130  return {};
131  }
132 
133  static bool
135  {
136  return w.empty();
137  }
138 
139  word_t
140  transpose(const word_t& w) const
141  {
142  // C++11 lacks std::rbegin/rend...
143  return {w.rbegin(), w.rend()};
144  }
145 
146  letter_t
148  {
149  return l;
150  }
151 
152  bool
153  equals(const letter_t& l1, const letter_t& l2) const
154  {
155  return l1 == l2;
156  }
157 
158  bool
159  equals(const word_t& w1, const word_t& w2) const
160  {
161  return w1 == w2;
162  }
163 
164  bool
165  is_letter(const letter_t&) const
166  {
167  return true;
168  }
169 
170  bool
171  is_letter(const word_t& w) const
172  {
173  return w.size() == 1;
174  }
175 
178  static letter_t one_letter() { return letter_t(""); }
179 
180  private:
185  static letter_t special_letter() { return letter_t{"\xFF"}; }
186 
187  public:
189 
192  static char get_char(std::istream& i)
193  {
194  int res = i.get();
195  if (res == EOF)
196  throw std::domain_error("invalid label: unexpected end-of-file");
197  else if (res == '\\')
198  {
199  res = i.get();
200  if (res == EOF)
201  throw std::domain_error("invalid label: unexpected end-of-file");
202  }
203  return res;
204  }
205 
206 
210  static letter_t get_letter(std::istream& i)
211  {
212  char c = get_char(i);
213  if (c == '\'')
214  {
215  std::string res;
216  while (true)
217  {
218  c = get_char(i);
219  if (c == '\'')
220  break;
221  else
222  res += c;
223  }
224  return letter_t{res};
225  }
226  else
227  return letter_t{c};
228  }
229 
230  std::ostream&
231  print(const letter_t& l, std::ostream& o,
232  const std::string& format = "text") const
233  {
234  if (l == special_letter())
235  o << '$';
236  else if (l == one_letter())
237  o << "ε";
238  else
239  {
240  if (format == "latex")
241  o << "\\mathit{";
242  o << l;
243  if (format == "latex")
244  o << '}';
245  }
246  return o;
247  }
248 
249  std::ostream&
250  print(const word_t& w, std::ostream& o,
251  const std::string& format = "text") const
252  {
253  if (format == "latex")
254  o << "\\mathit{";
255  for (auto l: w)
256  print(l, o, "text");
257  if (format == "latex")
258  o << '}';
259  return o;
260  }
261 
264  template <typename T = letter_t>
265  static T special();
266  };
267 
268  template <>
269  inline
271  string_letters::special<string_letters::letter_t>()
272  {
273  return special_letter();
274  }
275 
276  template <>
277  inline
279  string_letters::special<string_letters::word_t>()
280  {
281  return {special_letter()};
282  }
283 
284 }
std::ostream & print(const letter_t &l, std::ostream &o, const std::string &format="text") const
Definition: string.hh:231
virtual std::string vname(bool=true) const
Definition: string.hh:31
static T special()
Special character, used to label transitions from pre() and to post().
const word_t & to_word(const word_t &l) const
Definition: string.hh:43
boost::flyweight< std::string, boost::flyweights::no_tracking > letter_t
Internalize the letters to save trees.
Definition: string.hh:23
word_t concat(const letter_t l, const word_t &r) const
Definition: string.hh:80
std::ostream & print(const word_t &w, std::ostream &o, const std::string &format="text") const
Definition: string.hh:250
word_t concat(const letter_t l, const letter_t r) const
Definition: string.hh:49
bool equals(const word_t &w1, const word_t &w2) const
Definition: string.hh:159
static char get_char(std::istream &i)
FIXME: coding duplication with char.hh. Move to misc?
Definition: string.hh:192
static letter_t special_letter()
The reserved letter used to forge the labels for initial and final transitions.
Definition: string.hh:185
bool equals(const letter_t &l1, const letter_t &l2) const
Definition: string.hh:153
word_t concat(const word_t &l, const letter_t r) const
Definition: string.hh:65
std::vector< letter_t > word_t
Definition: string.hh:24
static word_t empty_word()
Definition: string.hh:128
static letter_t get_letter(std::istream &i)
Read one letter from i.
Definition: string.hh:210
word_t delimit(const word_t &w) const
Add the special character first and last.
Definition: string.hh:112
word_t undelimit(const word_t &w) const
Remove first and last characters, that must be "special".
Definition: string.hh:118
word_t concat(const word_t &l, const word_t &r) const
Definition: string.hh:95
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
word_t transpose(const word_t &w) const
Definition: string.hh:140
letter_t transpose(letter_t l) const
Definition: string.hh:147
bool is_letter(const letter_t &) const
Definition: string.hh:165
bool is_letter(const word_t &w) const
Definition: string.hh:171
static letter_t one_letter()
The reserved letter used to forge the "one" label (the unit, the identity).
Definition: string.hh:178
word_t to_word(const letter_t l) const
Definition: string.hh:37
static bool is_empty_word(const word_t &w)
Definition: string.hh:134
variadic_mul_mixin< detail::r_impl > r
Definition: fwd.hh:42
static std::string sname()
Definition: string.hh:26
Represent alphabets whose "letters" are strings.
Definition: string.hh:18