contrib/mul/mbl/mbl_stl_pred.h
Go to the documentation of this file.
00001 // This is mul/mbl/mbl_stl_pred.h
00002 #ifndef mbl_stl_pred_h_
00003 #define mbl_stl_pred_h_
00004 //:
00005 // \file
00006 // \brief Useful predicate functors for use in stl find_if,partition etc.
00007 // \author martin roberts
00008 // \date  July 2004
00009 
00010 
00011 #include <vcl_functional.h>
00012 #include <vcl_vector.h>
00013 #include <vcl_string.h>
00014 #include <vcl_utility.h>
00015 #include <vcl_cmath.h>
00016 #include <vnl/vnl_vector.h>
00017 
00018 //: Return true if a string contains a substring
00019 // Note without this you'd need bind2nd mem_fun which can cause reference to reference compile errors
00020 class mbl_stl_pred_str_contains : public vcl_unary_function<vcl_string, bool>
00021 {
00022   //: The sought substring
00023   const vcl_string& substr_;
00024  public:
00025   mbl_stl_pred_str_contains(const vcl_string& substr): substr_(substr){}
00026 
00027   inline bool operator()(const vcl_string& str) const
00028   {
00029     return ( (str.find(substr_) != str.npos) ? true : false);
00030   }
00031 };
00032 
00033 //: Adapt a predicate over a vector to the operation specified on an index into that vector
00034 // T is type of the vector, and Pred the boolean predicate to really be applied
00035 template <class T, class Pred>
00036 class mbl_stl_pred_index_adapter : public vcl_unary_function<unsigned, bool>
00037 {
00038   //:const reference to vector used to store the objects indexed
00039   const vcl_vector<T >& vec_;
00040   //: The predicate to really be applied
00041   Pred Op_;
00042  public:
00043   mbl_stl_pred_index_adapter(vcl_vector<T> const& v, Pred Op):vec_(v),Op_(Op){}
00044 
00045   inline bool operator()(const unsigned& i) const
00046   {
00047     return Op_(vec_[i]);
00048   }
00049 };
00050 
00051 template <class T, class Pred>
00052 class mbl_stl_pred_index_adapter_n : public vcl_unary_function<unsigned, bool>
00053 {
00054   //:const reference to vector used to store the objects indexed
00055   const vnl_vector<T >& vec_;
00056   //: The predicate to really be applied
00057   Pred Op_;
00058  public:
00059   mbl_stl_pred_index_adapter_n(vnl_vector<T> const& v, Pred Op):vec_(v),Op_(Op){}
00060 
00061   inline bool operator()(const unsigned& i) const
00062   {
00063     return Op_(vec_[i]);
00064   }
00065 };
00066 
00067 //: Helper function to create an index adapter of the appropriate type
00068 // As this is a function not a class, it saves some template gobbledegook in the class name
00069 // Vec is assumed vector<T> where T is the type associated with the constructed adapter
00070 //However note that using this means an extra copy of the predicate functor will occur
00071 template <class T, class Pred>
00072 inline mbl_stl_pred_index_adapter<T,Pred> mbl_stl_pred_create_index_adapter(const vcl_vector<T>& v, Pred Op)
00073 {
00074   return  mbl_stl_pred_index_adapter<T,Pred>(v,Op);
00075 };
00076 //: Helper function to create an index adapter of the appropriate type
00077 // As this is a function not a class, it saves some template gobbledegook in the class name
00078 // Vec is assumed vector<T> where T is the type associated with the constructed adapter
00079 //However note that using this means an extra copy of the predicate functor will occur
00080 template <class T, class Pred>
00081 inline mbl_stl_pred_index_adapter_n<T,Pred> mbl_stl_pred_create_index_adapter(const vnl_vector<T>& v, Pred Op)
00082 {
00083   return  mbl_stl_pred_index_adapter_n<T,Pred>(v,Op);
00084 };
00085 
00086 //: Adapt a predicate over a vector to the operation specified on an index into that vector
00087 // T is type of the vector, and Pred the boolean predicate to really be applied
00088 template <class T, class Pred>
00089 class mbl_stl_pred_binary_index_adapter : public vcl_binary_function<unsigned, unsigned, bool>
00090 {
00091   //:const reference to vector used to store the objects indexed
00092   const vcl_vector<T >& vec_;
00093   //: The predicate to really be applied
00094   Pred Op_;
00095  public:
00096   mbl_stl_pred_binary_index_adapter(vcl_vector<T> const& v, Pred Op):vec_(v),Op_(Op){}
00097 
00098   inline bool operator()(const unsigned& i, const unsigned& j) const
00099   {
00100     return Op_(vec_[i],vec_[j]);
00101   }
00102 };
00103 
00104 //: Helper function to create an index adapter of the appropriate type
00105 // As this is a function not a class, it saves some template gobbledegook in the class name
00106 // Vec is assumed vector<T> where T is the type associated with the constructed adapter
00107 //However note that using this means an extra copy of the predicate functor will occur
00108 template <class T, class Pred>
00109 inline mbl_stl_pred_binary_index_adapter<T,Pred> mbl_stl_pred_create_binary_index_adapter(const vcl_vector<T>& v, Pred Op)
00110 {
00111   return  mbl_stl_pred_binary_index_adapter<T,Pred>(v,Op);
00112 };
00113 
00114 
00115 //Order a collection of iterators according to their dereferenced values
00116 //NB assumes the value type supports operator<
00117 //Can also be used for collections of pointers or objects supporting
00118 //dereferencing operator like *p.
00119 template <class Iter>
00120 struct mbl_stl_pred_iter_deref_order : public vcl_binary_function<Iter,Iter, bool>
00121 {
00122   inline bool  operator()(const Iter& iter1, const Iter& iter2 ) const
00123   {
00124     return (*iter1 < *iter2) ? true : false;
00125   }
00126 };
00127 
00128 
00129 //Order a collection of pair iterators according to their dereferenced keys
00130 //NB assumes the key type supports operator<
00131 template <class PairIter>
00132 struct mbl_stl_pred_pair_iter_key_order : public vcl_binary_function<PairIter,PairIter, bool>
00133 {
00134   inline bool  operator()(const PairIter& iter1, const PairIter& iter2 ) const
00135   {
00136     return (iter1->first < iter2->first) ? true : false;
00137   }
00138 };
00139 
00140 //Order a collection of pair iterators according to their dereferenced values
00141 //NB assumes the key type supports operator<
00142 template <class PairIter>
00143 struct mbl_stl_pred_pair_iter_value_order : public vcl_binary_function<PairIter,PairIter, bool>
00144 {
00145   inline bool  operator()(const PairIter& iter1, const PairIter& iter2 ) const
00146   {
00147     return (iter1->second < iter2->second) ? true : false;
00148   }
00149 };
00150 
00151 
00152 //Order a collection of pairs according to their first elements
00153 //NB assumes the key type supports operator<
00154 template <class Pair>
00155 struct mbl_stl_pred_pair_key_order : public vcl_binary_function<Pair,Pair, bool>
00156 {
00157   inline bool  operator()(const Pair& pair1, const Pair& pair2 ) const
00158   {
00159     return (pair1.first < pair2.first) ? true : false;
00160   }
00161 };
00162 
00163 //Order a collection of pairs according to their second elements
00164 //NB assumes the key type supports operator<
00165 template <class Pair>
00166 struct mbl_stl_pred_pair_value_order : public vcl_binary_function<Pair,Pair, bool>
00167 {
00168   inline bool  operator()(const Pair& pair1, const Pair& pair2 ) const
00169   {
00170     return (pair1.second < pair2.second) ? true : false;
00171   }
00172 };
00173 
00174 
00175 //
00176 //////////////////////////////////////////////////////////////////////////
00177 //Order a collection of pairs
00178 //First is the primary key, second is the secondary key
00179 //NB assumes both the pair types supports operator<
00180 template <class T1, class T2>
00181 struct mbl_stl_pred_pair_order : public vcl_binary_function<vcl_pair<T1,T2>,vcl_pair<T1,T2>, bool>
00182 {
00183   inline bool  operator()(const vcl_pair<T1,T2>& pair1, const vcl_pair<T1,T2>& pair2 ) const
00184   {
00185     if (pair1.first < pair2.first)
00186       return true;
00187     else if (pair1.first > pair2.first)
00188       return false;
00189     else
00190       return pair1.second < pair2.second; //Primaries are equal so order on secondary
00191   }
00192 };
00193 
00194 //See if a test pointer is the class type required
00195 //Note the template type T would normally be of pointer type but might also be
00196 //something supporting operator->() in a pointer like way
00197 //(e.g. auto_ptr mbl_cloneable_ptr etc)
00198 template <class T>
00199 //NB assumes templated class provides is_a to return its typename
00200 class mbl_stl_pred_is_a : public vcl_unary_function<T, bool>
00201 {
00202   //:const reference to name of required class type
00203   const vcl_string& ctype_;
00204  public:
00205   mbl_stl_pred_is_a(vcl_string const& ctype):ctype_(ctype){}
00206 
00207   inline bool operator()(const T& p) const
00208   {
00209       return (p->is_a()==ctype_) ? true : false;
00210   }
00211 };
00212 
00213 class mbl_stl_pred_is_near : public vcl_unary_function<double, bool>
00214 {
00215   double epsilon_;
00216   double xtarget_;
00217  public:
00218   mbl_stl_pred_is_near(double xtarget,double epsilon=1.0E-12)
00219   : epsilon_(epsilon), xtarget_(xtarget)
00220   {}
00221   inline bool operator()(const double& x) const
00222   {
00223     return vcl_fabs(x-xtarget_)<epsilon_;
00224   }
00225 };
00226 
00227 #endif
00228