CMS 3D CMS Logo

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