Vcsn  2.1
Be Rational
char.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cassert>
4 #include <cstring> // strchr
5 #include <string>
6 #include <iostream>
7 
8 #include <vcsn/misc/escape.hh>
9 #include <vcsn/misc/format.hh>
10 #include <vcsn/misc/raise.hh>
11 #include <vcsn/misc/stream.hh>
12 #include <vcsn/misc/symbol.hh>
13 
14 namespace vcsn
15 {
18  {
19  public:
20  using letter_t = char;
21  using word_t = std::string;
22 
23  static symbol sname()
24  {
25  static symbol res("char_letters");
26  return res;
27  }
28 
30  word_t
31  to_word(const letter_t l) const
32  {
33  return {l};
34  }
35 
37  const word_t&
38  to_word(const word_t& l) const
39  {
40  return l;
41  }
42 
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 {l};
53  }
54  else if (r == one_letter())
55  return {l};
56  else
57  return {l, r};
58  }
59 
61  word_t
62  mul(const word_t& l, const letter_t r) const
63  {
64  return r == one_letter() ? l : l + r;
65  }
66 
68  word_t
69  mul(const letter_t l, const word_t& r) const
70  {
71  return l == one_letter() ? r : l + r;
72  }
73 
75  word_t
76  mul(const word_t& l, const word_t& r) const
77  {
78  return l + r;
79  }
80 
82  word_t delimit(const word_t& w) const
83  {
84  return mul(mul(special_letter(), w), special_letter());
85  }
86 
88  word_t undelimit(const word_t& w) const
89  {
90  size_t s = w.size();
91  assert(2 <= s);
92  assert(w[0] == special_letter());
93  assert(w[s-1] == special_letter());
94  return w.substr(1, s-2);
95  }
96 
98  static word_t
100  {
101  return {};
102  }
103 
105  static bool
107  {
108  return w.empty();
109  }
110 
112  word_t
113  transpose(const word_t& w) const
114  {
115  // C++11 lacks std::rbegin/rend...
116  return {w.rbegin(), w.rend()};
117  }
118 
120  letter_t
122  {
123  return l;
124  }
125 
127  static bool equal(const letter_t l, const letter_t r)
128  {
129  return l == r;
130  }
131 
133  static bool equal(const word_t& l, const word_t& r)
134  {
135  return l == r;
136  }
137 
139  static bool less(const letter_t l, const letter_t r)
140  {
141  // Be sure to convert the whole 8-bit spectrum.
142  return uint8_t(l) < uint8_t(r);
143  }
144 
146  static bool less(const word_t& l, const word_t& r)
147  {
148  // FIXME: do we need an unsigned comparison?
149  return l < r;
150  }
151 
153  bool is_letter(const letter_t) const
154  {
155  return true;
156  }
157 
159  bool is_letter(const word_t& w) const
160  {
161  return w.size() == 1;
162  }
163 
166  static constexpr letter_t one_letter() { return 0; }
167 
168  private:
176  static constexpr letter_t special_letter() { return -1; }
177 
178  public:
182  static letter_t get_letter(std::istream& i, bool quoted = true)
183  {
184  letter_t res = i.peek();
185  if (quoted && res == '\'')
186  {
187  eat(i, '\'');
188  res = get_char(i);
189  eat(i, '\'');
190  }
191  else
192  res = get_char(i);
193  return res;
194  }
195 
197  std::ostream&
198  print(const letter_t l, std::ostream& o, format fmt = {}) const
199  {
200  if (l == one_letter() || l == special_letter())
201  {}
202  else if (fmt == format::raw)
203  o << l;
204  else if (l == '\\')
205  o << (fmt == format::latex ? "\\backslash{}" : "\\\\");
206  else if (l == '|' || l == '\'' || l == ','
207  || l == '[' || l == ']'
208  || l == '<' || l == '>')
209  o << '\\' << l;
210  else
211  o << l;
212  return o;
213  }
214 
216  std::ostream&
217  print(const word_t& w, std::ostream& o, format fmt = {}) const
218  {
219  size_t s = w.size();
220 
221  if (s == 0
222  || (s == 1 && w[0] == one_letter()))
223  o << "\\e";
224  else if (s == 1 && w[0] == special_letter())
225  o << '$';
226  else if (fmt == format::raw)
227  o << w;
228  else
229  {
230  if (fmt == format::latex)
231  o << "\\mathit{";
232  o << str_escape(w);
233  if (fmt == format::latex)
234  o << '}';
235  }
236  return o;
237  }
238 
241  template <typename T = letter_t>
242  static T special();
243  };
244 
245  template <>
246  inline
248  char_letters::special<char_letters::letter_t>()
249  {
250  return special_letter();
251  }
252 
253  template <>
254  inline
256  char_letters::special<char_letters::word_t>()
257  {
258  return {special_letter()};
259  }
260 
261 }
word_t mul(const word_t &l, const letter_t r) const
Concatenation.
Definition: char.hh:62
std::ostream & str_escape(std::ostream &os, const std::string &str)
Output a string, escaping special characters.
Definition: escape.cc:43
std::ostream & print(const word_t &w, std::ostream &o, format fmt={}) const
Print a word.
Definition: char.hh:217
letter_t transpose(letter_t l) const
Mirror label.
Definition: char.hh:121
static bool equal(const letter_t l, const letter_t r)
Whether l == r.
Definition: char.hh:127
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
static bool less(const letter_t l, const letter_t r)
Whether l < r.
Definition: char.hh:139
static word_t empty_word()
One.
Definition: char.hh:99
char get_char(std::istream &i)
Read a single char, with possible -escape support.
Definition: stream.hh:78
word_t undelimit(const word_t &w) const
Remove first and last characters, that must be "special".
Definition: char.hh:88
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:37
word_t mul(const word_t &l, const word_t &r) const
Concatenation.
Definition: char.hh:76
bool is_letter(const letter_t) const
Whether is a letter.
Definition: char.hh:153
const word_t & to_word(const word_t &l) const
Convert to word.
Definition: char.hh:38
word_t to_word(const letter_t l) const
Convert to word.
Definition: char.hh:31
static bool less(const word_t &l, const word_t &r)
Whether l < r.
Definition: char.hh:146
bool is_letter(const word_t &w) const
Whether is a single-letter word.
Definition: char.hh:159
Print as is. For instance, don't try to escape labels.
Definition: format.hh:22
std::string word_t
Definition: char.hh:21
word_t mul(const letter_t l, const word_t &r) const
Concatenation.
Definition: char.hh:69
static constexpr letter_t special_letter()
The reserved letter used to forge the labels for initial and final transitions.
Definition: char.hh:176
An input/output format.
Definition: format.hh:11
static T special()
Special character, used to label transitions from pre() and to post().
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
word_t transpose(const word_t &w) const
Mirror label.
Definition: char.hh:113
Represent alphabets whose "letters" are plain chars.
Definition: char.hh:17
word_t mul(const letter_t l, const letter_t r) const
Concatenation.
Definition: char.hh:45
static symbol sname()
Definition: char.hh:23
static bool is_empty_word(const word_t &w)
Whether is one.
Definition: char.hh:106
std::ostream & print(const letter_t l, std::ostream &o, format fmt={}) const
Print a letter.
Definition: char.hh:198
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
static letter_t get_letter(std::istream &i, bool quoted=true)
Read one letter from i.
Definition: char.hh:182
word_t delimit(const word_t &w) const
Add the special character first and last.
Definition: char.hh:82
static bool equal(const word_t &l, const word_t &r)
Whether l == r.
Definition: char.hh:133
static constexpr letter_t one_letter()
The reserved letter used to forge the "one" label (the unit, the identity).
Definition: char.hh:166