summaryrefslogtreecommitdiff
path: root/src/value.cc
diff options
context:
space:
mode:
authorTorsten Paul <Torsten.Paul@gmx.de>2013-11-10 01:42:58 (GMT)
committerTorsten Paul <Torsten.Paul@gmx.de>2013-11-11 00:31:44 (GMT)
commit00a329f0bd4ab940c1063106ee6ba7db7811a090 (patch)
tree26872901c9cbc603e7a62b14975e306b0e146885 /src/value.cc
parente5d535e900ae5bc5923fc76c80fb3b3f9153a80e (diff)
Add support for handling negative step values in ranges (fixes #500).
Diffstat (limited to 'src/value.cc')
-rw-r--r--src/value.cc102
1 files changed, 98 insertions, 4 deletions
diff --git a/src/value.cc b/src/value.cc
index ac33a3b..931c616 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -232,7 +232,7 @@ public:
}
std::string operator()(const Value::RangeType &v) const {
- return (boost::format("[%1% : %2% : %3%]") % v.begin % v.step % v.end).str();
+ return (boost::format("[%1% : %2% : %3%]") % v.begin_val % v.step_val % v.end_val).str();
}
};
@@ -600,9 +600,9 @@ public:
Value operator()(const Value::RangeType &range, const double &idx) const {
switch(int(idx)) {
- case 0: return Value(range.begin);
- case 1: return Value(range.step);
- case 2: return Value(range.end);
+ case 0: return Value(range.begin_val);
+ case 1: return Value(range.step_val);
+ case 2: return Value(range.end_val);
}
return Value::undefined;
}
@@ -617,3 +617,97 @@ Value Value::operator[](const Value &v)
{
return boost::apply_visitor(bracket_visitor(), this->value, v.value);
}
+
+void Value::RangeType::normalize() {
+ if ((step_val>0) && (end_val < begin_val)) {
+ std::swap(begin_val,end_val);
+ PRINT("DEPRECATED: Using ranges of the form [begin:end] with begin value greater than the end value is deprecated.");
+ }
+}
+
+unsigned long Value::RangeType::nbsteps() const {
+ if (begin_val == end_val) {
+ return 0;
+ }
+
+ if (step_val == 0) {
+ return std::numeric_limits<unsigned long>::max();
+ }
+
+ double steps;
+ if (step_val < 0) {
+ if (begin_val < end_val) {
+ return 0;
+ }
+ steps = (begin_val - end_val) / (-step_val);
+ } else {
+ if (begin_val > end_val) {
+ return 0;
+ }
+ steps = (end_val - begin_val) / step_val;
+ }
+
+ return steps;
+}
+
+Value::RangeType::iterator::iterator(Value::RangeType &range, type_t type) : range(range), val(range.begin_val)
+{
+ this->type = type;
+ update_type();
+}
+
+void Value::RangeType::iterator::update_type()
+{
+ if (range.step_val == 0) {
+ type = RANGE_TYPE_END;
+ } else if (range.step_val < 0) {
+ if (val < range.end_val) {
+ type = RANGE_TYPE_END;
+ }
+ } else {
+ if (val > range.end_val) {
+ type = RANGE_TYPE_END;
+ }
+ }
+}
+
+Value::RangeType::iterator::reference Value::RangeType::iterator::operator*()
+{
+ return val;
+}
+
+Value::RangeType::iterator::pointer Value::RangeType::iterator::operator->()
+{
+ return &(operator*());
+}
+
+Value::RangeType::iterator::self_type Value::RangeType::iterator::operator++()
+{
+ if (type < 0) {
+ type = RANGE_TYPE_RUNNING;
+ }
+ val += range.step_val;
+ update_type();
+ return *this;
+}
+
+Value::RangeType::iterator::self_type Value::RangeType::iterator::operator++(int)
+{
+ self_type tmp(*this);
+ operator++();
+ return tmp;
+}
+
+bool Value::RangeType::iterator::operator==(const self_type &other) const
+{
+ if (type == RANGE_TYPE_RUNNING) {
+ return (type == other.type) && (val == other.val) && (range == other.range);
+ } else {
+ return (type == other.type) && (range == other.range);
+ }
+}
+
+bool Value::RangeType::iterator::operator!=(const self_type &other) const
+{
+ return !(*this == other);
+}
contact: Jan Huwald // Impressum