Vcsn  2.2
Be Rational
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/format.hh>
9 #include <vcsn/misc/symbol.hh>
10 
11 namespace vcsn
12 {
20  {
21  public:
23  using letter_t = symbol;
24  using word_t = std::vector<letter_t>;
25 
26  static symbol sname()
27  {
28  static auto res = symbol{"string_letters"};
29  return res;
30  }
31 
32  word_t
33  to_word(const letter_t l) const
34  {
35  return {l};
36  }
37 
38  const word_t&
39  to_word(const word_t& l) const
40  {
41  return l;
42  }
43 
44  word_t
45  mul(const letter_t l, const letter_t r) const
46  {
47  if (l == one_letter())
48  {
49  if (r == one_letter())
50  return {};
51  else
52  return {r};
53  }
54  else if (r == one_letter())
55  return {l};
56  else
57  return {l, r};
58  }
59 
60  word_t
61  mul(const word_t& l, const letter_t r) const
62  {
63  if (r == one_letter())
64  return l;
65  else
66  {
67  word_t res;
68  res.reserve(l.size() + 1);
69  res.insert(end(res), begin(l), end(l));
70  res.insert(end(res), r);
71  return res;
72  }
73  }
74 
75  word_t
76  mul(const letter_t l, const word_t& r) const
77  {
78  if (l == one_letter())
79  return r;
80  else
81  {
82  word_t res;
83  res.reserve(1 + r.size());
84  res.insert(end(res), l);
85  res.insert(end(res), begin(r), end(r));
86  return res;
87  }
88  }
89 
90  word_t
91  mul(const word_t& l, const word_t& r) const
92  {
93  if (is_empty_word(l))
94  return r;
95  else if (is_empty_word(r))
96  return l;
97  else
98  {
99  word_t res;
100  res.reserve(l.size() + r.size());
101  res.insert(end(res), begin(l), end(l));
102  res.insert(end(res), begin(r), end(r));
103  return res;
104  }
105  }
106 
108  word_t delimit(const word_t& w) const
109  {
110  return mul(mul(special_letter(), w), special_letter());
111  }
112 
114  word_t undelimit(const word_t& w) const
115  {
116  size_t s = w.size();
117  assert(2 <= s);
118  assert(w[0] == special_letter());
119  assert(w[s-1] == special_letter());
120  return {begin(w) + 1, begin(w) + (s - 1)};
121  }
122 
123  static word_t
125  {
126  return {};
127  }
128 
129  static bool
131  {
132  return w.empty();
133  }
134 
135  word_t
136  transpose(const word_t& w) const
137  {
138  // C++11 lacks std::rbegin/rend...
139  return {w.rbegin(), w.rend()};
140  }
141 
142  letter_t
144  {
145  return l;
146  }
147 
149  static bool equal(const letter_t l, const letter_t r)
150  {
151  return l == r;
152  }
153 
155  static bool equal(const word_t& l, const word_t& r)
156  {
157  return l == r;
158  }
159 
161  static bool less(const letter_t l, const letter_t r)
162  {
163  return l < r;
164  }
165 
167  static bool less(const word_t& l, const word_t& r)
168  {
169  return l < r;
170  }
171 
172  bool
173  is_letter(const letter_t) const
174  {
175  return true;
176  }
177 
178  bool
179  is_letter(const word_t& w) const
180  {
181  return w.size() == 1;
182  }
183 
186  static letter_t one_letter() { return letter_t(""); }
187 
188  private:
193  static letter_t special_letter() { return letter_t{std::string{char(0)}}; }
194 
195  public:
199  static letter_t get_letter(std::istream& i,
200  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 }
bool is_letter(const word_t &w) const
Definition: string.hh:179
letter_t transpose(letter_t l) const
Definition: string.hh:143
Represent alphabets whose "letters" are strings.
Definition: string.hh:19
static letter_t special_letter()
The reserved letter used to forge the labels for initial and final transitions.
Definition: string.hh:193
Print as rich UTF-8 text, escaped.
Definition: format.hh:28
char get_char(std::istream &i)
Read a single char, with possible -escape support.
Definition: stream.hh:78
static word_t empty_word()
Definition: string.hh:124
Definition: a-star.hh:8
static letter_t one_letter()
The reserved letter used to forge the "one" label (the unit, the identity).
Definition: string.hh:186
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
Definition: escape.cc:54
Print for LaTeX.
Definition: format.hh:20
Print as is. For instance, don't try to escape labels.
Definition: format.hh:22
word_t transpose(const word_t &w) const
Definition: string.hh:136
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
An input/output format for valuesets.
Definition: format.hh:11
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
std::ostream & print(const word_t &w, std::ostream &o, const format &fmt={}) const
Definition: string.hh:261
static bool is_empty_word(const word_t &w)
Definition: string.hh:130
symbol letter_t
Internalize the letters to save trees.
Definition: string.hh:23
const word_t & to_word(const word_t &l) const
Definition: string.hh:39
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
Print as plain (ASCII) text, escaped.
Definition: format.hh:26
static bool less(const word_t &l, const word_t &r)
Whether l < r.
Definition: string.hh:167
std::vector< letter_t > word_t
Definition: string.hh:24
word_t delimit(const word_t &w) const
Add the special character first and last.
Definition: string.hh:108
static bool equal(const word_t &l, const word_t &r)
Whether l == r.
Definition: string.hh:155
static T special()
Special character, used to label transitions from pre() and to post().
word_t mul(const word_t &l, const letter_t r) const
Definition: string.hh:61
Print as a parsable type string.
Definition: format.hh:24
static symbol sname()
Definition: string.hh:26
static bool less(const letter_t l, const letter_t r)
Whether l < r.
Definition: string.hh:161
word_t mul(const letter_t l, const letter_t r) const
Definition: string.hh:45
std::ostream & print(const letter_t l, std::ostream &o, const format &fmt={}) const
Definition: string.hh:232
word_t mul(const word_t &l, const word_t &r) const
Definition: string.hh:91
word_t undelimit(const word_t &w) const
Remove first and last characters, that must be "special".
Definition: string.hh:114
word_t mul(const letter_t l, const word_t &r) const
Definition: string.hh:76
static letter_t get_letter(std::istream &i, bool quoted=true)
Read one letter from i.
Definition: string.hh:199
bool is_letter(const letter_t) const
Definition: string.hh:173
word_t to_word(const letter_t l) const
Definition: string.hh:33
static bool equal(const letter_t l, const letter_t r)
Whether l == r.
Definition: string.hh:149