Vcsn  2.8
Be Rational
char.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/stream.hh>
11 #include <vcsn/misc/symbol.hh>
12 
13 namespace vcsn
14 {
17  {
18  public:
19  using letter_t = char;
20  using word_t = std::string;
21 
22  static symbol sname()
23  {
24  static auto res = symbol{"char_letters"};
25  return res;
26  }
27 
29  word_t
30  to_word(const letter_t l) const
31  {
32  return {l};
33  }
34 
36  const word_t&
37  to_word(const word_t& l) const
38  {
39  return l;
40  }
41 
43  word_t
44  mul(const letter_t l, const letter_t r) const
45  {
46  if (l == one_letter())
47  {
48  if (r == one_letter())
49  return {};
50  else
51  return {l};
52  }
53  else if (r == one_letter())
54  return {l};
55  else
56  return {l, r};
57  }
58 
60  word_t
61  mul(const word_t& l, const letter_t r) const
62  {
63  return r == one_letter() ? l : l + r;
64  }
65 
67  word_t
68  mul(const letter_t l, const word_t& r) const
69  {
70  return l == one_letter() ? r : l + r;
71  }
72 
74  word_t
75  mul(const word_t& l, const word_t& r) const
76  {
77  return l + r;
78  }
79 
81  word_t delimit(const word_t& w) const
82  {
83  return mul(mul(special_letter(), w), special_letter());
84  }
85 
87  word_t undelimit(const word_t& w) const
88  {
89  size_t s = w.size();
90  assert(2 <= s);
91  assert(w[0] == special_letter());
92  assert(w[s-1] == special_letter());
93  return w.substr(1, s-2);
94  }
95 
97  static word_t
99  {
100  return {};
101  }
102 
104  static bool
106  {
107  return w.empty();
108  }
109 
111  word_t
112  transpose(const word_t& w) const
113  {
114  // C++11 lacks std::rbegin/rend...
115  return {w.rbegin(), w.rend()};
116  }
117 
119  letter_t
121  {
122  return l;
123  }
124 
126  static int compare(const letter_t l, const letter_t r)
127  {
128  return int(uint8_t(l)) - int(uint8_t(r));
129  }
130 
132  static int compare(const word_t& l, const word_t& r)
133  {
134  return l.compare(r);
135  }
136 
138  static bool equal(const letter_t l, const letter_t r)
139  {
140  return l == r;
141  }
142 
144  static bool equal(const word_t& l, const word_t& r)
145  {
146  return l == r;
147  }
148 
150  static bool less(const letter_t l, const letter_t r)
151  {
152  // Be sure to convert the whole 8-bit spectrum.
153  return uint8_t(l) < uint8_t(r);
154  }
155 
157  static bool less(const word_t& l, const word_t& r)
158  {
159  // FIXME: do we need an unsigned comparison?
160  return l < r;
161  }
162 
164  bool is_letter(const letter_t) const
165  {
166  return true;
167  }
168 
170  bool is_letter(const word_t& w) const
171  {
172  return w.size() == 1;
173  }
174 
177  static constexpr letter_t one_letter() { return 0; }
178 
179  private:
187  static constexpr letter_t special_letter() { return -1; }
188 
189  public:
193  static letter_t get_letter(std::istream& i, bool quoted = true)
194  {
195  letter_t res = i.peek();
196  if (quoted && res == '\'')
197  {
198  eat(i, '\'');
199  res = get_char(i);
200  eat(i, '\'');
201  }
202  else
203  res = get_char(i);
204  return res;
205  }
206 
208  std::ostream&
209  print(const letter_t l, std::ostream& o, format fmt = {}) const
210  {
211  if (l == one_letter() || l == special_letter())
212  {}
213  else
214  switch (fmt.kind())
215  {
216  case format::sname:
217  // Escape dash and parens, which are special when parsed
218  // (actually, only the closing paren is special, but treating
219  // them symmetrically is better looking).
220  //
221  // Of course, escape single-quote and backslash, which are
222  // used to escape.
223  str_escape(o, l, "(-)\\'");
224  break;
225 
226  case format::latex:
227  if (l == '\\')
228  o << "\\backslash{}";
229  else
230  str_escape(o, l, "#{}$");
231  break;
232 
233  case format::raw:
234  o << l;
235  break;
236 
237  case format::text:
238  case format::utf8:
239  if (l == '\\')
240  o << "\\\\";
241  else
242  str_escape(o, l, fmt.meta() ? fmt.meta() : "|',[-]<> ");
243  }
244  return o;
245  }
246 
248  std::ostream&
249  print(const word_t& w, std::ostream& o, format fmt = {}) const
250  {
251  size_t s = w.size();
252 
253  if (s == 0
254  || (s == 1 && w[0] == one_letter()))
255  o << "\\e";
256  else if (s == 1 && w[0] == special_letter())
257  o << '$';
258  else if (fmt == format::raw)
259  o << w;
260  else
261  {
262  if (fmt == format::latex)
263  o << "\\mathit{";
264  for (auto c: w)
265  print(c, o, fmt);
266  if (fmt == format::latex)
267  o << '}';
268  }
269  return o;
270  }
271 
274  template <typename T = letter_t>
275  static T special();
276  };
277 
278  template <>
279  inline
281  char_letters::special<char_letters::letter_t>()
282  {
283  return special_letter();
284  }
285 
286  template <>
287  inline
289  char_letters::special<char_letters::word_t>()
290  {
291  return {special_letter()};
292  }
293 
294 }
std::ostream & print(const word_t &w, std::ostream &o, format fmt={}) const
Print a word.
Definition: char.hh:249
Print as a parsable type string.
Definition: format.hh:26
static constexpr letter_t one_letter()
The reserved letter used to forge the "one" label (the unit, the identity).
Definition: char.hh:177
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
static symbol sname()
Definition: char.hh:22
word_t mul(const word_t &l, const word_t &r) const
Concatenation.
Definition: char.hh:75
char get_char(std::istream &i)
Read a single char, with possible -escape support.
Definition: stream.cc:92
static bool equal(const word_t &l, const word_t &r)
Whether l == r.
Definition: char.hh:144
static bool is_empty_word(const word_t &w)
Whether is one.
Definition: char.hh:105
static constexpr letter_t special_letter()
The reserved letter used to forge the labels for initial and final transitions.
Definition: char.hh:187
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:147
word_t transpose(const word_t &w) const
Mirror label.
Definition: char.hh:112
word_t mul(const letter_t l, const letter_t r) const
Concatenation.
Definition: char.hh:44
static bool equal(const letter_t l, const letter_t r)
Whether l == r.
Definition: char.hh:138
static letter_t get_letter(std::istream &i, bool quoted=true)
Read one letter from i.
Definition: char.hh:193
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
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:21
word_t mul(const word_t &l, const letter_t r) const
Concatenation.
Definition: char.hh:61
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
An input/output format for valuesets.
Definition: format.hh:13
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
static int compare(const letter_t l, const letter_t r)
Three-way comparison between two letters.
Definition: char.hh:126
static T special()
Special character, used to label transitions from pre() and to post().
word_t to_word(const letter_t l) const
Convert to word.
Definition: char.hh:30
word_t delimit(const word_t &w) const
Add the special character first and last.
Definition: char.hh:81
Definition: a-star.hh:8
bool is_letter(const letter_t) const
Whether is a letter.
Definition: char.hh:164
word_t undelimit(const word_t &w) const
Remove first and last characters, that must be "special".
Definition: char.hh:87
std::ostream & print(const letter_t l, std::ostream &o, format fmt={}) const
Print a letter.
Definition: char.hh:209
Represent alphabets whose "letters" are plain chars.
Definition: char.hh:16
std::string word_t
Definition: char.hh:20
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
static bool less(const word_t &l, const word_t &r)
Whether l < r.
Definition: char.hh:157
word_t mul(const letter_t l, const word_t &r) const
Concatenation.
Definition: char.hh:68
bool is_letter(const word_t &w) const
Whether is a single-letter word.
Definition: char.hh:170
Print as is. For instance, don&#39;t try to escape labels.
Definition: format.hh:24
Print for LaTeX.
Definition: format.hh:22
letter_t transpose(letter_t l) const
Mirror label.
Definition: char.hh:120
static word_t empty_word()
One.
Definition: char.hh:98
const word_t & to_word(const word_t &l) const
Convert to word.
Definition: char.hh:37
static bool less(const letter_t l, const letter_t r)
Whether l < r.
Definition: char.hh:150
return res
Definition: multiply.hh:399
static int compare(const word_t &l, const word_t &r)
Three-way comparison between two words.
Definition: char.hh:132