platform/include/pion/platform/Comparison.hpp

00001 // ------------------------------------------------------------------------
00002 // Pion is a development platform for building Reactors that process Events
00003 // ------------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Pion is free software: you can redistribute it and/or modify it under the
00007 // terms of the GNU Affero General Public License as published by the Free
00008 // Software Foundation, either version 3 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Pion is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Affero General Public License
00017 // along with Pion.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 
00020 #ifndef __PION_COMPARISON_HEADER__
00021 #define __PION_COMPARISON_HEADER__
00022 
00023 #include <boost/scoped_array.hpp>
00024 #include <boost/regex.hpp>
00025 #include <boost/regex/icu.hpp>
00026 #include <boost/logic/tribool.hpp>
00027 #include <boost/algorithm/string/compare.hpp>
00028 #include <boost/algorithm/string/predicate.hpp>
00029 #include <boost/tuple/tuple.hpp>
00030 #include <pion/PionConfig.hpp>
00031 #include <pion/PionException.hpp>
00032 #include <pion/platform/Vocabulary.hpp>
00033 #include <pion/platform/Event.hpp>
00034 #include <unicode/uiter.h>
00035 #include <unicode/ustring.h>
00036 #include <unicode/stsearch.h>
00037 
00038 namespace pion {        // begin namespace pion
00039 namespace platform {    // begin namespace platform (Pion Platform Library)
00040 
00044 class PION_PLATFORM_API Comparison
00045 {
00046 public:
00047 
00049     enum ComparisonType {
00050         TYPE_FALSE = 0,                     // always false
00051         TYPE_TRUE,                          // always true
00052         TYPE_IS_DEFINED,                    // true if at least one value is defined
00053         TYPE_IS_NOT_DEFINED,                // true if no values are defined
00054         // numeric operations
00055         TYPE_EQUALS,
00056         TYPE_NOT_EQUALS,
00057         TYPE_GREATER_THAN,
00058         TYPE_LESS_THAN,
00059         TYPE_GREATER_OR_EQUAL,
00060         TYPE_LESS_OR_EQUAL,
00061         // string operations
00062         TYPE_EXACT_MATCH,
00063         TYPE_NOT_EXACT_MATCH,
00064         TYPE_CONTAINS,
00065         TYPE_NOT_CONTAINS,
00066         TYPE_STARTS_WITH,
00067         TYPE_NOT_STARTS_WITH,
00068         TYPE_ENDS_WITH,
00069         TYPE_NOT_ENDS_WITH,
00070         TYPE_ORDERED_BEFORE,
00071         TYPE_NOT_ORDERED_BEFORE,
00072         TYPE_ORDERED_AFTER,
00073         TYPE_NOT_ORDERED_AFTER,
00074         TYPE_REGEX,
00075         TYPE_NOT_REGEX,
00076         // string operations using UCOL_PRIMARY
00077         TYPE_EXACT_MATCH_PRIMARY,
00078         TYPE_NOT_EXACT_MATCH_PRIMARY,
00079         TYPE_CONTAINS_PRIMARY,
00080         TYPE_NOT_CONTAINS_PRIMARY,
00081         TYPE_STARTS_WITH_PRIMARY,
00082         TYPE_NOT_STARTS_WITH_PRIMARY,
00083         TYPE_ENDS_WITH_PRIMARY,
00084         TYPE_NOT_ENDS_WITH_PRIMARY,
00085         TYPE_ORDERED_BEFORE_PRIMARY,
00086         TYPE_NOT_ORDERED_BEFORE_PRIMARY,
00087         TYPE_ORDERED_AFTER_PRIMARY,
00088         TYPE_NOT_ORDERED_AFTER_PRIMARY,
00089         // date_time operations
00090         TYPE_SAME_DATE_TIME,
00091         TYPE_NOT_SAME_DATE_TIME,
00092         TYPE_EARLIER_DATE_TIME,
00093         TYPE_LATER_DATE_TIME,
00094         TYPE_SAME_OR_EARLIER_DATE_TIME,
00095         TYPE_SAME_OR_LATER_DATE_TIME,
00096         // date operations
00097         TYPE_SAME_DATE,
00098         TYPE_NOT_SAME_DATE,
00099         TYPE_EARLIER_DATE,
00100         TYPE_LATER_DATE,
00101         TYPE_SAME_OR_EARLIER_DATE,
00102         TYPE_SAME_OR_LATER_DATE,
00103         // time of day operations
00104         TYPE_SAME_TIME,
00105         TYPE_NOT_SAME_TIME,
00106         TYPE_EARLIER_TIME,
00107         TYPE_LATER_TIME,
00108         TYPE_SAME_OR_EARLIER_TIME,
00109         TYPE_SAME_OR_LATER_TIME,
00110         // Update LAST_COMPARISON_TYPE if adding types after TYPE_SAME_OR_LATER_TIME.
00111         LAST_COMPARISON_TYPE = TYPE_SAME_OR_LATER_TIME
00112     };
00113 
00115     class UnknownComparisonTypeException : public PionException {
00116     public:
00117         UnknownComparisonTypeException(const std::string& comparison_type)
00118             : PionException("Could not parse unknown comparison type: ", comparison_type) {}
00119     };
00120 
00122     class InvalidComparisonException : public std::exception {
00123     public:
00124         virtual const char* what() const throw() {
00125             return "An invalid comparison was attempted";
00126         }
00127     };
00128 
00130     class InvalidTypeForTermException : public std::exception {
00131     public:
00132         virtual const char* what() const throw() {
00133             return "Invalid comparison type given for Vocabulary Term";
00134         }
00135     };
00136 
00138     class InvalidValueForTypeException : public std::exception {
00139     public:
00140         virtual const char* what() const throw() {
00141             return "Invalid value given for comparison type";
00142         }
00143     };
00144 
00145 
00147     virtual ~Comparison() {}
00148 
00154     explicit Comparison(const Vocabulary::Term& term)
00155         : m_term(term), m_type(TYPE_FALSE), m_match_all_values(false)
00156     {}
00157 
00159     Comparison(const Comparison& c)
00160         : m_term(c.m_term), m_type(c.m_type), m_value(c.m_value),
00161         m_str_value(c.m_str_value), m_comparison_func(c.m_comparison_func), 
00162         m_regex(c.m_regex), m_match_all_values(c.m_match_all_values)
00163     {}
00164 
00172     inline bool evaluate(const Event& e) const;
00173 
00181     inline bool evaluateRange(const Event::ValuesRange& values_range) const;
00182 
00190     template <typename T>
00191     inline void configure(const ComparisonType type,
00192                           const T& value,
00193                           const bool match_all_values = false);
00194 
00202     inline void configure(const ComparisonType type, const char *value,
00203                           const bool match_all_values = false)
00204     {
00205         std::string value_str(value);
00206         configure(type, value_str, match_all_values);
00207     }
00208 
00216     void configure(const ComparisonType type, const std::string &value,
00217                    const bool match_all_values = false);
00218 
00224     void configure(const ComparisonType type);
00225 
00232     void updateVocabulary(const Vocabulary& v);
00233 
00234 
00236     inline const Vocabulary::Term& getTerm(void) const { return m_term; }
00237 
00239     inline ComparisonType getType(void) const { return m_type; }
00240 
00242     inline const Event::ParameterValue& getValue(void) const { return m_value; }
00243 
00245     inline bool getMatchAllValues(void) const { return m_match_all_values; }
00246 
00248     inline const boost::u32regex& getRegex(void) const { return m_regex; }
00249 
00251     inline const std::string& getRegexStr(void) const { return m_regex_str; }
00252 
00259     static ComparisonType parseComparisonType(std::string str);
00260 
00267     static std::string getComparisonTypeAsString(const ComparisonType comparison_type);
00268 
00270     static bool requiresValue(ComparisonType t);
00271 
00272     static void writeComparisonsXML(std::ostream& out);
00273 
00274 private:
00275 
00277     template <typename T>
00278     class CompareEquals {
00279     public:
00280         CompareEquals(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00281         inline bool operator()(const Event::ParameterValue& event_value) const {
00282             return boost::get<const T&>(event_value) == m_value;
00283         }
00284     private:
00285         const T&    m_value;
00286     };
00287 
00289     template <typename T>
00290     class CompareGreaterThan {
00291     public:
00292         CompareGreaterThan(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00293         inline bool operator()(const Event::ParameterValue& event_value) const {
00294             return boost::get<const T&>(event_value) > m_value;
00295         }
00296     private:
00297         const T&    m_value;
00298     };
00299 
00301     template <typename T>
00302     class CompareLessThan {
00303     public:
00304         CompareLessThan(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00305         inline bool operator()(const Event::ParameterValue& event_value) const {
00306             return boost::get<const T&>(event_value) < m_value;
00307         }
00308     private:
00309         const T&    m_value;
00310     };
00311 
00313     template <typename T>
00314     class CompareGreaterOrEqual {
00315     public:
00316         CompareGreaterOrEqual(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00317         inline bool operator()(const Event::ParameterValue& event_value) const {
00318             return boost::get<const T&>(event_value) >= m_value;
00319         }
00320     private:
00321         const T&    m_value;
00322     };
00323 
00325     template <typename T>
00326     class CompareLessOrEqual {
00327     public:
00328         CompareLessOrEqual(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00329         inline bool operator()(const Event::ParameterValue& event_value) const {
00330             return boost::get<const T&>(event_value) <= m_value;
00331         }
00332     private:
00333         const T&    m_value;
00334     };
00335 
00336     class ComparisonFunctor {
00337     public:
00338         ComparisonFunctor(const std::string& value, UColAttributeValue attr);
00339         virtual ~ComparisonFunctor();
00340 
00341         virtual bool operator()(const Event::ParameterValue& event_value) const = 0;
00342 
00343     protected:
00344         int32_t         m_pattern_buf_len;
00345         UChar*          m_pattern_buf;
00346         UCollator*      m_collator;
00347     };
00348 
00350     class CompareStringExactMatch : public ComparisonFunctor {
00351     public:
00352         CompareStringExactMatch(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00353         ~CompareStringExactMatch() {}
00354 
00355         virtual bool operator()(const Event::ParameterValue& event_value) const {
00356             UCharIterator text_iter, pattern_iter;
00357             const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00358             uiter_setUTF8(&text_iter, blob.get(), blob.size());
00359             uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00360             UErrorCode errorCode = U_ZERO_ERROR;
00361             UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00362             // TODO: check errorCode.
00363             return (result == UCOL_EQUAL);
00364         }
00365     };
00366 
00368     class CompareStringContains : public ComparisonFunctor {
00369     public:
00370         CompareStringContains(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00371         ~CompareStringContains() {}
00372 
00373         virtual bool operator()(const Event::ParameterValue& event_value) const {
00380             //UnicodeString text = UnicodeString::fromUTF8(boost::get<const Event::BlobType&>(event_value).get());
00381 
00382             const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00383             int32_t text_buf_len;
00384             UErrorCode errorCode = U_ZERO_ERROR;
00385             u_strFromUTF8(NULL, 0, &text_buf_len, blob.get(), blob.size(), &errorCode);
00386             errorCode = U_ZERO_ERROR; // Need to reset, because u_strFromUTF8 returns U_BUFFER_OVERFLOW_ERROR when destCapacity = 0.
00387             boost::scoped_array<UChar> text_buf(new UChar[text_buf_len]);
00388             u_strFromUTF8(text_buf.get(), text_buf_len, NULL, blob.get(), blob.size(), &errorCode);
00389             // Use u_strFromUTF8Lenient instead?
00390             UStringSearch* ss = usearch_openFromCollator(m_pattern_buf, m_pattern_buf_len, text_buf.get(), text_buf_len, m_collator, NULL, &errorCode);
00391             int pos = usearch_first(ss, &errorCode);
00392             usearch_close(ss);
00393             // TODO: check errorCode.
00394             return (pos != USEARCH_DONE);
00395         }
00396     };
00397 
00399     class CompareStringStartsWith : public ComparisonFunctor {
00400     public:
00401         CompareStringStartsWith(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00402         ~CompareStringStartsWith();
00403 
00404         virtual bool operator()(const Event::ParameterValue& event_value) const {
00405             // Create a code unit iterator from the Event value.
00406             const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00407             UCharIterator text_iter;
00408             uiter_setUTF8(&text_iter, blob.get(), blob.size());
00409 
00410             // Populate a buffer by parsing UTF-8 bytes from the blob into code units, until the number of code units is the same as in the pattern.
00411             boost::scoped_array<UChar> text_prefix_buf(new UChar[m_pattern_buf_len]);
00412             int i;
00413             for (i = 0; i < m_pattern_buf_len; ++i) {
00414                 UChar32 c = text_iter.next(&text_iter);
00415                 if (c == U_SENTINEL) {
00416                     // If the iteration failed, the text is too short to start with the pattern, so return false.
00417                     return false;
00418                 }
00419                 text_prefix_buf[i] = c;
00420             }
00421 
00422             UCollationResult result = ucol_strcoll(m_collator, text_prefix_buf.get(), m_pattern_buf_len, m_pattern_buf, m_pattern_buf_len);
00423             return (result == UCOL_EQUAL);
00424         }
00425     };
00426 
00428     class CompareStringEndsWith : public ComparisonFunctor {
00429     public:
00430         CompareStringEndsWith(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00431         ~CompareStringEndsWith() {}
00432 
00433         virtual bool operator()(const Event::ParameterValue& event_value) const {
00434             // Create a code unit iterator from the Event value.
00435             const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00436             UCharIterator text_iter;
00437             uiter_setUTF8(&text_iter, blob.get(), blob.size());
00438 
00439             // Try to iterate back m_pattern_buf_len code units from the end (where m_pattern_buf_len is the number of code units in the pattern).
00440             int32_t p = text_iter.move(&text_iter, -m_pattern_buf_len, UITER_LIMIT);
00441 
00442             // If the iteration failed, the text is too short to end with the pattern, so return false.
00443             if (p == U_SENTINEL)
00444                 return false;
00445 
00446             // Compare the last m_pattern_buf_len code units of the text with all m_pattern_buf_len code units of the pattern.
00447             UCharIterator pattern_iter;
00448             uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00449             UErrorCode errorCode = U_ZERO_ERROR;
00450             UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00451             // TODO: check errorCode.
00452             return (result == UCOL_EQUAL);
00453         }
00454     };
00455 
00457     class CompareStringOrderedBefore : public ComparisonFunctor {
00458     public:
00459         CompareStringOrderedBefore(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00460         ~CompareStringOrderedBefore() {}
00461 
00462         virtual bool operator()(const Event::ParameterValue& event_value) const {
00463             UCharIterator text_iter, pattern_iter;
00464             const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00465             uiter_setUTF8(&text_iter, blob.get(), blob.size());
00466             uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00467             UErrorCode errorCode = U_ZERO_ERROR;
00468             UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00469             // TODO: check errorCode.
00470             return (result == UCOL_LESS);
00471         }
00472     };
00473 
00475     class CompareStringOrderedAfter : public ComparisonFunctor {
00476     public:
00477         CompareStringOrderedAfter(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00478         ~CompareStringOrderedAfter() {}
00479 
00480         virtual bool operator()(const Event::ParameterValue& event_value) const {
00481             UCharIterator text_iter, pattern_iter;
00482             const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00483             uiter_setUTF8(&text_iter, blob.get(), blob.size());
00484             uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00485             UErrorCode errorCode = U_ZERO_ERROR;
00486             UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00487             // TODO: check errorCode.
00488             return (result == UCOL_GREATER);
00489         }
00490     };
00491 
00493     class CompareStringRegex {
00494     public:
00495         CompareStringRegex(const boost::u32regex& value) : m_regex(value) {}
00496         inline bool operator()(const Event::ParameterValue& event_value) const {
00497             // note: regex_match must match the ENTIRE string; use regex_search
00498             // instead to match any part of the string
00499             return boost::u32regex_search(
00500                 boost::get<const Event::BlobType&>(event_value).get(), m_regex);
00501         }
00502     private:
00503         const boost::u32regex&  m_regex;
00504     };
00505 
00507     class CompareSameDateTime {
00508     public:
00509         CompareSameDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00510         inline bool operator()(const Event::ParameterValue& event_value) const {
00511             return boost::get<const PionDateTime&>(event_value) == m_value;
00512         }
00513     private:
00514         const PionDateTime& m_value;
00515     };
00516 
00518     class CompareEarlierDateTime {
00519     public:
00520         CompareEarlierDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00521         inline bool operator()(const Event::ParameterValue& event_value) const {
00522             return boost::get<const PionDateTime&>(event_value) < m_value;
00523         }
00524     private:
00525         const PionDateTime& m_value;
00526     };
00527 
00529     class CompareLaterDateTime {
00530     public:
00531         CompareLaterDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00532         inline bool operator()(const Event::ParameterValue& event_value) const {
00533             return boost::get<const PionDateTime&>(event_value) > m_value;
00534         }
00535     private:
00536         const PionDateTime& m_value;
00537     };
00538 
00540     class CompareSameOrEarlierDateTime {
00541     public:
00542         CompareSameOrEarlierDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00543         inline bool operator()(const Event::ParameterValue& event_value) const {
00544             return boost::get<const PionDateTime&>(event_value) <= m_value;
00545         }
00546     private:
00547         const PionDateTime& m_value;
00548     };
00549 
00551     class CompareSameOrLaterDateTime {
00552     public:
00553         CompareSameOrLaterDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00554         inline bool operator()(const Event::ParameterValue& event_value) const {
00555             return boost::get<const PionDateTime&>(event_value) >= m_value;
00556         }
00557     private:
00558         const PionDateTime& m_value;
00559     };
00560 
00562     class CompareSameDate {
00563     public:
00564         CompareSameDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00565         inline bool operator()(const Event::ParameterValue& event_value) const {
00566             return boost::get<const PionDateTime&>(event_value).date() == m_value.date();
00567         }
00568     private:
00569         const PionDateTime& m_value;
00570     };
00571 
00573     class CompareEarlierDate {
00574     public:
00575         CompareEarlierDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00576         inline bool operator()(const Event::ParameterValue& event_value) const {
00577             return boost::get<const PionDateTime&>(event_value).date() < m_value.date();
00578         }
00579     private:
00580         const PionDateTime& m_value;
00581     };
00582 
00584     class CompareLaterDate {
00585     public:
00586         CompareLaterDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00587         inline bool operator()(const Event::ParameterValue& event_value) const {
00588             return boost::get<const PionDateTime&>(event_value).date() > m_value.date();
00589         }
00590     private:
00591         const PionDateTime& m_value;
00592     };
00593 
00595     class CompareSameOrEarlierDate {
00596     public:
00597         CompareSameOrEarlierDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00598         inline bool operator()(const Event::ParameterValue& event_value) const {
00599             return boost::get<const PionDateTime&>(event_value).date() <= m_value.date();
00600         }
00601     private:
00602         const PionDateTime& m_value;
00603     };
00604 
00606     class CompareSameOrLaterDate {
00607     public:
00608         CompareSameOrLaterDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00609         inline bool operator()(const Event::ParameterValue& event_value) const {
00610             return boost::get<const PionDateTime&>(event_value).date() >= m_value.date();
00611         }
00612     private:
00613         const PionDateTime& m_value;
00614     };
00615 
00617     class CompareSameTime {
00618     public:
00619         CompareSameTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00620         inline bool operator()(const Event::ParameterValue& event_value) const {
00621             return boost::get<const PionDateTime&>(event_value).time_of_day() == m_value.time_of_day();
00622         }
00623     private:
00624         const PionDateTime& m_value;
00625     };
00626 
00628     class CompareEarlierTime {
00629     public:
00630         CompareEarlierTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00631         inline bool operator()(const Event::ParameterValue& event_value) const {
00632             return boost::get<const PionDateTime&>(event_value).time_of_day() < m_value.time_of_day();
00633         }
00634     private:
00635         const PionDateTime& m_value;
00636     };
00637 
00639     class CompareLaterTime {
00640     public:
00641         CompareLaterTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00642         inline bool operator()(const Event::ParameterValue& event_value) const {
00643             return boost::get<const PionDateTime&>(event_value).time_of_day() > m_value.time_of_day();
00644         }
00645     private:
00646         const PionDateTime& m_value;
00647     };
00648 
00650     class CompareSameOrEarlierTime {
00651     public:
00652         CompareSameOrEarlierTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00653         inline bool operator()(const Event::ParameterValue& event_value) const {
00654             return boost::get<const PionDateTime&>(event_value).time_of_day() <= m_value.time_of_day();
00655         }
00656     private:
00657         const PionDateTime& m_value;
00658     };
00659 
00661     class CompareSameOrLaterTime {
00662     public:
00663         CompareSameOrLaterTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00664         inline bool operator()(const Event::ParameterValue& event_value) const {
00665             return boost::get<const PionDateTime&>(event_value).time_of_day() >= m_value.time_of_day();
00666         }
00667     private:
00668         const PionDateTime& m_value;
00669     };
00670 
00671 
00679     bool checkForValidType(const ComparisonType type) const;
00680 
00691     template <typename ComparisonFunction>
00692     inline bool checkComparison(const ComparisonFunction& comparison_func,
00693                                 const Event::ValuesRange& values_range) const;
00694 
00696     Vocabulary::Term            m_term;
00697 
00699     ComparisonType              m_type;
00700 
00702     Event::ParameterValue       m_value;
00703 
00705     std::string                 m_str_value;
00706 
00707     boost::shared_ptr<ComparisonFunctor>
00708                                 m_comparison_func;
00709 
00711     boost::u32regex             m_regex;
00712 
00714     std::string                 m_regex_str;
00715 
00717     bool                        m_match_all_values;
00718 };
00719 
00720 
00721 
00722 template <typename T>
00723 inline void Comparison::configure(const ComparisonType type,
00724                                   const T& value,
00725                                   const bool match_all_values)
00726 {
00727     if (! checkForValidType(type))
00728         throw InvalidTypeForTermException();
00729 
00730     m_type = type;
00731     m_value = value;
00732     m_match_all_values = match_all_values;
00733 
00734     // make sure the value matches the comparison type
00735     switch (m_term.term_type) {
00736         case Vocabulary::TYPE_NULL:
00737         case Vocabulary::TYPE_OBJECT:
00738             throw InvalidValueForTypeException();
00739             break;
00740         case Vocabulary::TYPE_INT8:
00741         case Vocabulary::TYPE_INT16:
00742         case Vocabulary::TYPE_INT32:
00743             if (boost::get<boost::int32_t>(&m_value) == NULL)
00744                 throw InvalidValueForTypeException();
00745             break;
00746         case Vocabulary::TYPE_UINT8:
00747         case Vocabulary::TYPE_UINT16:
00748         case Vocabulary::TYPE_UINT32:
00749             if (boost::get<boost::uint32_t>(&m_value) == NULL)
00750                 throw InvalidValueForTypeException();
00751             break;
00752         case Vocabulary::TYPE_INT64:
00753             if (boost::get<boost::int64_t>(&m_value) == NULL)
00754                 throw InvalidValueForTypeException();
00755             break;
00756         case Vocabulary::TYPE_UINT64:
00757             if (boost::get<boost::uint64_t>(&m_value) == NULL)
00758                 throw InvalidValueForTypeException();
00759             break;
00760         case Vocabulary::TYPE_FLOAT:
00761             if (boost::get<float>(&m_value) == NULL)
00762                 throw InvalidValueForTypeException();
00763             break;
00764         case Vocabulary::TYPE_DOUBLE:
00765             if (boost::get<double>(&m_value) == NULL)
00766                 throw InvalidValueForTypeException();
00767             break;
00768         case Vocabulary::TYPE_LONG_DOUBLE:
00769             if (boost::get<long double>(&m_value) == NULL)
00770                 throw InvalidValueForTypeException();
00771             break;
00772         case Vocabulary::TYPE_SHORT_STRING:
00773         case Vocabulary::TYPE_STRING:
00774         case Vocabulary::TYPE_LONG_STRING:
00775         case Vocabulary::TYPE_CHAR:
00776         case Vocabulary::TYPE_BLOB:
00777         case Vocabulary::TYPE_ZBLOB:
00778             throw InvalidValueForTypeException();
00779             break;
00780         case Vocabulary::TYPE_DATE_TIME:
00781         case Vocabulary::TYPE_DATE:
00782         case Vocabulary::TYPE_TIME:
00783             if (boost::get<PionDateTime>(&m_value) == NULL)
00784                 throw InvalidValueForTypeException();
00785             break;
00786     }
00787 }
00788 
00789 //************************************************************************************************************************************************
00790 
00791 // inline member functions for Comparison
00792 
00793 template <typename ComparisonFunction>
00794 inline bool Comparison::checkComparison(const ComparisonFunction& comparison_func,
00795                                         const Event::ValuesRange& values_range) const
00796 {
00797     boost::tribool result = boost::indeterminate;
00798 //  Event::ConstIterator value = values_range.second;
00799 
00800     for (Event::ConstIterator i = values_range.first;
00801          i != values_range.second; ++i)
00802     {
00803         if (comparison_func(i->value)) {
00804             if (! m_match_all_values) {
00805                 result = true;
00806 //              value = i;
00807                 break;
00808             }
00809         } else {
00810             if (m_match_all_values) {
00811                 result = false;
00812                 break;
00813             }
00814         }
00815     }
00816 
00817     if (boost::indeterminate(result))
00818         result = m_match_all_values;
00819 
00820     return result;
00821 }
00822 
00823 
00824 // This method now evaluates only a values_range, in order to support TransformReactor2
00825 // See Comparison::evaluate() on how values_range is defined, and the special case of *_DEFINED
00826 inline bool Comparison::evaluateRange(const Event::ValuesRange& values_range) const
00827 {
00828     bool result = false;
00829     bool negate_result = false;
00830 
00831     switch (m_type) {
00832         case TYPE_FALSE:
00833             result = false;
00834             break;
00835         case TYPE_TRUE:
00836             result = true;
00837             break;
00838         case TYPE_IS_DEFINED:
00839             result = (values_range.first != values_range.second);
00840             break;
00841         case TYPE_IS_NOT_DEFINED:
00842             result = (values_range.first == values_range.second);
00843             break;
00844 
00845         case TYPE_EQUALS:
00846         case TYPE_NOT_EQUALS:
00847             switch (m_term.term_type) {
00848                 case Vocabulary::TYPE_INT8:
00849                 case Vocabulary::TYPE_INT16:
00850                 case Vocabulary::TYPE_INT32:
00851                 {
00852                     CompareEquals<boost::int32_t> comparison_func(m_value);
00853                     result = checkComparison(comparison_func, values_range);
00854                     break;
00855                 }
00856                 case Vocabulary::TYPE_INT64:
00857                 {
00858                     CompareEquals<boost::int64_t> comparison_func(m_value);
00859                     result = checkComparison(comparison_func, values_range);
00860                     break;
00861                 }
00862                 case Vocabulary::TYPE_UINT8:
00863                 case Vocabulary::TYPE_UINT16:
00864                 case Vocabulary::TYPE_UINT32:
00865                 {
00866                     CompareEquals<boost::uint32_t> comparison_func(m_value);
00867                     result = checkComparison(comparison_func, values_range);
00868                     break;
00869                 }
00870                 case Vocabulary::TYPE_UINT64:
00871                 {
00872                     CompareEquals<boost::uint64_t> comparison_func(m_value);
00873                     result = checkComparison(comparison_func, values_range);
00874                     break;
00875                 }
00876                 case Vocabulary::TYPE_FLOAT:
00877                 {
00878                     CompareEquals<float> comparison_func(m_value);
00879                     result = checkComparison(comparison_func, values_range);
00880                     break;
00881                 }
00882                 case Vocabulary::TYPE_DOUBLE:
00883                 {
00884                     CompareEquals<double> comparison_func(m_value);
00885                     result = checkComparison(comparison_func, values_range);
00886                     break;
00887                 }
00888                 case Vocabulary::TYPE_LONG_DOUBLE:
00889                 {
00890                     CompareEquals<long double> comparison_func(m_value);
00891                     result = checkComparison(comparison_func, values_range);
00892                     break;
00893                 }
00894                 default:
00895                     throw InvalidComparisonException();
00896             }
00897             if (m_type == TYPE_NOT_EQUALS)
00898                 result = !result;
00899             break;
00900 
00901         case TYPE_GREATER_THAN:
00902             switch (m_term.term_type) {
00903                 case Vocabulary::TYPE_INT8:
00904                 case Vocabulary::TYPE_INT16:
00905                 case Vocabulary::TYPE_INT32:
00906                 {
00907                     CompareGreaterThan<boost::int32_t> comparison_func(m_value);
00908                     result = checkComparison(comparison_func, values_range);
00909                     break;
00910                 }
00911                 case Vocabulary::TYPE_INT64:
00912                 {
00913                     CompareGreaterThan<boost::int64_t> comparison_func(m_value);
00914                     result = checkComparison(comparison_func, values_range);
00915                     break;
00916                 }
00917                 case Vocabulary::TYPE_UINT8:
00918                 case Vocabulary::TYPE_UINT16:
00919                 case Vocabulary::TYPE_UINT32:
00920                 {
00921                     CompareGreaterThan<boost::uint32_t> comparison_func(m_value);
00922                     result = checkComparison(comparison_func, values_range);
00923                     break;
00924                 }
00925                 case Vocabulary::TYPE_UINT64:
00926                 {
00927                     CompareGreaterThan<boost::uint64_t> comparison_func(m_value);
00928                     result = checkComparison(comparison_func, values_range);
00929                     break;
00930                 }
00931                 case Vocabulary::TYPE_FLOAT:
00932                 {
00933                     CompareGreaterThan<float> comparison_func(m_value);
00934                     result = checkComparison(comparison_func, values_range);
00935                     break;
00936                 }
00937                 case Vocabulary::TYPE_DOUBLE:
00938                 {
00939                     CompareGreaterThan<double> comparison_func(m_value);
00940                     result = checkComparison(comparison_func, values_range);
00941                     break;
00942                 }
00943                 case Vocabulary::TYPE_LONG_DOUBLE:
00944                 {
00945                     CompareGreaterThan<long double> comparison_func(m_value);
00946                     result = checkComparison(comparison_func, values_range);
00947                     break;
00948                 }
00949                 default:
00950                     throw InvalidComparisonException();
00951             }
00952             break;
00953 
00954         case TYPE_LESS_THAN:
00955             switch (m_term.term_type) {
00956                 case Vocabulary::TYPE_INT8:
00957                 case Vocabulary::TYPE_INT16:
00958                 case Vocabulary::TYPE_INT32:
00959                 {
00960                     CompareLessThan<boost::int32_t> comparison_func(m_value);
00961                     result = checkComparison(comparison_func, values_range);
00962                     break;
00963                 }
00964                 case Vocabulary::TYPE_INT64:
00965                 {
00966                     CompareLessThan<boost::int64_t> comparison_func(m_value);
00967                     result = checkComparison(comparison_func, values_range);
00968                     break;
00969                 }
00970                 case Vocabulary::TYPE_UINT8:
00971                 case Vocabulary::TYPE_UINT16:
00972                 case Vocabulary::TYPE_UINT32:
00973                 {
00974                     CompareLessThan<boost::uint32_t> comparison_func(m_value);
00975                     result = checkComparison(comparison_func, values_range);
00976                     break;
00977                 }
00978                 case Vocabulary::TYPE_UINT64:
00979                 {
00980                     CompareLessThan<boost::uint64_t> comparison_func(m_value);
00981                     result = checkComparison(comparison_func, values_range);
00982                     break;
00983                 }
00984                 case Vocabulary::TYPE_FLOAT:
00985                 {
00986                     CompareLessThan<float> comparison_func(m_value);
00987                     result = checkComparison(comparison_func, values_range);
00988                     break;
00989                 }
00990                 case Vocabulary::TYPE_DOUBLE:
00991                 {
00992                     CompareLessThan<double> comparison_func(m_value);
00993                     result = checkComparison(comparison_func, values_range);
00994                     break;
00995                 }
00996                 case Vocabulary::TYPE_LONG_DOUBLE:
00997                 {
00998                     CompareLessThan<long double> comparison_func(m_value);
00999                     result = checkComparison(comparison_func, values_range);
01000                     break;
01001                 }
01002                 default:
01003                     throw InvalidComparisonException();
01004             }
01005             break;
01006 
01007         case TYPE_GREATER_OR_EQUAL:
01008             switch (m_term.term_type) {
01009                 case Vocabulary::TYPE_INT8:
01010                 case Vocabulary::TYPE_INT16:
01011                 case Vocabulary::TYPE_INT32:
01012                 {
01013                     CompareGreaterOrEqual<boost::int32_t> comparison_func(m_value);
01014                     result = checkComparison(comparison_func, values_range);
01015                     break;
01016                 }
01017                 case Vocabulary::TYPE_INT64:
01018                 {
01019                     CompareGreaterOrEqual<boost::int64_t> comparison_func(m_value);
01020                     result = checkComparison(comparison_func, values_range);
01021                     break;
01022                 }
01023                 case Vocabulary::TYPE_UINT8:
01024                 case Vocabulary::TYPE_UINT16:
01025                 case Vocabulary::TYPE_UINT32:
01026                 {
01027                     CompareGreaterOrEqual<boost::uint32_t> comparison_func(m_value);
01028                     result = checkComparison(comparison_func, values_range);
01029                     break;
01030                 }
01031                 case Vocabulary::TYPE_UINT64:
01032                 {
01033                     CompareGreaterOrEqual<boost::uint64_t> comparison_func(m_value);
01034                     result = checkComparison(comparison_func, values_range);
01035                     break;
01036                 }
01037                 case Vocabulary::TYPE_FLOAT:
01038                 {
01039                     CompareGreaterOrEqual<float> comparison_func(m_value);
01040                     result = checkComparison(comparison_func, values_range);
01041                     break;
01042                 }
01043                 case Vocabulary::TYPE_DOUBLE:
01044                 {
01045                     CompareGreaterOrEqual<double> comparison_func(m_value);
01046                     result = checkComparison(comparison_func, values_range);
01047                     break;
01048                 }
01049                 case Vocabulary::TYPE_LONG_DOUBLE:
01050                 {
01051                     CompareGreaterOrEqual<long double> comparison_func(m_value);
01052                     result = checkComparison(comparison_func, values_range);
01053                     break;
01054                 }
01055                 default:
01056                     throw InvalidComparisonException();
01057             }
01058             break;
01059 
01060         case TYPE_LESS_OR_EQUAL:
01061             switch (m_term.term_type) {
01062                 case Vocabulary::TYPE_INT8:
01063                 case Vocabulary::TYPE_INT16:
01064                 case Vocabulary::TYPE_INT32:
01065                 {
01066                     CompareLessOrEqual<boost::int32_t> comparison_func(m_value);
01067                     result = checkComparison(comparison_func, values_range);
01068                     break;
01069                 }
01070                 case Vocabulary::TYPE_INT64:
01071                 {
01072                     CompareLessOrEqual<boost::int64_t> comparison_func(m_value);
01073                     result = checkComparison(comparison_func, values_range);
01074                     break;
01075                 }
01076                 case Vocabulary::TYPE_UINT8:
01077                 case Vocabulary::TYPE_UINT16:
01078                 case Vocabulary::TYPE_UINT32:
01079                 {
01080                     CompareLessOrEqual<boost::uint32_t> comparison_func(m_value);
01081                     result = checkComparison(comparison_func, values_range);
01082                     break;
01083                 }
01084                 case Vocabulary::TYPE_UINT64:
01085                 {
01086                     CompareLessOrEqual<boost::uint64_t> comparison_func(m_value);
01087                     result = checkComparison(comparison_func, values_range);
01088                     break;
01089                 }
01090                 case Vocabulary::TYPE_FLOAT:
01091                 {
01092                     CompareLessOrEqual<float> comparison_func(m_value);
01093                     result = checkComparison(comparison_func, values_range);
01094                     break;
01095                 }
01096                 case Vocabulary::TYPE_DOUBLE:
01097                 {
01098                     CompareLessOrEqual<double> comparison_func(m_value);
01099                     result = checkComparison(comparison_func, values_range);
01100                     break;
01101                 }
01102                 case Vocabulary::TYPE_LONG_DOUBLE:
01103                 {
01104                     CompareLessOrEqual<long double> comparison_func(m_value);
01105                     result = checkComparison(comparison_func, values_range);
01106                     break;
01107                 }
01108                 default:
01109                     throw InvalidComparisonException();
01110             }
01111             break;
01112 
01113         case TYPE_NOT_EXACT_MATCH:
01114         case TYPE_NOT_EXACT_MATCH_PRIMARY:
01115         case TYPE_NOT_CONTAINS:
01116         case TYPE_NOT_CONTAINS_PRIMARY:
01117         case TYPE_NOT_STARTS_WITH:
01118         case TYPE_NOT_STARTS_WITH_PRIMARY:
01119         case TYPE_NOT_ENDS_WITH:
01120         case TYPE_NOT_ENDS_WITH_PRIMARY:
01121         case TYPE_NOT_ORDERED_BEFORE:
01122         case TYPE_NOT_ORDERED_BEFORE_PRIMARY:
01123         case TYPE_NOT_ORDERED_AFTER:
01124         case TYPE_NOT_ORDERED_AFTER_PRIMARY:
01125             negate_result = true;
01126         case TYPE_EXACT_MATCH:
01127         case TYPE_EXACT_MATCH_PRIMARY:
01128         case TYPE_CONTAINS:
01129         case TYPE_CONTAINS_PRIMARY:
01130         case TYPE_STARTS_WITH:
01131         case TYPE_STARTS_WITH_PRIMARY:
01132         case TYPE_ENDS_WITH:
01133         case TYPE_ENDS_WITH_PRIMARY:
01134         case TYPE_ORDERED_BEFORE:
01135         case TYPE_ORDERED_BEFORE_PRIMARY:
01136         case TYPE_ORDERED_AFTER:
01137         case TYPE_ORDERED_AFTER_PRIMARY:
01138             switch (m_term.term_type) {
01139                 case Vocabulary::TYPE_SHORT_STRING:
01140                 case Vocabulary::TYPE_STRING:
01141                 case Vocabulary::TYPE_LONG_STRING:
01142                 case Vocabulary::TYPE_CHAR:
01143                 case Vocabulary::TYPE_BLOB:
01144                 case Vocabulary::TYPE_ZBLOB:
01145                     result = checkComparison(*m_comparison_func, values_range);
01146                     break;
01147                 default:
01148                     throw InvalidComparisonException();
01149             }
01150             if (negate_result)
01151                 result = !result;
01152             break;
01153 
01154         case TYPE_REGEX:
01155         case TYPE_NOT_REGEX:
01156             switch (m_term.term_type) {
01157                 case Vocabulary::TYPE_SHORT_STRING:
01158                 case Vocabulary::TYPE_STRING:
01159                 case Vocabulary::TYPE_LONG_STRING:
01160                 case Vocabulary::TYPE_CHAR:
01161                 case Vocabulary::TYPE_BLOB:
01162                 case Vocabulary::TYPE_ZBLOB:
01163                 {
01164                     CompareStringRegex comparison_func(m_regex);
01165                     result = checkComparison(comparison_func, values_range);
01166                     break;
01167                 }
01168                 default:
01169                     throw InvalidComparisonException();
01170             }
01171             if (m_type == TYPE_NOT_REGEX)
01172                 result = !result;
01173             break;
01174 
01175         case TYPE_SAME_DATE_TIME:
01176         case TYPE_NOT_SAME_DATE_TIME:
01177         {
01178             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01179             CompareSameDateTime comparison_func(m_value);
01180             result = checkComparison(comparison_func, values_range);
01181             if (m_type == TYPE_NOT_SAME_DATE_TIME)
01182                 result = !result;
01183             break;
01184         }
01185 
01186         case TYPE_EARLIER_DATE_TIME:
01187         {
01188             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01189             CompareEarlierDateTime comparison_func(m_value);
01190             result = checkComparison(comparison_func, values_range);
01191             break;
01192         }
01193 
01194         case TYPE_LATER_DATE_TIME:
01195         {
01196             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01197             CompareLaterDateTime comparison_func(m_value);
01198             result = checkComparison(comparison_func, values_range);
01199             break;
01200         }
01201 
01202         case TYPE_SAME_OR_EARLIER_DATE_TIME:
01203         {
01204             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01205             CompareSameOrEarlierDateTime comparison_func(m_value);
01206             result = checkComparison(comparison_func, values_range);
01207             break;
01208         }
01209 
01210         case TYPE_SAME_OR_LATER_DATE_TIME:
01211         {
01212             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01213             CompareSameOrLaterDateTime comparison_func(m_value);
01214             result = checkComparison(comparison_func, values_range);
01215             break;
01216         }
01217 
01218         case TYPE_SAME_DATE:
01219         case TYPE_NOT_SAME_DATE:
01220         {
01221             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01222             CompareSameDate comparison_func(m_value);
01223             result = checkComparison(comparison_func, values_range);
01224             if (m_type == TYPE_NOT_SAME_DATE)
01225                 result = !result;
01226             break;
01227         }
01228 
01229         case TYPE_EARLIER_DATE:
01230         {
01231             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01232             CompareEarlierDate comparison_func(m_value);
01233             result = checkComparison(comparison_func, values_range);
01234             break;
01235         }
01236 
01237         case TYPE_LATER_DATE:
01238         {
01239             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01240             CompareLaterDate comparison_func(m_value);
01241             result = checkComparison(comparison_func, values_range);
01242             break;
01243         }
01244 
01245         case TYPE_SAME_OR_EARLIER_DATE:
01246         {
01247             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01248             CompareSameOrEarlierDate comparison_func(m_value);
01249             result = checkComparison(comparison_func, values_range);
01250             break;
01251         }
01252 
01253         case TYPE_SAME_OR_LATER_DATE:
01254         {
01255             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01256             CompareSameOrLaterDate comparison_func(m_value);
01257             result = checkComparison(comparison_func, values_range);
01258             break;
01259         }
01260 
01261         case TYPE_SAME_TIME:
01262         case TYPE_NOT_SAME_TIME:
01263         {
01264             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01265             CompareSameTime comparison_func(m_value);
01266             result = checkComparison(comparison_func, values_range);
01267             if (m_type == TYPE_NOT_SAME_TIME)
01268                 result = !result;
01269             break;
01270         }
01271 
01272         case TYPE_EARLIER_TIME:
01273         {
01274             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01275             CompareEarlierTime comparison_func(m_value);
01276             result = checkComparison(comparison_func, values_range);
01277             break;
01278         }
01279 
01280         case TYPE_LATER_TIME:
01281         {
01282             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01283             CompareLaterTime comparison_func(m_value);
01284             result = checkComparison(comparison_func, values_range);
01285             break;
01286         }
01287 
01288         case TYPE_SAME_OR_EARLIER_TIME:
01289         {
01290             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01291             CompareSameOrEarlierTime comparison_func(m_value);
01292             result = checkComparison(comparison_func, values_range);
01293             break;
01294         }
01295 
01296         case TYPE_SAME_OR_LATER_TIME:
01297         {
01298             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01299             CompareSameOrLaterTime comparison_func(m_value);
01300             result = checkComparison(comparison_func, values_range);
01301             break;
01302         }
01303     }
01304 
01305     return result;
01306 }
01307 
01308 // This is the refactored version of evaluate
01309 // Since IS_DEFINED and IS_NOT_DEFINED allow for looking at Event, in addition to range_value,
01310 // it was necessary to put some convoluted special-case logic here...
01311 inline bool Comparison::evaluate(const Event& e) const
01312 {
01313     if (m_type == TYPE_IS_DEFINED || m_type == TYPE_IS_NOT_DEFINED) {
01314         // If object type matches looked for type, return true -- refactored out of evaluateRange
01315         if (e.getType() == m_term.term_ref) return m_type == TYPE_IS_DEFINED;
01316     }
01318     Event::ValuesRange values_range = e.equal_range(m_term.term_ref);
01319     return Comparison::evaluateRange(values_range);
01320 }
01321 
01322 
01323 }   // end namespace platform
01324 }   // end namespace pion
01325 
01326 #endif

Generated on Wed Apr 13 16:38:34 2011 for pion-platform by  doxygen 1.4.7