Comparator_T.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef COMPARATOR_H
00009 #define COMPARATOR_H
00010 
00011 #include /**/ "ace/pre.h"
00012 
00013 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00014 # pragma once
00015 #endif /* ACE_LACKS_PRAGMA_ONCE */
00016 
00017 #include "ace/OS_NS_string.h"
00018 
00019 #include "RcHandle_T.h"
00020 #include "RcObject_T.h"
00021 #include "RakeData.h"
00022 
00023 namespace OpenDDS {
00024 namespace DCPS {
00025 
00026 class ComparatorBase : public RcObject<ACE_SYNCH_MUTEX> {
00027 public:
00028   typedef RcHandle<ComparatorBase> Ptr;
00029 
00030   explicit ComparatorBase(Ptr next = 0) : next_(next) {}
00031 
00032   virtual ~ComparatorBase() {}
00033 
00034   virtual bool less(void* lhs, void* rhs) const = 0;
00035   virtual bool equal(void* lhs, void* rhs) const = 0;
00036 
00037   bool compare(void* lhs, void* rhs) const {
00038     if (next_.in() && equal(lhs, rhs)) return next_->compare(lhs, rhs);
00039 
00040     return less(lhs, rhs);
00041   }
00042 
00043 private:
00044   Ptr next_;
00045 };
00046 
00047 template <class Sample, class Field>
00048 class FieldComparator : public ComparatorBase {
00049 public:
00050   typedef Field Sample::* MemberPtr;
00051   FieldComparator(MemberPtr mp, ComparatorBase::Ptr next)
00052   : ComparatorBase(next)
00053   , mp_(mp) {}
00054 
00055   bool less(void* lhs_void, void* rhs_void) const {
00056     Sample* lhs = static_cast<Sample*>(lhs_void);
00057     Sample* rhs = static_cast<Sample*>(rhs_void);
00058     using ::operator<; // TAO::String_Manager's operator< is in global NS
00059     return lhs->*mp_ < rhs->*mp_;
00060   }
00061 
00062   bool equal(void* lhs_void, void* rhs_void) const {
00063     Sample* lhs = static_cast<Sample*>(lhs_void);
00064     Sample* rhs = static_cast<Sample*>(rhs_void);
00065     const Field& field_l = lhs->*mp_;
00066     const Field& field_r = rhs->*mp_;
00067     using ::operator<; // TAO::String_Manager's operator< is in global NS
00068     return !(field_l < field_r) && !(field_r < field_l);
00069   }
00070 
00071 private:
00072   MemberPtr mp_;
00073 };
00074 
00075 template <class Sample, class Field>
00076 ComparatorBase::Ptr make_field_cmp(Field Sample::* mp,
00077                                    ComparatorBase::Ptr next)
00078 {
00079   return new FieldComparator<Sample, Field>(mp, next);
00080 }
00081 
00082 /** deal with nested structs, for example:
00083  *  struct A { long x; };
00084  *  struct B { A theA; };
00085  *  B's query string has "ORDER BY theA.x"
00086  *  The generated code will create a StructComparator with
00087  *  Sample = B and Field = A which in turn has a "delegate" which is
00088  *  a FieldComparator (see above) with Sample = A and Field = CORBA::Long
00089  */
00090 template <class Sample, class Field>
00091 class StructComparator : public ComparatorBase {
00092 public:
00093   typedef Field Sample::* MemberPtr;
00094   StructComparator(MemberPtr mp, ComparatorBase::Ptr delegate,
00095                    ComparatorBase::Ptr next)
00096   : ComparatorBase(next)
00097   , mp_(mp)
00098   , delegate_(delegate) {}
00099 
00100   bool less(void* lhs_void, void* rhs_void) const {
00101     Sample* lhs = static_cast<Sample*>(lhs_void);
00102     Sample* rhs = static_cast<Sample*>(rhs_void);
00103     return delegate_->less(&(lhs->*mp_), &(rhs->*mp_));
00104   }
00105 
00106   bool equal(void* lhs_void, void* rhs_void) const {
00107     Sample* lhs = static_cast<Sample*>(lhs_void);
00108     Sample* rhs = static_cast<Sample*>(rhs_void);
00109     return delegate_->equal(&(lhs->*mp_), &(rhs->*mp_));
00110   }
00111 
00112 private:
00113   MemberPtr mp_;
00114   ComparatorBase::Ptr delegate_;
00115 };
00116 
00117 template <class Sample, class Field>
00118 ComparatorBase::Ptr make_struct_cmp(Field Sample::* mp,
00119                                     ComparatorBase::Ptr delegate,
00120                                     ComparatorBase::Ptr next)
00121 {
00122   return new StructComparator<Sample, Field>(mp, delegate, next);
00123 }
00124 
00125 } // namespace DCPS
00126 } // namespace OpenDDS
00127 
00128 #endif

Generated on Fri Feb 12 20:05:19 2016 for OpenDDS by  doxygen 1.4.7