IDL compiler front-end library
Variant.h
Go to the documentation of this file.
1 /*
3 * Nirvana IDL front-end library.
4 *
5 * This is a part of the Nirvana project.
6 *
7 * Author: Igor Popov
8 *
9 * Copyright (c) 2021 Igor Popov.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
23 *
24 * Send comments and/or bug reports to:
25 * popov.nirvana@gmail.com
26 */
27 #ifndef IDLFE_AST_VARIANT_H_
28 #define IDLFE_AST_VARIANT_H_
29 #pragma once
30 
31 #include "Type.h"
32 #include "Fixed.h"
33 #include <forward_list>
34 
35 namespace AST {
36 
37 class EnumItem;
38 class Constant;
39 
41 class Variant
42 {
43 public:
45  enum class VT
46  {
47  EMPTY,
48 
49  BOOLEAN,
50  OCTET,
51  CHAR,
52  WCHAR,
53  USHORT,
54  ULONG,
55  ULONGLONG,
56  SHORT,
57  LONG,
58  LONGLONG,
59  FLOAT,
60  DOUBLE,
61  LONGDOUBLE,
62 
63  STRING,
64  WSTRING,
65  FIXED,
66 
67  ENUM_ITEM,
68  CONSTANT
69  };
70 
72  VT vtype () const noexcept
73  {
74  return type_;
75  }
76 
77  // Integral
78 
81  bool as_bool () const noexcept
82  {
83  assert (vtype () == VT::BOOLEAN);
84  return val_.u.i != 0;
85  }
86 
89  uint8_t as_octet () const noexcept
90  {
91  assert (vtype () == VT::OCTET);
92  return (uint8_t)val_.u.ui;
93  }
94 
97  char as_char () const noexcept
98  {
99  assert (vtype () == VT::CHAR);
100  return (char)val_.u.ui;
101  }
102 
105  wchar_t as_wchar () const noexcept
106  {
107  assert (vtype () == VT::WCHAR);
108  return (wchar_t)val_.u.ui;
109  }
110 
113  uint16_t as_unsigned_short () const noexcept
114  {
115  assert (vtype () == VT::USHORT);
116  return (uint16_t)val_.u.ui;
117  }
118 
121  int16_t as_short () const noexcept
122  {
123  assert (vtype () == VT::SHORT);
124  return (int16_t)val_.u.i;
125  }
126 
129  uint32_t as_unsigned_long () const noexcept
130  {
131  assert (vtype () == VT::ULONG);
132  return (uint32_t)val_.u.ui;
133  }
134 
137  int32_t as_long () const noexcept
138  {
139  assert (vtype () == VT::LONG);
140  return (int32_t)val_.u.i;
141  }
142 
145  uint64_t as_unsigned_long_long () const noexcept
146  {
147  assert (vtype () == VT::ULONGLONG);
148  return val_.u.ui;
149  }
150 
153  int64_t as_long_long () const noexcept
154  {
155  assert (vtype () == VT::LONGLONG);
156  return val_.u.i;
157  }
158 
159  // Floating point
160 
163  float as_float () const noexcept
164  {
165  assert (vtype () == VT::FLOAT);
166  return (float)val_.u.d;
167  }
168 
171  double as_double () const noexcept
172  {
173  assert (vtype () == VT::DOUBLE);
174  return (double)val_.u.d;
175  }
176 
179  long double as_long_double () const noexcept
180  {
181  assert (vtype () == VT::LONGDOUBLE);
182  return val_.u.d;
183  }
184 
185  // String
186 
189  const std::string& as_string () const noexcept
190  {
191  assert (vtype () == VT::STRING);
192  return val_.u.s;
193  }
194 
197  const std::wstring& as_wstring () const noexcept
198  {
199  assert (vtype () == VT::WSTRING);
200  return val_.u.ws;
201  }
202 
205  const EnumItem& as_enum_item () const noexcept
206  {
207  assert (vtype () == VT::ENUM_ITEM);
208  return *val_.u.enum_item;
209  }
210 
213  const Constant& as_constant () const noexcept
214  {
215  assert (vtype () == VT::CONSTANT);
216  return *val_.u.constant;
217  }
218 
219  // Fixed
220 
223  const Fixed& as_Fixed () const noexcept
224  {
225  assert (VT::FIXED == type_);
226  return val_.u.fixed;
227  }
228 
233  std::string to_string () const;
234 
237  bool empty () const noexcept
238  {
239  return vtype () == VT::EMPTY;
240  }
241 
243  const Variant& dereference_const () const noexcept;
244 
247  {
248  clear ();
249  }
250 
252  Variant () :
253  type_ (VT::EMPTY)
254  {}
255 
257  Variant (const Variant& src)
258  {
259  copy (src);
260  }
261 
263  Variant (Variant&& src) noexcept
264  {
265  move (std::move (src));
266  }
267 
269  Variant (bool v) noexcept :
270  type_ (VT::BOOLEAN),
271  val_ ((uint64_t)v)
272  {}
273 
275  Variant (uint8_t v) noexcept :
276  type_ (VT::OCTET),
277  val_ ((uint64_t)v)
278  {}
279 
281  Variant (char v) noexcept :
282  type_ (VT::CHAR),
283  val_ ((uint64_t)v)
284  {}
285 
287  Variant (wchar_t v) noexcept :
288  type_ (VT::WCHAR),
289  val_ ((uint64_t)v)
290  {}
291 
293  Variant (int16_t v) noexcept :
294  type_ (VT::SHORT),
295  val_ ((int64_t)v)
296  {}
297 
299  Variant (uint16_t v) noexcept :
300  type_ (VT::USHORT),
301  val_ ((int64_t)v)
302  {}
303 
305  Variant (int32_t v) noexcept :
306  type_ (VT::LONG),
307  val_ ((int64_t)v)
308  {}
309 
311  Variant (uint32_t v) noexcept :
312  type_ (VT::ULONG),
313  val_ ((int64_t)v)
314  {}
315 
317  Variant (int64_t v) noexcept :
318  type_ (VT::LONGLONG),
319  val_ (v)
320  {}
321 
323  Variant (uint64_t v) noexcept :
324  type_ (VT::ULONGLONG),
325  val_ (v)
326  {}
327 
329  Variant (float v) noexcept :
330  type_ (VT::FLOAT),
331  val_ ((long double)v)
332  {}
333 
335  Variant (double v) noexcept :
336  type_ (VT::DOUBLE),
337  val_ ((long double)v)
338  {}
339 
341  Variant (long double v) noexcept :
342  type_ (VT::LONGDOUBLE),
343  val_ (v)
344  {}
345 
347  Variant (std::string&& v) noexcept :
348  type_ (VT::STRING),
349  val_ (std::move (v))
350  {}
351 
353  Variant (const char* s) :
354  Variant (std::string (s))
355  {}
356 
358  Variant (std::wstring&& v) noexcept :
359  type_ (VT::WSTRING),
360  val_ (std::move (v))
361  {}
362 
364  Variant (const wchar_t* s) :
365  Variant (std::wstring (s))
366  {}
367 
369  Variant (const Fixed& v) noexcept :
370  type_ (VT::FIXED),
371  val_ (v)
372  {}
373 
375  Variant (const EnumItem& item) noexcept :
376  type_ (VT::ENUM_ITEM),
377  val_ (item)
378  {}
379 
381  Variant (const Constant& constant) noexcept :
382  type_ (VT::CONSTANT),
383  val_ (constant)
384  {}
385 
388 
390  Variant& operator = (Variant&& src) noexcept;
391 
392  bool to_boolean () const
393  {
394  assert (is_integral ());
395  return val_.u.i != 0;
396  }
397 
398  uint8_t to_octet () const;
399 
400  char to_char () const
401  {
402  return (char)to_octet ();
403  }
404 
405  wchar_t to_wchar () const
406  {
407  return (wchar_t)to_unsigned_short ();
408  }
409 
410  uint16_t to_unsigned_short () const;
411  int16_t to_short () const;
412  uint32_t to_unsigned_long () const;
413  int32_t to_long () const;
414  uint64_t to_unsigned_long_long () const;
415  int64_t to_long_long () const;
416  float to_float () const;
417  double to_double () const;
418  long double to_long_double () const;
419 
420  typedef uint64_t Key;
421 
422  Key to_key () const noexcept
423  {
424  if (is_integral ())
425  return val_.u.ui;
426  else {
427  assert (VT::ENUM_ITEM == type_);
428  return (Key)val_.u.enum_item;
429  }
430  }
431 
432  bool is_integral () const noexcept
433  {
434  return VT::BOOLEAN <= type_ && type_ <= VT::LONGLONG;
435  }
436 
437  bool is_signed () const noexcept
438  {
439  return VT::SHORT <= type_ && type_ <= VT::LONGDOUBLE;
440  }
441 
442  bool is_floating_point () const noexcept
443  {
444  return VT::FLOAT <= type_ && type_ <= VT::LONGDOUBLE;
445  }
446 
447 private:
448  friend class Builder;
449 
450  void clear () noexcept;
451  void copy (const Variant& src);
452  void move (Variant&& src);
453 
454  static void check_fp ();
455 
456  static void append (std::string& s, unsigned c);
457 
458  [[noreturn]] static void throw_out_of_range ();
459 
460 private:
461  VT type_;
462 
463  union U
464  {
465  int64_t i;
466  uint64_t ui;
467  long double d;
468  Fixed fixed;
469  std::string s;
470  std::wstring ws;
471  const EnumItem* enum_item;
472  const Constant* constant;
473 
474  ~U ()
475  {}
476 
477  U ()
478  {}
479 
480  U (const int64_t& src) :
481  i (src)
482  {}
483 
484  U (const uint64_t& src) :
485  ui (src)
486  {}
487 
488  U (const long double& src) :
489  d (src)
490  {}
491 
492  U (std::string&& src) :
493  s (std::move (src))
494  {}
495 
496  U (std::wstring&& src) :
497  ws (std::move (src))
498  {}
499 
500  U (const Fixed& src) :
501  fixed (src)
502  {}
503 
504  U (const EnumItem& src) :
505  enum_item (&src)
506  {}
507 
508  U (const Constant& src) :
509  constant (&src)
510  {}
511  };
512 
513  struct Plain
514  {
515  int data [sizeof (U) / sizeof (int)];
516  };
517 
518  union Val
519  {
520  U u;
521  Plain plain;
522 
523  ~Val ()
524  {}
525 
526  Val ()
527  {}
528 
529  template <typename T>
530  Val (const T& src) :
531  u (src)
532  {}
533 
534  template <typename T>
535  Val (T&& src) :
536  u (std::move (src))
537  {}
538 
539  } val_;
540 };
541 
542 typedef std::forward_list <Variant> Variants;
543 
544 }
545 
546 #endif
const definition.
Definition: Constant.h:45
The enumerator.
Definition: Enum.h:44
A fixed point constant.
Definition: Fixed.h:44
Stores the constant value.
Definition: Variant.h:42
const std::string & as_string() const noexcept
Definition: Variant.h:189
Variant(const EnumItem &item) noexcept
VT::ENUM_ITEM.
Definition: Variant.h:375
Variant(char v) noexcept
VT::CHAR.
Definition: Variant.h:281
Variant(std::wstring &&v) noexcept
VT::WSTRING.
Definition: Variant.h:358
Variant(uint8_t v) noexcept
VT::OCTET.
Definition: Variant.h:275
Variant(wchar_t v) noexcept
VT::WCHAR.
Definition: Variant.h:287
wchar_t as_wchar() const noexcept
Definition: Variant.h:105
Variant(const Constant &constant) noexcept
VT::CONSTANT.
Definition: Variant.h:381
Variant(uint16_t v) noexcept
VT::USHORT.
Definition: Variant.h:299
Variant(int32_t v) noexcept
VT::LONG.
Definition: Variant.h:305
const std::wstring & as_wstring() const noexcept
Definition: Variant.h:197
const Variant & dereference_const() const noexcept
Variant(double v) noexcept
VT::DOUBLE.
Definition: Variant.h:335
Variant & operator=(const Variant &src)
Copy assignment.
Variant(long double v) noexcept
VT::LONGDOUBLE.
Definition: Variant.h:341
Variant(uint64_t v) noexcept
VT::ULONGLONG.
Definition: Variant.h:323
bool as_bool() const noexcept
Definition: Variant.h:81
const Fixed & as_Fixed() const noexcept
Definition: Variant.h:223
Variant(Variant &&src) noexcept
Move constructor.
Definition: Variant.h:263
VT vtype() const noexcept
Definition: Variant.h:72
Variant(std::string &&v) noexcept
VT::STRING.
Definition: Variant.h:347
long double as_long_double() const noexcept
Definition: Variant.h:179
float as_float() const noexcept
Definition: Variant.h:163
uint32_t as_unsigned_long() const noexcept
Definition: Variant.h:129
Variant(bool v) noexcept
VT::BOOLEAN.
Definition: Variant.h:269
Variant(float v) noexcept
VT::FLOAT.
Definition: Variant.h:329
int16_t as_short() const noexcept
Definition: Variant.h:121
Variant(const wchar_t *s)
VT::WSTRING.
Definition: Variant.h:364
Variant(int64_t v) noexcept
VT::LONGLONG.
Definition: Variant.h:317
Variant(const Variant &src)
Copy constructor.
Definition: Variant.h:257
const Constant & as_constant() const noexcept
Definition: Variant.h:213
int32_t as_long() const noexcept
Definition: Variant.h:137
std::string to_string() const
double as_double() const noexcept
Definition: Variant.h:171
Variant(uint32_t v) noexcept
VT::ULONG.
Definition: Variant.h:311
uint16_t as_unsigned_short() const noexcept
Definition: Variant.h:113
VT
Value vtype.
Definition: Variant.h:46
@ CHAR
Variant::as_char ()
@ OCTET
Variant::as_octet ()
@ ULONG
Variant::as_unsigned_long ()
@ STRING
Variant::as_string ()
@ ENUM_ITEM
Variant::as_enum_item ()
@ CONSTANT
Variant::as_constant ()
@ ULONGLONG
Variant::as_unsigned_long_long ()
@ SHORT
Variant::as_short ()
@ LONGDOUBLE
Variant::as_long_double ()
@ USHORT
Variant::as_unsigned_short ()
@ EMPTY
No value.
@ LONG
Variant::as_long ()
@ BOOLEAN
Variant::as_bool ()
@ FIXED
Variant::as_Fixed ();.
@ WSTRING
Variant::as_wstring ()
@ WCHAR
Variant::as_wchar ()
@ LONGLONG
Variant::as_long_long ()
@ FLOAT
Variant::as_float ()
@ DOUBLE
Variant::as_double ()
Variant()
VT::EMPTY.
Definition: Variant.h:252
Variant(const Fixed &v) noexcept
VT::FIXED.
Definition: Variant.h:369
Variant(const char *s)
VT::STRING.
Definition: Variant.h:353
Variant(int16_t v) noexcept
VT::SHORT.
Definition: Variant.h:293
int64_t as_long_long() const noexcept
Definition: Variant.h:153
bool empty() const noexcept
Definition: Variant.h:237
uint64_t as_unsigned_long_long() const noexcept
Definition: Variant.h:145
char as_char() const noexcept
Definition: Variant.h:97
uint8_t as_octet() const noexcept
Definition: Variant.h:89
const EnumItem & as_enum_item() const noexcept
Definition: Variant.h:205
Abstract Syntax Tree namespace.
Definition: Array.h:34