Line data Source code
1 : /* 2 : * Distributed under the OpenDDS License. 3 : * See: http://www.opendds.org/license.html 4 : */ 5 : 6 : #ifndef OPENDDS_DCPS_COMPARATOR_T_H 7 : #define OPENDDS_DCPS_COMPARATOR_T_H 8 : 9 : #include <ace/config-macros.h> 10 : #ifndef ACE_LACKS_PRAGMA_ONCE 11 : # pragma once 12 : #endif 13 : 14 : #include "RcHandle_T.h" 15 : #include "RcObject.h" 16 : #include "RakeData.h" 17 : 18 : #include <ace/OS_NS_string.h> 19 : 20 : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL 21 : 22 : namespace OpenDDS { 23 : namespace DCPS { 24 : 25 : class ComparatorBase : public virtual RcObject { 26 : public: 27 : typedef RcHandle<ComparatorBase> Ptr; 28 : 29 : ComparatorBase(){} 30 0 : explicit ComparatorBase(Ptr next) : next_(next) {} 31 : 32 0 : virtual ~ComparatorBase() {} 33 : 34 : virtual bool less(void* lhs, void* rhs) const = 0; 35 : virtual bool equal(void* lhs, void* rhs) const = 0; 36 : 37 0 : bool compare(void* lhs, void* rhs) const { 38 0 : if (next_.in() && equal(lhs, rhs)) return next_->compare(lhs, rhs); 39 : 40 0 : return less(lhs, rhs); 41 : } 42 : 43 : private: 44 : Ptr next_; 45 : }; 46 : 47 : template <class Sample, class Field> 48 : class FieldComparator : public ComparatorBase { 49 : public: 50 : typedef Field Sample::* MemberPtr; 51 0 : FieldComparator(MemberPtr mp, ComparatorBase::Ptr next) 52 : : ComparatorBase(next) 53 0 : , mp_(mp) {} 54 : 55 0 : bool less(void* lhs_void, void* rhs_void) const { 56 0 : Sample* lhs = static_cast<Sample*>(lhs_void); 57 0 : Sample* rhs = static_cast<Sample*>(rhs_void); 58 : using ::operator<; // TAO::String_Manager's operator< is in global NS 59 0 : return lhs->*mp_ < rhs->*mp_; 60 : } 61 : 62 0 : bool equal(void* lhs_void, void* rhs_void) const { 63 0 : Sample* lhs = static_cast<Sample*>(lhs_void); 64 0 : Sample* rhs = static_cast<Sample*>(rhs_void); 65 0 : const Field& field_l = lhs->*mp_; 66 0 : const Field& field_r = rhs->*mp_; 67 : using ::operator<; // TAO::String_Manager's operator< is in global NS 68 0 : return !(field_l < field_r) && !(field_r < field_l); 69 : } 70 : 71 : private: 72 : MemberPtr mp_; 73 : }; 74 : 75 : template <class Sample, class Field> 76 0 : ComparatorBase::Ptr make_field_cmp(Field Sample::* mp, 77 : ComparatorBase::Ptr next) 78 : { 79 0 : return make_rch<FieldComparator<Sample, Field> >(mp, next); 80 : } 81 : 82 : /** deal with nested structs, for example: 83 : * struct A { long x; }; 84 : * struct B { A theA; }; 85 : * B's query string has "ORDER BY theA.x" 86 : * The generated code will create a StructComparator with 87 : * Sample = B and Field = A which in turn has a "delegate" which is 88 : * a FieldComparator (see above) with Sample = A and Field = CORBA::Long 89 : */ 90 : template <class Sample, class Field> 91 : class StructComparator : public ComparatorBase { 92 : public: 93 : typedef Field Sample::* MemberPtr; 94 0 : StructComparator(MemberPtr mp, ComparatorBase::Ptr delegate, 95 : ComparatorBase::Ptr next) 96 : : ComparatorBase(next) 97 0 : , mp_(mp) 98 0 : , delegate_(delegate) {} 99 : 100 0 : bool less(void* lhs_void, void* rhs_void) const { 101 0 : Sample* lhs = static_cast<Sample*>(lhs_void); 102 0 : Sample* rhs = static_cast<Sample*>(rhs_void); 103 0 : return delegate_->less(&(lhs->*mp_), &(rhs->*mp_)); 104 : } 105 : 106 0 : bool equal(void* lhs_void, void* rhs_void) const { 107 0 : Sample* lhs = static_cast<Sample*>(lhs_void); 108 0 : Sample* rhs = static_cast<Sample*>(rhs_void); 109 0 : return delegate_->equal(&(lhs->*mp_), &(rhs->*mp_)); 110 : } 111 : 112 : private: 113 : MemberPtr mp_; 114 : ComparatorBase::Ptr delegate_; 115 : }; 116 : 117 : template <class Sample, class Field> 118 0 : ComparatorBase::Ptr make_struct_cmp(Field Sample::* mp, 119 : ComparatorBase::Ptr delegate, 120 : ComparatorBase::Ptr next) 121 : { 122 0 : return make_rch<StructComparator<Sample, Field> >(mp, delegate, next); 123 : } 124 : 125 : } // namespace DCPS 126 : } // namespace OpenDDS 127 : 128 : OPENDDS_END_VERSIONED_NAMESPACE_DECL 129 : 130 : #endif