Vcsn  2.4
Be Rational
string.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cassert>
4 #include <string>
5 #include <iostream>
6 
7 #include <vcsn/misc/escape.hh>
8 #include <vcsn/misc/format.hh>
9 #include <vcsn/misc/raise.hh>
10 #include <vcsn/misc/symbol.hh>
11 
12 namespace vcsn
13 {
21  {
22  public:
24  using letter_t = symbol;
25  using word_t = std::vector<letter_t>;
26 
27  static symbol sname()
28  {
29  static auto res = symbol{"string_letters"};
30  return res;
31  }
32 
33  word_t
34  to_word(const letter_t l) const
35  {
36  return {l};
37  }
38 
39  const word_t&
40  to_word(const word_t& l) const
41  {
42  return l;
43  }
44 
45  word_t
46  mul(const letter_t l, const letter_t r) const
47  {
48  if (l == one_letter())
49  {
50  if (r == one_letter())
51  return {};
52  else
53  return {r};
54  }
55  else if (r == one_letter())
56  return {l};
57  else
58  return {l, r};
59  }
60 
61  word_t
62  mul(const word_t& l, const letter_t r) const
63  {
64  if (r == one_letter())
65  return l;
66  else
67  {
68  word_t res;
69  res.reserve(l.size() + 1);
70  res.insert(end(res), begin(l), end(l));
71  res.insert(end(res), r);
72  return res;
73  }
74  }
75 
76  word_t
77  mul(const letter_t l, const word_t& r) const
78  {
79  if (l == one_letter())
80  return r;
81  else
82  {
83  word_t res;
84  res.reserve(1 + r.size());
85  res.insert(end(res), l);
86  res.insert(end(res), begin(r), end(r));
87  return res;
88  }
89  }
90 
91  word_t
92  mul(const word_t& l, const word_t& r) const
93  {
94  if (is_empty_word(l))
95  return r;
96  else if (is_empty_word(r))
97  return l;
98  else
99  {
100  word_t res;
101  res.reserve(l.size() + r.size());
102  res.insert(end(res), begin(l), end(l));
103  res.insert(end(res), begin(r), end(r));
104  return res;
105  }
106  }
107 
109  word_t delimit(const word_t& w) const
110  {
111  return mul(mul(special_letter(), w), special_letter());
112  }
113 
115  word_t undelimit(const word_t& w) const
116  {
117  size_t s = w.size();
118  assert(2 <= s);
119  assert(w[0] == special_letter());
120  assert(w[s-1] == special_letter());
121  return {begin(w) + 1, begin(w) + (s - 1)};
122  }
123 
124  static word_t
126  {
127  return {};
128  }
129 
130  static bool
132  {
133  return w.empty();
134  }
135 
136  word_t
137  transpose(const word_t& w) const
138  {
139  // C++11 lacks std::rbegin/rend...
140  return {w.rbegin(), w.rend()};
141  }
142 
143  letter_t
145  {
146  return l;
147  }
148 
150  static bool equal(const letter_t l, const letter_t r)
151  {
152  return l == r;
153  }
154 
156  static bool equal(const word_t& l, const word_t& r)
157  {
158  return l == r;
159  }
160 
162  static bool less(const letter_t l, const letter_t r)
163  {
164  return l < r;
165  }
166 
168  static bool less(const word_t& l, const word_t& r)
169  {
170  return l < r;
171  }
172 
173  bool
174  is_letter(const letter_t) const
175  {
176  return true;
177  }
178 
179  bool
180  is_letter(const word_t& w) const
181  {
182  return w.size() == 1;
183  }
184 
187  static letter_t one_letter() { return letter_t(""); }
188 
189  private:
194  static letter_t special_letter() { return letter_t{std::string{char(0)}}; }
195 
196  public:
200  static letter_t get_letter(std::istream& i, bool quoted = true)
201  {
202  std::string res;
203  if (quoted)
204  {
205  int c = i.peek();
206  if (c == '\'')
207  {
208  i.ignore();
209  while (true)
210  {
211  c = i.peek();
212  if (c == EOF)
213  raise(sname(), ": get_letter: invalid end-of-file");
214  else if (c == '\'')
215  {
216  i.ignore();
217  break;
218  }
219  else
220  res += get_char(i);
221  }
222  }
223  else
224  res = std::string{get_char(i)};
225  }
226  else
227  res = std::string{std::istreambuf_iterator<char>(i), {}};
228  return letter_t{res};
229  }
230 
231  std::ostream&
232  print(const letter_t l, std::ostream& o, const format& fmt = {}) const
233  {
234  if (l == one_letter() || l == special_letter())
235  {}
236  else
237  switch (fmt.kind())
238  {
239  case format::latex:
240  o << "`\\mathit{" << l << "}\\textrm{'}";
241  break;
242 
243  case format::sname:
244  case format::text:
245  case format::utf8:
246  if (l.get().size() == 1)
247  str_escape(o, l, "|',[-]<>");
248  else
249  o << '\'' << l << '\'';
250  break;
251 
252  raw:
253  case format::raw:
254  o << l;
255  break;
256  }
257  return o;
258  }
259 
260  std::ostream&
261  print(const word_t& w, std::ostream& o, const format& fmt = {}) const
262  {
263  for (auto l: w)
264  print(l, o, fmt);
265  return o;
266  }
267 
270  template <typename T = letter_t>
271  static T special();
272  };
273 
274  template <>
275  inline
277  string_letters::special<string_letters::letter_t>()
278  {
279  return special_letter();
280  }
281 
282  template <>
283  inline
285  string_letters::special<string_letters::word_t>()
286  {
287  return {special_letter()};
288  }
289 }
static bool less(const word_t &l, const word_t &r)
Whether l < r.
Definition: string.hh:168
static letter_t one_letter()
The reserved letter used to forge the "one" label (the unit, the identity).
Definition: string.hh:187
Print as is. For instance, don't try to escape labels.
Definition: format.hh:24
static letter_t special_letter()
The reserved letter used to forge the labels for initial and final transitions.
Definition: string.hh:194
bool is_letter(const letter_t) const
Definition: string.hh:174
Print as a parsable type string.
Definition: format.hh:26
return res
Definition: multiply.hh:398
static bool less(const letter_t l, const letter_t r)
Whether l < r.
Definition: string.hh:162
Print for LaTeX.
Definition: format.hh:22
static symbol sname()
Definition: string.hh:27
std::vector< letter_t > word_t
Definition: string.hh:25
word_t to_word(const letter_t l) const
Definition: string.hh:34
static word_t empty_word()
Definition: string.hh:125
word_t mul(const letter_t l, const letter_t r) const
Definition: string.hh:46
word_t delimit(const word_t &w) const
Add the special character first and last.
Definition: string.hh:109
An input/output format for valuesets.
Definition: format.hh:13
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
word_t mul(const word_t &l, const letter_t r) const
Definition: string.hh:62
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
std::ostream & print(const letter_t l, std::ostream &o, const format &fmt={}) const
Definition: string.hh:232
word_t mul(const letter_t l, const word_t &r) const
Definition: string.hh:77
Represent alphabets whose "letters" are strings.
Definition: string.hh:20
Definition: a-star.hh:8
bool is_letter(const word_t &w) const
Definition: string.hh:180
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
const word_t & to_word(const word_t &l) const
Definition: string.hh:40
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
static bool equal(const letter_t l, const letter_t r)
Whether l == r.
Definition: string.hh:150
symbol letter_t
Internalize the letters to save trees.
Definition: string.hh:24
char get_char(std::istream &i)
Read a single char, with possible -escape support.
Definition: stream.cc:37
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
Definition: escape.cc:51
static bool is_empty_word(const word_t &w)
Definition: string.hh:131
letter_t transpose(letter_t l) const
Definition: string.hh:144
static letter_t get_letter(std::istream &i, bool quoted=true)
Read one letter from i.
Definition: string.hh:200
static T special()
Special character, used to label transitions from pre() and to post().
word_t mul(const word_t &l, const word_t &r) const
Definition: string.hh:92
word_t undelimit(const word_t &w) const
Remove first and last characters, that must be "special".
Definition: string.hh:115
static bool equal(const word_t &l, const word_t &r)
Whether l == r.
Definition: string.hh:156
std::ostream & print(const word_t &w, std::ostream &o, const format &fmt={}) const
Definition: string.hh:261
word_t transpose(const word_t &w) const
Definition: string.hh:137