-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.hpp
110 lines (77 loc) · 2.88 KB
/
atom.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*! \file atom.hpp
Defines the Atom type and associated functions.
*/
#ifndef ATOM_HPP
#define ATOM_HPP
#include "token.hpp"
#include <complex>
#include <string>
/*! \class Atom
\brief A variant type that may be a Number or Symbol or Complex or the default type None.
This class provides value semantics.
*/
class Atom {
public:
/// Construct a default Atom of type None
Atom();
/// Construct an Atom of type Number with value
Atom(double value);
/// Construct an Atom of type Symbol or String with value
Atom(const std::string & value);
/// Construct an Atom of type Complex with value
Atom(std::complex<double> value);
/// Construct an Atom directly from a Token
Atom(const Token & token);
/// Copy-construct an Atom
Atom(const Atom & x);
/// Assign an Atom
Atom & operator=(const Atom & x);
/// Atom destructor
~Atom();
/// predicate to determine if an Atom is of type None
bool isNone() const noexcept;
/// predicate to determine if an Atom is of type Number
bool isNumber() const noexcept;
/// predicate to determine if an Atom is of type Symbol
bool isSymbol() const noexcept;
/// predicate to determine if an Atom is of type Complex
bool isComplex() const noexcept;
/// predicate to determine if an Atom is of type String
bool isString() const noexcept;
/// value of Atom as a Number literal, return 0 if not a Number
double asNumber() const noexcept;
/// value of Atom as a Symbol, returns empty-string if not a Symbol
std::string asSymbol() const noexcept;
/// value of Atom as a Complex number, return 0 if not a Complex
std::complex<double> asComplex() const noexcept;
/// value of Atom as a String literal, returns empty-string if not a String
std::string asString() const noexcept;
/// equality comparison based on type and value
bool operator==(const Atom & right) const noexcept;
private:
// internal enum of known types
enum Type {NoneKind, NumberKind, SymbolKind, ComplexKind, StringKind};
// track the type
Type m_type;
// values for the known types. Note the use of a union requires care
// when setting non POD values (see setSymbol)
union { // A union is a special class type that can hold only one of its non-static data members at a time.
double numberValue;
std::string symbolValue;
std::complex<double> complexValue;
std::string stringValue;
};
// helper to set type and value of Number
void setNumber(double value);
// helper to set type and value of Symbol
void setSymbol(const std::string & value);
// helper to set type and value of Complex
void setComplex(std::complex<double> value);
// helper to set type and value of String
void setString(const std::string & value);
};
/// inequality comparison for Atom
bool operator!=(const Atom &left, const Atom & right) noexcept;
/// output stream rendering
std::ostream & operator<<(std::ostream & out, const Atom & a);
#endif