Basic Polynomial Algebra Subprograms (BPAS)  v. 1.791
Symbol.hpp
1 #ifndef _SYMBOL_H_
2 #define _SYMBOL_H_
3 
4 #include <locale>
5 #include <codecvt>
6 #include <string>
7 #include "../ExpressionTree/ExprTreeNode.hpp"
8 #include "../ExpressionTree/ExpressionTree.hpp"
9 
10 
11 extern std::wstring string2wstring(const std::string& str);
12 extern std::string wstring2string(const std::wstring& wstr);
13 
14 // Do we need a Unicode processing library (such as ICU) to normalize strings,
15 // i.e., can multiple unicode strings be equivalent?
16 // This is currently mixing hpp and cpp code
17 
18 /**
19  * An encapsulation of a mathematical symbol.
20  * This symbol can be an indeterminant, or more generally, any unicode string.
21  * Provides comparison, concatenation, and printing.
22  */
23 class Symbol {
24  private:
25  /**
26  * Simple union for different
27  */
28  union SymbolString {
29  std::string* str; // ASCII string
30  std::wstring* wstr; // Unicode string
31  };
32 
33  /**
34  * Enum to differentiate between symbol types.
35  */
36  typedef enum SymbolType{
37  NULL_TYPE = 0x0,
38  STRING_TYPE,
39  WSTRING_TYPE
40  } SymbolType;
41 
42  SymbolString s;
43  SymbolType type;
44 
45  public:
46  /**
47  * Construct an empty Symbol.
48  */
49  Symbol () : type(NULL_TYPE) {
50  s.str = new std::string("");
51  }
52 
53  /**
54  * Construct a Symbol from the given character.
55  * @param c the character
56  */
57  Symbol (char c) : type(STRING_TYPE) {
58  char localC[2];
59  localC[0] = c;
60  localC[1] = '\0';
61  s.str = new std::string(localC);
62  }
63 
64  /**
65  * Construct a Symbol from a c-string.
66  * @param c the c-string.
67  */
68  explicit Symbol (const char* c) : type(STRING_TYPE) {
69  s.str = new std::string(c);
70  }
71 
72  /**
73  * Construct a Symbol from a wide character c-string.
74  */
75  explicit Symbol (const wchar_t* c) : type(WSTRING_TYPE) {
76  s.wstr = new std::wstring(c);
77  }
78 
79  /**
80  * Construct a Symbol from a std::string.
81  * @param a the string
82  */
83  explicit Symbol (const std::string& a) : type(STRING_TYPE) {
84  s.str = new std::string(a);
85  }
86 
87  /**
88  * Construct a Symbol from a wide string, std::wstring.
89  * @param a the wide string
90  */
91  explicit Symbol (const std::wstring& a) : type(WSTRING_TYPE) {
92  s.wstr = new std::wstring(a);
93  }
94 
95  /**
96  * Copy constructor.
97  */
98  Symbol (const Symbol& a) : type(a.type) {
99  switch (type) {
100  case NULL_TYPE :
101  case STRING_TYPE : {
102  s.str = new std::string(*a.s.str);
103  break;
104  }
105  case WSTRING_TYPE: {
106  s.wstr = new std::wstring(*a.s.wstr);
107  break;
108  }
109  }
110  }
111 
112  /**
113  * Destructor.
114  */
115  ~Symbol () {
116  switch (type) {
117  case NULL_TYPE:
118  case STRING_TYPE: {
119  delete s.str;
120  break;
121  }
122  case WSTRING_TYPE: {
123  delete s.wstr;
124  break;
125  }
126  }
127  }
128 
129  /**
130  * Get the type of this Symbol.
131  */
132  // std::string getType() {
133  // switch (type) {
134  // case NULL_TYPE: {
135  // return "NULL_TYPE";
136  // }
137  // case STRING_TYPE: {
138  // return "STRING_TYPE";
139  // }
140  // case WSTRING_TYPE: {
141  // return "WSTRING_TYPE";
142  // }
143  // }
144  // }
145 
146  /**
147  * Assignment operator from a character.
148  *
149  * @param c the character to assign from.
150  */
151  inline Symbol& operator= (char c) {
152  char localC[2];
153  localC[0] = c;
154  localC[1] = '\0';
155  return (*this = std::string(localC));
156  }
157 
158  /**
159  * Assignment operator from a c-string.
160  *
161  * @param c the c-string to assign from.
162  */
163  inline Symbol& operator= (const char* c) {
164  std::string s(c);
165  return (*this = s);
166  }
167 
168  /**
169  * Assignment operator from a std::string.
170  *
171  * @param a the string to assign from.
172  */
173  inline Symbol& operator= (const std::string& a) {
174  switch (type) {
175  case NULL_TYPE: {
176  if (a != "") {
177  type = STRING_TYPE;
178  *s.str = a;
179  }
180  break;
181  }
182  case STRING_TYPE: {
183  if (a == "") {
184  type = NULL_TYPE;
185  }
186  *s.str = a;
187  break;
188  }
189  case WSTRING_TYPE: {
190  delete s.wstr;
191  s.str = new std::string(a);
192  type = STRING_TYPE;
193  break;
194  }
195  }
196  return *this;
197  }
198 
199  /**
200  * Copy assignment.
201  * @param a the other Symbol to copy from.
202  */
203  inline Symbol& operator= (const Symbol& a) {
204  switch (a.type) {
205  case NULL_TYPE: {
206  switch (type) {
207  case NULL_TYPE: {
208  break;
209  }
210  case STRING_TYPE: {
211  *s.str = *a.s.str;
212  type = NULL_TYPE;
213  break;
214  }
215  case WSTRING_TYPE: {
216  delete s.wstr;
217  s.str = new std::string("");
218  type = NULL_TYPE;
219  break;
220  }
221  }
222  break;
223  }
224  case STRING_TYPE: {
225  switch (type) {
226  case NULL_TYPE: {
227  *s.str = *a.s.str;
228  type = STRING_TYPE;
229  break;
230  }
231  case STRING_TYPE: {
232  *s.str = *a.s.str;
233  break;
234  }
235  case WSTRING_TYPE: {
236  delete s.wstr;
237  s.str = new std::string(*a.s.str);
238  type = STRING_TYPE;
239  break;
240  }
241  }
242  break;
243  }
244  case WSTRING_TYPE: {
245  switch (type) {
246  case NULL_TYPE:
247  case STRING_TYPE: {
248  delete s.str;
249  s.wstr = new std::wstring(*a.s.wstr);
250  type = WSTRING_TYPE;
251  break;
252  }
253  case WSTRING_TYPE: {
254  *s.wstr = *a.s.wstr;
255  break;
256  }
257  }
258  }
259  }
260  return *this;
261  }
262 
263  /**
264  * Concatenate a string to this Symbol.
265  * @param a the string to concatenate.
266  */
267  inline Symbol& operator+= (const std::string& a) {
268  if (a != "") {
269  switch (type) {
270  case NULL_TYPE: {
271  type = STRING_TYPE;
272  }
273  case STRING_TYPE: {
274  *s.str += a;
275  break;
276  }
277  case WSTRING_TYPE: {
278  std::wstring b;
279  b = string2wstring(a);
280  *s.wstr += b;
281  break;
282  }
283  }
284  }
285  return *this;
286  }
287 
288  /**
289  * Concatenate a Symbol to this Symbol.
290  * @param a the Symbol to concatenate.
291  */
292  inline Symbol& operator+= (const Symbol& a) {
293  switch (type) {
294  case NULL_TYPE: {
295  switch (a.type) {
296  case NULL_TYPE: {
297  break;
298  }
299  case STRING_TYPE: {
300  *s.str += *a.s.str;
301  type = STRING_TYPE;
302  break;
303  }
304  case WSTRING_TYPE: {
305  delete s.str;
306  s.wstr = new std::wstring(*a.s.wstr);
307  type = WSTRING_TYPE;
308  }
309  }
310  break;
311  }
312  case STRING_TYPE: {
313  switch (a.type) {
314  case NULL_TYPE: {
315  break;
316  }
317  case STRING_TYPE: {
318  *s.str += *a.s.str;
319  break;
320  }
321  case WSTRING_TYPE: {
322  std::wstring b;
323  b = string2wstring(*s.str);
324  delete s.str;
325  s.wstr = new std::wstring(b);
326  *s.wstr += *a.s.wstr;
327  type = WSTRING_TYPE;
328  break;
329  }
330  }
331  break;
332  }
333  case WSTRING_TYPE: {
334  switch (a.type) {
335  case NULL_TYPE: {
336  break;
337  }
338  case STRING_TYPE: {
339  std::wstring b;
340  b = string2wstring(*a.s.str);
341  *s.wstr += b;
342  break;
343  }
344  case WSTRING_TYPE: {
345  *s.wstr += *a.s.wstr;
346  }
347  }
348  }
349  }
350  return *this;
351  }
352 
353  /**
354  * Less than comparison operator between two Symbol.
355  * @param s1 the first Symbol
356  * @param s2 the second Symbol
357  * @return true iff s1 < s2
358  */
359  friend bool operator<(const Symbol& s1,const Symbol& s2);
360 
361  /**
362  * Equality comparison operator between two Symbol.
363  * @param s1 the first Symbol
364  * @param s2 the second Symbol
365  * @return true iff s1 = s2
366  */
367  friend bool operator==(const Symbol& s1,const Symbol& s2);
368 
369  /**
370  * Equality comparison operator between a Symbol and a string.
371  * @param s1 a Symbol
372  * @param s2 a string
373  * @return true iff s1 = s2
374  */
375  friend bool operator== (const std::string& s2, const Symbol& s1);
376 
377  /**
378  * Equality comparison operator between a Symbol and a string.
379  * @param s1 a Symbol
380  * @param s2 a string
381  * @return true iff s1 = s2
382  */
383  friend bool operator== (const Symbol& s1, const std::string& s2);
384 
385  /**
386  * Inequality comparison operator between a Symbol and a string.
387  * @param s1 a Symbol
388  * @param s2 a string
389  * @return true iff s1 != s2
390  */
391  friend bool operator!= (const std::string& s2, const Symbol& s1);
392 
393  /**
394  * Inequality comparison operator between a Symbol and a string.
395  * @param s1 a Symbol
396  * @param s2 a string
397  * @return true iff s1 != s2
398  */
399  friend bool operator!= (const Symbol& s1, const std::string& s2);
400 
401  //not needed as we can convert form string to symbol
402  // friend bool operator==(const Symbol& s1, const std::string& s2){
403  // return s1 == Symbol(s2);
404  // }
405  // friend bool operator==(const std::string& s1, const Symbol& s2) {
406  // return Symbol(s1) == s2;
407  // }
408 
409 
410  /**
411  * Less-than-equal comparison operator between two Symbol.
412  * @param s1 the first Symbol
413  * @param s2 the second Symbol
414  * @return true iff s1 <= s2
415  */
416  friend bool operator<=(const Symbol& s1,const Symbol& s2) {
417  return (s1<s2 || s1==s2);
418  }
419 
420  /**
421  * Greater-than comparison operator between two Symbol.
422  * @param s1 the first Symbol
423  * @param s2 the second Symbol
424  * @return true iff s1 > s2
425  */
426  friend bool operator>(const Symbol& s1,const Symbol& s2) {
427  return !(s1<=s2);
428  }
429 
430  /**
431  * Greater-than-equal comparison operator between two Symbol.
432  * @param s1 the first Symbol
433  * @param s2 the second Symbol
434  * @return true iff s1 >= s2
435  */
436  friend bool operator>=(const Symbol& s1,const Symbol& s2) {
437  return !(s1<s2);
438  }
439 
440  /**
441  * Inequality comparison operator between two Symbol.
442  * @param s1 the first Symbol
443  * @param s2 the second Symbol
444  * @return true iff s1 != s2
445  */
446  friend bool operator!=(const Symbol& s1,const Symbol& s2) {
447  return !(s1==s2);
448  }
449 
450  /**
451  * Get a random Symbol.
452  * @return the random Symbol.
453  */
454  static Symbol randomElement();
455 
456  /**
457  * Get a vector of pair-wise different random Symbols.
458  * n: the size of the vector.
459  * @return the vector of Symbols
460  */
461  static std::vector<Symbol> randomElements(int n);
462 
463  /**
464  * Conver a Symbol to a std::string.
465  * @return the Symbol as a string.
466  */
467  std::string toString() const {
468  std::string out;
469  switch (type) {
470  case NULL_TYPE:
471  case STRING_TYPE: {
472  out = *(s.str);
473  break;
474  }
475  case WSTRING_TYPE: {
476  out = wstring2string(*s.wstr);
477  break;
478  }
479  }
480  return out;
481  }
482 
483  /**
484  * Output operator. Outputs the Symbol to the output stream.
485  * out: the output stream.
486  * b: the Symbol to output.
487  */
488  inline friend std::ostream& operator<< (std::ostream &out, const Symbol& b) {
489  out << b.toString();
490  return out;
491  }
492 
493  /**
494  * Convert a Symbol to an ExpressionTree.
495  * @return the ExpressionTree encoding this Symbol.
496  */
498  ExprTreeNode* etn = new ExprTreeNode(*this);
499  ExpressionTree et(etn);
500  return et;
501  }
502 
503 };
504 
505 #endif
friend bool operator==(const Symbol &s1, const Symbol &s2)
Equality comparison operator between two Symbol.
~Symbol()
Destructor.
Definition: Symbol.hpp:115
std::string toString() const
Conver a Symbol to a std::string.
Definition: Symbol.hpp:467
friend std::ostream & operator<<(std::ostream &out, const Symbol &b)
Output operator.
Definition: Symbol.hpp:488
Symbol & operator=(char c)
Get the type of this Symbol.
Definition: Symbol.hpp:151
friend bool operator<=(const Symbol &s1, const Symbol &s2)
Less-than-equal comparison operator between two Symbol.
Definition: Symbol.hpp:416
Symbol(const std::wstring &a)
Construct a Symbol from a wide string, std::wstring.
Definition: Symbol.hpp:91
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
friend bool operator!=(const Symbol &s1, const Symbol &s2)
Inequality comparison operator between two Symbol.
Definition: Symbol.hpp:446
friend bool operator!=(const std::string &s2, const Symbol &s1)
Inequality comparison operator between a Symbol and a string.
Symbol(const Symbol &a)
Copy constructor.
Definition: Symbol.hpp:98
ExpressionTree convertToExpressionTree() const
Convert a Symbol to an ExpressionTree.
Definition: Symbol.hpp:497
friend bool operator>(const Symbol &s1, const Symbol &s2)
Greater-than comparison operator between two Symbol.
Definition: Symbol.hpp:426
Symbol()
Construct an empty Symbol.
Definition: Symbol.hpp:49
Symbol(const char *c)
Construct a Symbol from a c-string.
Definition: Symbol.hpp:68
friend bool operator<(const Symbol &s1, const Symbol &s2)
Less than comparison operator between two Symbol.
static std::vector< Symbol > randomElements(int n)
Get a vector of pair-wise different random Symbols.
An encapsulation of a mathematical symbol.
Definition: Symbol.hpp:23
static Symbol randomElement()
Get a random Symbol.
Symbol(const wchar_t *c)
Construct a Symbol from a wide character c-string.
Definition: Symbol.hpp:75
Symbol(char c)
Construct a Symbol from the given character.
Definition: Symbol.hpp:57
Symbol(const std::string &a)
Construct a Symbol from a std::string.
Definition: Symbol.hpp:83
Symbol & operator+=(const std::string &a)
Concatenate a string to this Symbol.
Definition: Symbol.hpp:267
ExprTreeNode is a single node in the bianry tree of an ExpressionTree.
Definition: ExprTreeNode.hpp:76
friend bool operator>=(const Symbol &s1, const Symbol &s2)
Greater-than-equal comparison operator between two Symbol.
Definition: Symbol.hpp:436