CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DataFormats/Provenance/interface/Hash.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Provenance_Hash_h
00002 #define DataFormats_Provenance_Hash_h
00003 
00004 #include <string>
00005 
00006 /*----------------------------------------------------------------------
00007   
00008 Hash:
00009 
00010   Note: The call to 'fixup' in every member function is a temporary
00011   measure for backwards compatibility. It is necessary in every function
00012   because Root creates instances of the class *without* using the
00013   interface of the class, thus making it insufficient to assure that
00014   all constructors make corrected instances.
00015 
00016 ----------------------------------------------------------------------*/
00017 namespace cms {
00018   class Digest;
00019 }
00020 
00021 namespace edm {
00022 
00023   namespace detail {
00024     // This string is the 16-byte, non-printable version.
00025     std::string const& InvalidHash();
00026   }
00027 
00028   namespace hash_detail {
00029     typedef std::string value_type;
00030     value_type compactForm_(value_type const& hash);
00031     void fixup_(value_type& hash);
00032     bool isCompactForm_(value_type const& hash);
00033     bool isValid_(value_type const& hash);
00034     void throwIfIllFormed(value_type const& hash);
00035     void toString_(std::string& result, value_type const& hash);
00036     void toDigest_(cms::Digest& digest, value_type const& hash);
00037     std::ostream& print_(std::ostream& os, value_type const& hash);
00038   }
00039 
00040   template <int I>
00041   class Hash {
00042   public:
00043     typedef hash_detail::value_type value_type;
00044 
00045     Hash();
00046     explicit Hash(value_type const& v);
00047 
00048     Hash(Hash<I> const&);
00049     Hash<I> const& operator=(Hash<I> const& iRHS);
00050 
00051     void reset();
00052 
00053     // For now, just check the most basic: a default constructed
00054     // ParameterSetID is not valid. This is very crude: we are
00055     // assuming that nobody created a ParameterSetID from an empty
00056     // string, nor from any string that is not a valid string
00057     // representation of an MD5 checksum.
00058     bool isValid() const;
00059 
00060     bool operator<(Hash<I> const& other) const;
00061     bool operator>(Hash<I> const& other) const;
00062     bool operator==(Hash<I> const& other) const;
00063     bool operator!=(Hash<I> const& other) const;
00064     std::ostream& print(std::ostream& os) const;
00065     void toString(std::string& result) const;
00066     void toDigest(cms::Digest& digest) const;
00067     void swap(Hash<I>& other);
00068 
00069     // Return the 16-byte (non-printable) string form.
00070     value_type compactForm() const;
00071     
00072     bool isCompactForm() const;
00073     
00074   private:
00075 
00078     void throwIfIllFormed() const;
00079 
00080     template<typename Op>
00081       bool
00082       compareUsing(Hash<I> const& iOther, Op op) const {
00083         bool meCF = hash_detail::isCompactForm_(hash_);
00084         bool otherCF = hash_detail::isCompactForm_(iOther.hash_);
00085         if(meCF == otherCF) {
00086           return op(this->hash_,iOther.hash_);
00087         }
00088         //copy constructor will do compact form conversion
00089         if(meCF) {
00090            Hash<I> temp(iOther);
00091            return op(this->hash_,temp.hash_);
00092         } 
00093         Hash<I> temp(*this);
00094         return op(temp.hash_,iOther.hash_);
00095       }
00096 
00097     value_type hash_;
00098   };
00099 
00100 
00101   //--------------------------------------------------------------------
00102   //
00103   // Implementation details follow...
00104   //--------------------------------------------------------------------
00105 
00106 
00107   template <int I>
00108   inline
00109   Hash<I>::Hash() : hash_(detail::InvalidHash()) {}
00110 
00111   template <int I>
00112   inline
00113   Hash<I>::Hash(typename Hash<I>::value_type const& v) : hash_(v) {
00114     hash_detail::fixup_(hash_);
00115   }
00116 
00117   template <int I>
00118   inline
00119   Hash<I>::Hash(Hash<I> const& iOther) : hash_(iOther.hash_) {
00120      hash_detail::fixup_(hash_);
00121   }
00122 
00123   template <int I>
00124   inline
00125   Hash<I> const& 
00126   Hash<I>::operator=(Hash<I> const& iRHS) {
00127     hash_ = iRHS.hash_;
00128     hash_detail::fixup_(hash_);
00129     return *this;
00130   }
00131   
00132   template <int I>
00133   inline
00134   void 
00135   Hash<I>::reset() {
00136     hash_ = detail::InvalidHash();
00137   }
00138   
00139   template <int I>
00140   inline
00141   bool 
00142   Hash<I>::isValid() const {
00143     return hash_detail::isValid_(hash_);
00144   }
00145   
00146   template <int I>
00147   inline
00148   bool
00149   Hash<I>::operator<(Hash<I> const& other) const {
00150     return this->compareUsing(other, std::less<std::string>());
00151   }
00152 
00153   template <int I>
00154   inline
00155   bool 
00156   Hash<I>::operator>(Hash<I> const& other) const {
00157     return this->compareUsing(other, std::greater<std::string>());
00158   }
00159 
00160   template <int I>
00161   inline
00162   bool 
00163   Hash<I>::operator==(Hash<I> const& other) const {
00164     return this->compareUsing(other, std::equal_to<std::string>());
00165   }
00166 
00167   template <int I>
00168   inline
00169   bool 
00170   Hash<I>::operator!=(Hash<I> const& other) const {
00171     return this->compareUsing(other, std::not_equal_to<std::string>());
00172   }
00173 
00174   template <int I>
00175   inline
00176   std::ostream& 
00177   Hash<I>::print(std::ostream& os) const {
00178     return hash_detail::print_(os, hash_);
00179   }
00180 
00181   template <int I>
00182   inline
00183   void
00184   Hash<I>::toString(std::string& result) const {
00185     hash_detail::toString_(result, hash_);
00186   }
00187 
00188   template <int I>
00189   inline
00190   void
00191   Hash<I>::toDigest(cms::Digest& digest) const {
00192     hash_detail::toDigest_(digest, hash_);
00193   }
00194 
00195   template <int I>
00196   inline
00197   void 
00198   Hash<I>::swap(Hash<I>& other) {
00199     hash_.swap(other.hash_);
00200   }
00201 
00202   template <int I>
00203   inline
00204   typename Hash<I>::value_type
00205   Hash<I>::compactForm() const {
00206     return hash_detail::compactForm_(hash_);
00207   }
00208 
00209   // Note: this template is not declared 'inline' because of the
00210   // switch statement.
00211 
00212   template <int I>
00213   inline
00214   bool Hash<I>::isCompactForm() const {
00215     return hash_detail::isCompactForm_(hash_);
00216   }
00217   
00218 
00219   // Free swap function
00220   template <int I>
00221   inline
00222   void
00223   swap(Hash<I>& a, Hash<I>& b) {
00224     a.swap(b);
00225   }
00226 
00227   template <int I>
00228   inline
00229   std::ostream&
00230   operator<<(std::ostream& os, Hash<I> const& h) {
00231     return h.print(os);
00232   }
00233 
00234 }
00235 #endif