diff options
| author | Andrew Stitcher <astitcher@apache.org> | 2013-03-04 21:08:45 +0000 |
|---|---|---|
| committer | Andrew Stitcher <astitcher@apache.org> | 2013-03-04 21:08:45 +0000 |
| commit | dfada942aa6795a44bcf6988fc300d0767c994e8 (patch) | |
| tree | 07e59fa97f4a2d3a83e1e5a06786101251439497 /cpp/src/qpid/broker/SelectorValue.cpp | |
| parent | 5ebf2fd5b0e7ada7089437efa95e37c6f473fcfc (diff) | |
| download | qpid-python-dfada942aa6795a44bcf6988fc300d0767c994e8.tar.gz | |
QPID-4558: Selectors for C++ broker
- Added numeric and boolean values
* To literals and identifier values
* To the code that extracts values from message properties
- Added the full set of comparison operators
- Implemented full "unknown" semantics for all
operators.
- Implemented extended "is null" and "is not null" operators
that allow expressions as well as just identifiers.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1452525 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/broker/SelectorValue.cpp')
| -rw-r--r-- | cpp/src/qpid/broker/SelectorValue.cpp | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/cpp/src/qpid/broker/SelectorValue.cpp b/cpp/src/qpid/broker/SelectorValue.cpp new file mode 100644 index 0000000000..d35e4edd3e --- /dev/null +++ b/cpp/src/qpid/broker/SelectorValue.cpp @@ -0,0 +1,196 @@ +/* + * + * 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 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); + } + } +} + +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(); +} + +}}
\ No newline at end of file |
