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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#ifndef VALUE_H_
#define VALUE_H_
#include <vector>
#include <string>
#include <algorithm>
#include <limits>
// Workaround for https://bugreports.qt-project.org/browse/QTBUG-22829
#ifndef Q_MOC_RUN
#include <boost/variant.hpp>
#include <boost/lexical_cast.hpp>
#endif
class QuotedString : public std::string
{
public:
QuotedString() : std::string() {}
QuotedString(const std::string &s) : std::string(s) {}
};
std::ostream &operator<<(std::ostream &stream, const QuotedString &s);
class Filename : public QuotedString
{
public:
Filename() : QuotedString() {}
Filename(const std::string &f) : QuotedString(f) {}
};
std::ostream &operator<<(std::ostream &stream, const Filename &filename);
class Value
{
public:
struct RangeType {
RangeType(double begin, double step, double end)
: begin(begin), step(step), end(end) {}
bool operator==(const RangeType &other) const {
return this->begin == other.begin &&
this->step == other.step &&
this->end == other.end;
}
/// inverse begin/end if begin is upper than end
void normalize() {
if ((step>0) && (end < begin)) {
std::swap(begin,end);
}
}
/// return number of steps, max int value if step is null
int nbsteps() const {
if (step<=0) {
return std::numeric_limits<int>::max();
}
return (int)((begin-end)/step);
}
double begin;
double step;
double end;
};
typedef std::vector<Value> VectorType;
enum ValueType {
UNDEFINED,
BOOL,
NUMBER,
STRING,
VECTOR,
RANGE
};
static Value undefined;
Value();
Value(bool v);
Value(int v);
Value(double v);
Value(const std::string &v);
Value(const char *v);
Value(const char v);
Value(const VectorType &v);
Value(const RangeType &v);
~Value() {}
ValueType type() const;
bool isUndefined() const;
double toDouble() const;
bool getDouble(double &v) const;
bool toBool() const;
std::string toString() const;
const VectorType &toVector() const;
bool getVec2(double &x, double &y) const;
bool getVec3(double &x, double &y, double &z, double defaultval = 0.0) const;
RangeType toRange() const;
operator bool() const { return this->toBool(); }
Value &operator=(const Value &v);
bool operator==(const Value &v) const;
bool operator!=(const Value &v) const;
bool operator<(const Value &v) const;
bool operator<=(const Value &v) const;
bool operator>=(const Value &v) const;
bool operator>(const Value &v) const;
Value operator-() const;
Value operator[](const Value &v);
Value operator+(const Value &v) const;
Value operator-(const Value &v) const;
Value operator*(const Value &v) const;
Value operator/(const Value &v) const;
Value operator%(const Value &v) const;
friend std::ostream &operator<<(std::ostream &stream, const Value &value) {
if (value.type() == Value::STRING) stream << QuotedString(value.toString());
else stream << value.toString();
return stream;
}
typedef boost::variant< boost::blank, bool, double, std::string, VectorType, RangeType > Variant;
private:
static Value multvecnum(const Value &vecval, const Value &numval);
static Value multmatvec(const Value &matrixval, const Value &vectorval);
static Value multvecmat(const Value &vectorval, const Value &matrixval);
Variant value;
};
#endif
|