KeyContainer.hpp

Go to the documentation of this file.
00001 #ifndef wali_KEY_CONTAINER_GUARD
00002 #define wali_KEY_CONTAINER_GUARD 1
00003 
00004 /**
00005  * @author Nicholas Kidd
00006  */
00007 
00008 #include "wali/Common.hpp"
00009 #include "wali/hm_hash.hpp"
00010 #include <utility>          // provides std::pair
00011 
00012 namespace wali
00013 {
00014   static inline size_t combineKeys( Key k1, Key k2 )
00015   {
00016     return k1 + (997*k2);
00017   }
00018 
00019   /**
00020    * KeyPair
00021    */
00022   typedef std::pair< Key,Key > KeyPair;
00023 
00024   /**
00025    * @class Triple
00026    */
00027   template< typename T,typename U,typename V > struct Triple
00028   {
00029     Triple() {}
00030 
00031     Triple( T t,U u,V v )
00032       : first(t),second(u),third(v) {}
00033 
00034     Triple( const Triple & rhs )
00035       : first(rhs.first), second(rhs.second), third(rhs.third) {}
00036 
00037     Triple & operator=( const Triple & rhs )
00038     {
00039       first   = rhs.first;
00040       second  = rhs.second;
00041       third   = rhs.third;
00042       return *this;
00043     }
00044 
00045     bool operator==( const Triple & rhs ) const
00046     {
00047       return (
00048           (first == rhs.first) &&
00049           (second == rhs.second) &&
00050           (third == rhs.third)
00051           );
00052     }
00053 
00054     // @author Amanda Burton
00055       bool operator<( const Triple & rhs ) const
00056       {
00057           if( first == rhs.first )
00058           {
00059               if( second == rhs.second )
00060                   return (third < rhs.third);
00061               else
00062                   return (second < rhs.second);
00063           }
00064           else
00065               return (first < rhs.first);
00066       }
00067 
00068     T first;
00069     U second;
00070     V third;
00071   };
00072 
00073   /**
00074    * KeyTriple
00075    */
00076   typedef Triple< Key,Key,Key > KeyTriple;
00077 
00078   /**
00079    * Return a Triple with the given types (analgous to std::make_pair)
00080    */
00081   template< typename T,typename U,typename V >
00082   Triple<T, U, V>
00083   make_triple(T const & t, U const & u, V const & v)
00084   {
00085     return Triple<T, U, V>(t, u, v);
00086   }
00087 
00088   // @author Amanda Burton
00089   /**
00090    * @class Quad
00091    */
00092   template< typename T,typename U,typename V,typename W > struct Quad
00093   {
00094     Quad() {}
00095 
00096     Quad( T t,U u,V v,W w )
00097       : first(t),second(u),third(v),fourth(w) {}
00098 
00099     Quad( const Quad & other )
00100       : first(other.first), second(other.second), third(other.third),
00101       fourth(other.fourth) {}
00102 
00103     Quad & operator=( const Quad & other )
00104     {
00105       first   = other.first;
00106       second  = other.second;
00107       third   = other.third;
00108       fourth  = other.fourth;
00109       return *this;
00110     }
00111 
00112     bool operator==( const Quad & other ) const
00113     {
00114       return ((first == other.first) &&
00115         (second == other.second) &&
00116         (third == other.third) &&
00117         (fourth == other.fourth)); 
00118     }
00119 
00120     bool operator<( const Quad & other ) const
00121     {
00122       if( first == other.first )
00123       {
00124         if( second == other.second )
00125         {
00126           if( third == other.third )
00127             return (fourth < other.fourth);
00128           else
00129             return (third < other.third);
00130         }
00131         else
00132           return (second < other.second);
00133       }
00134       else
00135         return (first < other.first );
00136     }
00137 
00138     T first;
00139     U second;
00140     V third;
00141     W fourth;
00142   };
00143 
00144   /**
00145    * KeyQuad
00146    */
00147   typedef Quad< Key,Key,Key,Key > KeyQuad;
00148 
00149   /**
00150    * Return a Quad with the given types (analgous to std::make_pair)
00151    */
00152   template< typename T,typename U,typename V,typename W >
00153   Quad<T, U, V, W>
00154   make_quad(T const & t, U const & u, V const & v, W const & w)
00155   {
00156     return Quad<T, U, V, W>(t, u, v, w);
00157   }
00158 
00159 
00160   template<> struct hm_hash< KeyPair >
00161   {
00162     hm_hash< size_t > hasher;
00163 
00164     size_t operator()( const KeyPair & kp ) const
00165     {
00166       return hasher( combineKeys( kp.first,kp.second ) );
00167     }
00168 
00169   };
00170 
00171   template<> struct hm_equal< KeyPair >
00172   {
00173     bool operator()( const KeyPair& lhs,const KeyPair& rhs ) const
00174     {
00175       return ((lhs.first == rhs.first) && (lhs.second == rhs.second));
00176     }
00177 
00178   };
00179 
00180   template<> struct hm_hash< KeyTriple >
00181   {
00182 
00183     hm_hash< size_t > hasher;
00184 
00185     size_t operator()( const KeyTriple & kt ) const
00186     {
00187       size_t ans = combineKeys(kt.first,kt.second);
00188       ans = combineKeys( ans,kt.third);
00189       return hasher( ans );
00190     }
00191 
00192   };
00193 
00194   template<> struct hm_equal< KeyTriple >
00195   {
00196 
00197     bool operator()( const KeyTriple& lhs,const KeyTriple& rhs ) const
00198     {
00199       return lhs == rhs;
00200     }
00201 
00202   };
00203   
00204   // @author Amanda Burton
00205   template<> struct hm_hash< std::set<Key> >
00206   {
00207     hm_hash< size_t > hasher;
00208 
00209     size_t operator()( const std::set<Key> & ks ) const
00210     {
00211       size_t key = 0;
00212       for( std::set<Key>::const_iterator it = ks.begin();
00213             it != ks.end(); it++ )
00214       {
00215         key = hasher( combineKeys( key,*it ) );
00216       } 
00217       return key;      
00218     }
00219 
00220   };
00221 
00222   template<> struct hm_equal< std::set<Key> >
00223   {
00224     bool operator()( const std::set<Key>& lhs,const std::set<Key>& rhs ) const
00225     {
00226       if( lhs.size() != rhs.size() )
00227         return false;
00228       for( std::set<Key>::const_iterator lit = lhs.begin(), rit = rhs.begin();
00229             (lit != lhs.end()) && (rit != rhs.end()); lit++,rit++ )
00230       {
00231         if( *lit != *rit )
00232           return false;
00233       }
00234       return true;
00235     }
00236 
00237   };
00238 
00239 } // namespace wali
00240 
00241 #endif  // wali_KEY_CONTAINER_GUARD
00242