Vcsn  2.8
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/functional.hh> // vcsn::lexicographical_cmp
10 #include <vcsn/misc/raise.hh>
11 #include <vcsn/misc/symbol.hh>
12 
13 namespace vcsn
14 {
22  {
23  public:
26  using letter_t = symbol;
27  using word_t = std::vector<letter_t>;
28 
29  static symbol sname()
30  {
31  static auto res = symbol{"string_letters"};
32  return res;
33  }
34 
35  word_t
36  to_word(const letter_t l) const
37  {
38  return {l};
39  }
40 
41  const word_t&
42  to_word(const word_t& l) const
43  {
44  return l;
45  }
46 
47  word_t
48  mul(const letter_t l, const letter_t r) const
49  {
50  if (l == one_letter())
51  {
52  if (r == one_letter())
53  return {};
54  else
55  return {r};
56  }
57  else if (r == one_letter())
58  return {l};
59  else
60  return {l, r};
61  }
62 
63  word_t
64  mul(const word_t& l, const letter_t r) const
65  {
66  if (r == one_letter())
67  return l;
68  else
69  {
70  word_t res;
71  res.reserve(l.size() + 1);
72  res.insert(end(res), begin(l), end(l));
73  res.insert(end(res), r);
74  return res;
75  }
76  }
77 
78  word_t
79  mul(const letter_t l, const word_t& r) const
80  {
81  if (l == one_letter())
82  return r;
83  else
84  {
85  word_t res;
86  res.reserve(1 + r.size());
87  res.insert(end(res), l);
88  res.insert(end(res), begin(r), end(r));
89  return res;
90  }
91  }
92 
93  word_t
94  mul(const word_t& l, const word_t& r) const
95  {
96  if (is_empty_word(l))
97  return r;
98  else if (is_empty_word(r))
99  return l;
100  else
101  {
102  word_t res;
103  res.reserve(l.size() + r.size());
104  res.insert(end(res), begin(l), end(l));
105  res.insert(end(res), begin(r), end(r));
106  return res;
107  }
108  }
109 
111  word_t delimit(const word_t& w) const
112  {
113  return mul(mul(special_letter(), w), special_letter());
114  }
115 
117  word_t undelimit(const word_t& w) const
118  {
119  size_t s = w.size();
120  assert(2 <= s);
121  assert(w[0] == special_letter());
122  assert(w[s-1] == special_letter());
123  return {begin(w) + 1, begin(w) + (s - 1)};
124  }
125 
126  static word_t
128  {
129  return {};
130  }
131 
132  static bool
134  {
135  return w.empty();
136  }
137 
138  word_t
139  transpose(const word_t& w) const
140  {
141  // C++11 lacks std::rbegin/rend...
142  return {w.rbegin(), w.rend()};
143  }
144 
145  letter_t
147  {
148  return l;
149  }
150 
152  static int compare(const letter_t l, const letter_t r)
153  {
154  return l.get().compare(r.get());
155  }
156 
158  static int compare(const word_t& l, const word_t& r)
159  {
160  return lexicographical_cmp(l, r,
162  }
163 
165  static bool equal(const letter_t l, const letter_t r)
166  {
167  return l == r;
168  }
169 
171  static bool equal(const word_t& l, const word_t& r)
172  {
173  return l == r;
174  }
175 
177  static bool less(const letter_t l, const letter_t r)
178  {
179  return l < r;
180  }
181 
183  static bool less(const word_t& l, const word_t& r)
184  {
185  return l < r;
186  }
187 
188  bool
189  is_letter(const letter_t) const
190  {
191  return true;
192  }
193 
194  bool
195  is_letter(const word_t& w) const
196  {
197  return w.size() == 1;
198  }
199 
202  static letter_t one_letter() { return letter_t(""); }
203 
204  private:
209  static letter_t special_letter() { return letter_t{std::string{char(0)}}; }
210 
211  public:
215  static letter_t get_letter(std::istream& i, bool quoted = true)
216  {
217  std::string res;
218  if (quoted)
219  {
220  int c = i.peek();
221  if (c == '\'')
222  {
223  i.ignore();
224  while (true)
225  {
226  c = i.peek();
227  if (c == EOF)
228  raise(sname(), ": get_letter: invalid end-of-file");
229  else if (c == '\'')
230  {
231  i.ignore();
232  break;
233  }
234  else
235  res += get_char(i);
236  }
237  }
238  else
239  res = std::string{get_char(i)};
240  }
241  else
242  res = std::string{std::istreambuf_iterator<char>(i), {}};
243  return letter_t{res};
244  }
245 
246  std::ostream&
247  print(const letter_t l, std::ostream& o, const format& fmt = {}) const
248  {
249  if (l == one_letter() || l == special_letter())
250  {}
251  else
252  switch (fmt.kind())
253  {
254  case format::latex:
255  o << "`\\mathit{" << l << "}\\textrm{'}";
256  break;
257 
258  case format::sname:
259  case format::text:
260  case format::utf8:
261  if (l.get().size() == 1)
262  str_escape(o, l, "|',[-]<>");
263  else
264  o << '\'' << l << '\'';
265  break;
266 
267  raw:
268  case format::raw:
269  o << l;
270  break;
271  }
272  return o;
273  }
274 
275  std::ostream&
276  print(const word_t& w, std::ostream& o, const format& fmt = {}) const
277  {
278  for (auto l: w)
279  print(l, o, fmt);
280  return o;
281  }
282 
285  template <typename T = letter_t>
286  static T special();
287  };
288 
289  template <>
290  inline
292  string_letters::special<string_letters::letter_t>()
293  {
294  return special_letter();
295  }
296 
297  template <>
298  inline
300  string_letters::special<string_letters::word_t>()
301  {
302  return {special_letter()};
303  }
304 }
Print as a parsable type string.
Definition: format.hh:26
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
static int compare(const letter_t l, const letter_t r)
Three-way comparison between two letters.
Definition: string.hh:152
int lexicographical_cmp(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp)
Lexicographical three-way comparison between two ranges.
Definition: algorithm.hh:128
static int compare(const word_t &l, const word_t &r)
Three-way comparison between two words.
Definition: string.hh:158
word_t transpose(const word_t &w) const
Definition: string.hh:139
char get_char(std::istream &i)
Read a single char, with possible -escape support.
Definition: stream.cc:92
static bool equal(const letter_t l, const letter_t r)
Whether l == r.
Definition: string.hh:165
static letter_t get_letter(std::istream &i, bool quoted=true)
Read one letter from i.
Definition: string.hh:215
word_t to_word(const letter_t l) const
Definition: string.hh:36
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
Represent alphabets whose "letters" are strings.
Definition: string.hh:21
static T special()
Special character, used to label transitions from pre() and to post().
symbol letter_t
Internalize the letters to save trees.
Definition: string.hh:26
std::ostream & print(const letter_t l, std::ostream &o, const format &fmt={}) const
Definition: string.hh:247
static bool is_empty_word(const word_t &w)
Definition: string.hh:133
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 bool less(const word_t &l, const word_t &r)
Whether l < r.
Definition: string.hh:183
letter_t transpose(letter_t l) const
Definition: string.hh:146
std::vector< letter_t > word_t
Definition: string.hh:27
word_t delimit(const word_t &w) const
Add the special character first and last.
Definition: string.hh:111
static bool less(const letter_t l, const letter_t r)
Whether l < r.
Definition: string.hh:177
Definition: a-star.hh:8
word_t mul(const word_t &l, const letter_t r) const
Definition: string.hh:64
static bool equal(const word_t &l, const word_t &r)
Whether l == r.
Definition: string.hh:171
word_t undelimit(const word_t &w) const
Remove first and last characters, that must be "special".
Definition: string.hh:117
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
static symbol sname()
Definition: string.hh:29
static letter_t one_letter()
The reserved letter used to forge the "one" label (the unit, the identity).
Definition: string.hh:202
const word_t & to_word(const word_t &l) const
Definition: string.hh:42
Print as is. For instance, don&#39;t try to escape labels.
Definition: format.hh:24
word_t mul(const letter_t l, const letter_t r) const
Definition: string.hh:48
Print for LaTeX.
Definition: format.hh:22
static letter_t special_letter()
The reserved letter used to forge the labels for initial and final transitions.
Definition: string.hh:209
word_t mul(const word_t &l, const word_t &r) const
Definition: string.hh:94
Functor to three-way comparison Values of ValueSets.
Definition: functional.hh:11
bool is_letter(const letter_t) const
Definition: string.hh:189
word_t mul(const letter_t l, const word_t &r) const
Definition: string.hh:79
static word_t empty_word()
Definition: string.hh:127
std::ostream & print(const word_t &w, std::ostream &o, const format &fmt={}) const
Definition: string.hh:276
return res
Definition: multiply.hh:399
bool is_letter(const word_t &w) const
Definition: string.hh:195