summaryrefslogtreecommitdiff
path: root/src/value.h
blob: 75dff2bcc2ff067c86ab92d05ff30c48b03c9437 (plain)
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 &range;
      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
    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
contact: Jan Huwald // Impressum