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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
#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
#include <boost/cstdint.hpp>
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:
class RangeType {
private:
double begin_val;
double step_val;
double end_val;
/// inverse begin/end if begin is upper than end
void normalize();
public:
typedef enum { RANGE_TYPE_BEGIN, RANGE_TYPE_RUNNING, RANGE_TYPE_END } type_t;
class iterator {
public:
typedef iterator self_type;
typedef double value_type;
typedef double& reference;
typedef double* pointer;
typedef std::forward_iterator_tag iterator_category;
typedef double difference_type;
iterator(RangeType &range, type_t type);
self_type operator++();
self_type operator++(int junk);
reference operator*();
pointer operator->();
bool operator==(const self_type& other) const;
bool operator!=(const self_type& other) const;
private:
RangeType ⦥
double val;
type_t type;
void update_type();
};
RangeType(double begin, double end)
: begin_val(begin), step_val(1.0), end_val(end)
{
normalize();
}
RangeType(double begin, double step, double end)
: begin_val(begin), step_val(step), end_val(end) {}
bool operator==(const RangeType &other) const {
return this->begin_val == other.begin_val &&
this->step_val == other.step_val &&
this->end_val == other.end_val;
}
iterator begin() { return iterator(*this, RANGE_TYPE_BEGIN); }
iterator end() { return iterator(*this, RANGE_TYPE_END); }
/// return number of steps, max uint32_t value if step is 0
boost::uint32_t nbsteps() const;
friend class tostring_visitor;
friend class bracket_visitor;
};
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
|