diff options
Diffstat (limited to 'qpid/cpp/src/qpid/broker/SelectorValue.cpp')
-rw-r--r-- | qpid/cpp/src/qpid/broker/SelectorValue.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/broker/SelectorValue.cpp b/qpid/cpp/src/qpid/broker/SelectorValue.cpp new file mode 100644 index 0000000000..0855fa91d0 --- /dev/null +++ b/qpid/cpp/src/qpid/broker/SelectorValue.cpp @@ -0,0 +1,212 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "qpid/broker/SelectorValue.h" + +#include <ostream> +#include <boost/scoped_ptr.hpp> + +using std::ostream; + +namespace qpid { +namespace broker { + +ostream& operator<<(ostream& os, const Value& v) +{ + switch (v.type) { + case Value::T_UNKNOWN: os << "UNKNOWN"; break; + case Value::T_BOOL: os << "BOOL:" << std::boolalpha << v.b; break; + case Value::T_EXACT: os << "EXACT:" << v.i; break; + case Value::T_INEXACT: os << "APPROX:" << v.x; break; + case Value::T_STRING: os << "STRING:'" << *v.s << "'"; break; + }; + return os; +} + +class NumericPairBase { +public: + virtual ~NumericPairBase() {} + virtual Value add() = 0; + virtual Value sub() = 0; + virtual Value mul() = 0; + virtual Value div() = 0; + + virtual bool eq() = 0; + virtual bool ne() = 0; + virtual bool ls() = 0; + virtual bool gr() = 0; + virtual bool le() = 0; + virtual bool ge() = 0; +}; + +template <typename T> +class NumericPair : public NumericPairBase { + const T n1; + const T n2; + + Value add() { return n1+n2; } + Value sub() { return n1-n2; } + Value mul() { return n1*n2; } + Value div() { return n1/n2; } + + bool eq() { return n1==n2; } + bool ne() { return n1!=n2; } + bool ls() { return n1<n2; } + bool gr() { return n1>n2; } + bool le() { return n1<=n2; } + bool ge() { return n1>=n2; } + +public: + NumericPair(T x, T y) : + n1(x), + n2(y) + {} +}; + +NumericPairBase* promoteNumeric(const Value& v1, const Value& v2) +{ + if (!numeric(v1) || !numeric(v2)) return 0; + + if (v1.type != v2.type) { + switch (v1.type) { + case Value::T_INEXACT: return new NumericPair<double>(v1.x, v2.i); + case Value::T_EXACT: return new NumericPair<double>(v1.i, v2.x); + default: + assert(false); + } + } else { + switch (v1.type) { + case Value::T_INEXACT: return new NumericPair<double>(v1.x, v2.x); + case Value::T_EXACT: return new NumericPair<int64_t>(v1.i, v2.i); + default: + assert(false); + } + } + // Can never get here - but this stops a warning + return 0; +} + +bool operator==(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->eq(); + + if (v1.type != v2.type) return false; + switch (v1.type) { + case Value::T_BOOL: return v1.b == v2.b; + case Value::T_STRING: return *v1.s == *v2.s; + default: // Cannot ever get here + return false; + } +} + +bool operator!=(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->ne(); + + if (v1.type != v2.type) return false; + switch (v1.type) { + case Value::T_BOOL: return v1.b != v2.b; + case Value::T_STRING: return *v1.s != *v2.s; + default: // Cannot ever get here + return false; + } +} + +bool operator<(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->ls(); + + return false; +} + +bool operator>(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->gr(); + + return false; +} + +bool operator<=(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->le(); + + return false; +} + +bool operator>=(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->ge(); + + return false; +} + +Value operator+(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->add(); + + return Value(); +} + +Value operator-(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->sub(); + + return Value(); +} + +Value operator*(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->mul(); + + return Value(); +} + +Value operator/(const Value& v1, const Value& v2) +{ + boost::scoped_ptr<NumericPairBase> nbp(promoteNumeric(v1, v2)); + if (nbp) return nbp->div(); + + return Value(); +} + +Value operator-(const Value& v) +{ + switch (v.type) { + case Value::T_EXACT: + return -v.i; + case Value::T_INEXACT: + return -v.x; + default: + break; + } + return Value(); +} + +}} |