DiaDes  0.1
DIAgnosis of Discrete-Event System
Label.hh
Go to the documentation of this file.
1 
9 #ifndef __DIADES__UTILS__LABEL__HH
10 #define __DIADES__UTILS__LABEL__HH
11 #include<iostream>
12 #include<istream>
13 #include<string>
14 #include <locale>
15 #include <algorithm>
18 
19 namespace Diades
20 {
21  namespace Utils
22  {
23 
31  template < typename CharT,
32  typename Traits,
33  typename Alloc>
35  {
36  protected:
37  typedef std::basic_string<CharT, Traits, Alloc> BasicString;
38  private:
39  BasicString _label;
40 
41  public:
42 
43  const BasicString &
44  toString() const
45  {
46  return _label;
47  }
48 
49  bool
50  isNull() const
51  {
52  return _label.empty();
53  }
54 
56  {
57  if(this != &label)
58  {
59  setLabel(label._label);
60  }
61  return *this;
62  }
63 
64  protected:
65 
66  void
67  setLabel(const BasicString & label)
68  {
69  _label = label;
70  }
71 
72  };
73 
80  template < typename CharT, typename Traits, typename Alloc >
81  class QuotedLabel : public GenericLabel<CharT, Traits, Alloc>
82  {
83  public:
84  QuotedLabel() = default;
85  QuotedLabel(const QuotedLabel & label) = default;
86  QuotedLabel(QuotedLabel && label) = default;
87 
88  QuotedLabel(std::basic_istream<CharT> & is) : GenericLabel<CharT, Traits, Alloc>()
89  {
90  checkQuotedLabel(is);
91  }
92 
94  {
96  return *this;
97  }
98 
100  nudeString() const
101  {
103  {
105  }
106  return "";
107  }
108 
109  private:
110 
111  void
112  checkQuotedLabel(std::basic_istream<CharT> & is)
113  {
115  CharT c;
116  is.get(c);
117  int counter = 1;
118  while(std::isspace<CharT>(c, is.getloc()) && is.get(c))
119  {
120  ++counter;
121  }
122 
123  if(c != '\"')
124  {
125  is.seekg(-counter, std::ios_base::cur);
126  return;
127  }
128  label += c;
129  bool stop = false;
130 
131  while(!(stop) && is.get(c))
132  {
133  ++counter;
134  if(c == '\"')
135  {
136  stop = true;
137  label += c;
138  }
139  else
140  {
141  label += c;
142  }
143  }
144  if(label.size() == 1)
145  {
146  is.seekg(-counter, std::ios_base::cur);
147  return;
148  }
149  if(label.back() != '\"')
150  {
151  is.seekg(-counter, std::ios_base::cur);
152  return;
153  }
154 
155  this->setLabel(label);
156  }
157  };
158 
159 
160  template<typename CharT, typename Traits, typename Alloc>
162 
172  template < typename CharT, typename Traits, typename Alloc >
173  class UnquotedLabel : public GenericLabel<CharT, Traits, Alloc>
174  {
175  public:
177 
178  public:
180  using BasicString = typename GL::BasicString;
181  public:
182  UnquotedLabel() = default;
183  UnquotedLabel(const UnquotedLabel & label) = default;
184  UnquotedLabel(UnquotedLabel && label) = default;
185 
186  UnquotedLabel(const BasicString & s) : GL()
187  {
188  checkUnquotedLabel(s);
189  }
190 
191  UnquotedLabel(std::basic_istream<CharT> & is) : GL()
192  {
193  checkUnquotedLabel(is);
194  }
195 
197  {
199  return *this;
200  }
201 
202  private:
203 
204  void
206  {
207  if(std::find_if(s.begin(), s.end(), [&](CharT c) -> bool
208  {
209  return c == ' ';
210  }) == s.end())
211  {
212 
213  std::basic_stringstream<CharT> stream;
214  stream << s;
215 
216  checkUnquotedLabel(stream);
217  }
218  }
219 
220  void
221  checkUnquotedLabel(std::basic_istream<CharT> & is)
222  {
224  CharT c;
225  is.get(c);
226  //std::cout << "reading first character '" << c << "'\n";
227  int counter = 1;
228  while(std::isspace<CharT>(c, is.getloc()) && is.get(c))
229  {
230  //std::cout << "is a space, reading a new one '" << c << "'\n";
231  ++counter;
232  }
233  //std::cout << "'" << c << "' is not a space\n";
234  if(!(std::isalpha(c) || c == '_'))
235  {
236  //std::cout << "'" << c << "' is neither alpha nor _, give up\n";
237  is.seekg(-counter, std::ios_base::cur);
238  return;
239  }
240  label += c;
241 
242  bool stop = false;
243 
244  while(!(stop) && is.get(c))
245  {
246  ++counter;
247  if(std::isalnum<CharT>(c, is.getloc()) || (c == '_'))
248  {
249  label += c;
250  }
251  else
252  {
253  if(std::isspace<CharT>(c, is.getloc()))
254  {
255  stop = true;
256  is.seekg(-1, std::ios_base::cur);
257  }
258  else
259  {
260  is.seekg(-counter, std::ios_base::cur);
261  return;
262  }
263  }
264  }
265  this->setLabel(label);
266  }
267  };
268 
275  template < typename CharT,
276  typename Traits,
277  typename Alloc>
278  bool
279  readLabel(std::basic_istream<CharT> & stream,
280  std::basic_string<CharT, Traits, Alloc> & label)
281  {
282  UnquotedLabel<CharT, Traits, Alloc> unqLabel(stream);
283  if(unqLabel.isNull())
284  {
285 
286  QuotedLabel<CharT, Traits, Alloc> qLabel(stream);
287  if(qLabel.isNull())
288  {
289 
290  return false;
291  }
292  else
293  {
294 
295  /* quoted label
296  * consists of a character string starting with a
297  * double quote and ending with a double quote. Between these two
298  * double quotes, there can be zero, one or many printable
299  * characters; the meaning of "printable" is given by the POSIX
300  * isprint() function with locale "C" (namely, ASCII characters
301  * with decimal codes in the range from 32 to 126, bounds included).
302  * No other assumption should be made about the characters present
303  * between these two double quotes. In particular, the double quote
304  * character itself may be present, and may not necessarily be
305  * "escaped" in some way (e.g., preceded by a backslash, as in C).
306  */
307 
308  label = qLabel.nudeString();
309 
310  }
311  }
312  else
313  {
314 
315  /* unquoted label
316  * consists of a character string starting with a
317  * letter, and followed by zero, one, or many letters, digits, or
318  * underscore characters.
319  */
320  label = unqLabel.toString();
321 
322  }
323  return true;
324  }
325 
326 
327 
328 
329 
334 
335 
336 
343  template<typename CharT, typename Traits, typename Alloc>
344  class
346  {
347  public:
348 
351 
352  private:
353  const std::array<CharT, 26>
354  _characters = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
357 
358 
359  public:
360 
361 
365  LabelGenerator() = default;
366 
367 
372  LabelGenerator(LabelGenerator const& other) = default;
378  LabelGenerator& operator=(LabelGenerator const& other) = default;
383  LabelGenerator(LabelGenerator && other) = default;
389  LabelGenerator& operator=(LabelGenerator && other) = default;
390 
394  virtual ~LabelGenerator() = default;
395 
401  LabelGenerator(const Label & prefix) : Gen(), _enumerator(), _prefix(prefix)
402  {
403  init();
404  };
405 
410  void init()
411  {
412  _enumerator.setup({0},
413  {
414  _characters.size()
415  });
416  _enumerator.start();
417  }
418 
424  {
425  Label result = getLabel();
426  if(!_enumerator.hasNext())
427  {
428  std::vector<size_t> start(_enumerator.current().size() + 1);
429  std::vector<size_t> last(_enumerator.current().size() + 1);
430  std::fill(start.begin(), start.end(), 0);
431  std::fill(last.begin(), last.end(), _characters.size());
432  _enumerator.setup(std::move(start), std::move(last));
433  _enumerator.start();
434  }
435  return result;
436  }
437 
438  private:
439 
445  {
446  Label result;
447  typename Label::BasicString configuration;
448  std::for_each(_enumerator.current().rbegin(), _enumerator.current().rend(),
449  [&](size_t i)
450  {
451  configuration += _characters[i];
452  });
453  result.setLabel(_prefix.toString() + configuration);
454  return result;
455  }
456 
457 
458 
459  };
460 
461 
464  }
465 }
466 
467 
468 #endif /* LABEL_HH */
469 
std::basic_string< CharT, Traits, Alloc > BasicString
Definition: Label.hh:37
void checkUnquotedLabel(const BasicString &s)
Definition: Label.hh:205
QuotedLabel & operator=(const QuotedLabel &label)
Definition: Label.hh:93
Diades::Utils::RangesEnumeration< size_t > _enumerator
Definition: Label.hh:355
QuotedLabel< wchar_t, std::char_traits< wchar_t >, std::allocator< wchar_t > > QuotedWideStringLabel
Definition: Label.hh:333
UnquotedLabel< char, std::char_traits< char >, std::allocator< char > > UnquotedStringLabel
Definition: Label.hh:330
LabelGenerator< char, std::char_traits< char >, std::allocator< char > > UnquotedStringLabelGenerator
Definition: Label.hh:462
QuotedLabel(std::basic_istream< CharT > &is)
Definition: Label.hh:88
UnquotedLabel(std::basic_istream< CharT > &is)
Definition: Label.hh:191
const BasicString & toString() const
Definition: Label.hh:44
LabelGenerator< wchar_t, std::char_traits< wchar_t >, std::allocator< wchar_t > > UnquotedWideStringLabelGenerator
Definition: Label.hh:463
UnquotedLabel & operator=(const UnquotedLabel &label)
Definition: Label.hh:196
Definition: Run.cc:88
LabelGenerator(const Label &prefix)
Definition: Label.hh:401
GenericLabel & operator=(const GenericLabel &label)
Definition: Label.hh:55
bool readLabel(std::basic_istream< CharT > &stream, std::basic_string< CharT, Traits, Alloc > &label)
Definition: Label.hh:279
QuotedLabel< char, std::char_traits< char >, std::allocator< char > > QuotedStringLabel
Definition: Label.hh:332
Namespace of the Diades project.
void setup(std::vector< T > &&start, const std::vector< T > &&end)
Definition: Enumerators.hh:81
GenericLabel< CharT, Traits, Alloc >::BasicString nudeString() const
Definition: Label.hh:100
UnquotedLabel(const BasicString &s)
Definition: Label.hh:186
bool isNull() const
Definition: Label.hh:50
void checkUnquotedLabel(std::basic_istream< CharT > &is)
Definition: Label.hh:221
UnquotedLabel< wchar_t, std::char_traits< wchar_t >, std::allocator< wchar_t > > UnquotedWideStringLabel
Definition: Label.hh:331
void checkQuotedLabel(std::basic_istream< CharT > &is)
Definition: Label.hh:112
const std::vector< T > & current() const
Definition: Enumerators.hh:107
void setLabel(const BasicString &label)
Definition: Label.hh:67
typename GL::BasicString BasicString
Definition: Label.hh:180