00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef _DECAF_UTIL_HASHCODE_H_ 00019 #define _DECAF_UTIL_HASHCODE_H_ 00020 00021 #include <decaf/util/Config.h> 00022 00023 #include <decaf/lang/Pointer.h> 00024 #include <decaf/lang/Float.h> 00025 #include <decaf/lang/Double.h> 00026 00027 #include <string> 00028 #include <functional> 00029 00030 namespace decaf { 00031 namespace util { 00032 00033 template<typename T> 00034 struct HashCodeUnaryBase { 00035 public: 00036 00037 typedef T argument_type; 00038 typedef int result_type; 00039 00040 virtual ~HashCodeUnaryBase() {} 00041 }; 00042 00049 template<typename T> 00050 struct HashCode : HashCodeUnaryBase<const T&> { 00051 public: 00052 int operator()(const T& arg) const { 00053 return arg.getHashCode(); 00054 } 00055 }; 00056 00057 template<typename T> 00058 struct HashCode<const T> : HashCodeUnaryBase<const T&> { 00059 int operator()(const T& arg) const { 00060 return arg.getHashCode(); 00061 } 00062 }; 00063 00064 template<typename T> 00065 struct HashCode<T*> : public HashCodeUnaryBase<const T*> { 00066 int operator()(const T* arg) const { 00067 if (arg != NULL) { 00068 return arg->getHashCode(); 00069 } 00070 return 0; 00071 } 00072 }; 00073 00074 template<typename T> 00075 struct HashCode<const T*> : public HashCodeUnaryBase<const T*> { 00076 int operator()(const T* arg) const { 00077 if (arg != NULL) { 00078 return arg->getHashCode(); 00079 } 00080 return 0; 00081 } 00082 }; 00083 00084 template<> 00085 struct HashCode<bool> : public HashCodeUnaryBase<bool> { 00086 int operator()(bool arg) const { 00087 return arg ? 1231 : 1237; 00088 } 00089 }; 00090 00091 #if defined(HAVE_WCHAR_T) 00092 template<> 00093 struct HashCode<unsigned char> : public HashCodeUnaryBase<unsigned char> { 00094 int operator()(unsigned char arg) const { 00095 return (int) arg; 00096 } 00097 }; 00098 #endif 00099 00100 template<> 00101 struct HashCode<char> : public HashCodeUnaryBase<char> { 00102 int operator()(char arg) const { 00103 return (int) arg; 00104 } 00105 }; 00106 00107 template<> 00108 struct HashCode<wchar_t> : public HashCodeUnaryBase<wchar_t> { 00109 int operator()(wchar_t arg) const { 00110 return (int) arg; 00111 } 00112 }; 00113 00114 template<> 00115 struct HashCode<unsigned short> : public HashCodeUnaryBase<unsigned short> { 00116 int operator()(unsigned short arg) const { 00117 return (int) arg; 00118 } 00119 }; 00120 00121 template<> 00122 struct HashCode<short> : public HashCodeUnaryBase<short> { 00123 int operator()(short arg) const { 00124 return (int) arg; 00125 } 00126 }; 00127 00128 template<> 00129 struct HashCode<unsigned int> : public HashCodeUnaryBase<unsigned int> { 00130 int operator()(unsigned int arg) const { 00131 return (int) arg; 00132 } 00133 }; 00134 00135 template<> 00136 struct HashCode<int> : public HashCodeUnaryBase<int> { 00137 int operator()(int arg) const { 00138 return arg; 00139 } 00140 }; 00141 00142 template<> 00143 struct HashCode<unsigned long long> : public HashCodeUnaryBase<unsigned long long> { 00144 int operator()(unsigned long long arg) const { 00145 return (int) (arg ^ (arg >> 32)); 00146 } 00147 }; 00148 00149 template<> 00150 struct HashCode<long long> : public HashCodeUnaryBase<long long> { 00151 int operator()(long long arg) const { 00152 return (int) (arg ^ ((unsigned long long) arg >> 32)); 00153 } 00154 }; 00155 00156 template<> 00157 struct HashCode<float> : public HashCodeUnaryBase<float> { 00158 int operator()(float arg) const { 00159 return decaf::lang::Float::floatToIntBits(arg); 00160 } 00161 }; 00162 00163 template<> 00164 struct HashCode<double> : public HashCodeUnaryBase<double> { 00165 int operator()(double arg) const { 00166 long long value = decaf::lang::Double::doubleToLongBits(arg); 00167 return (int) (value ^ ((unsigned long long) value >> 32)); 00168 } 00169 }; 00170 00171 template<> 00172 struct HashCode<std::string> : public HashCodeUnaryBase<const std::string&> { 00173 int operator()(const std::string& arg) const { 00174 int h = 0; 00175 if (h == 0 && arg.length() > 0) { 00176 std::string::const_iterator iter = arg.begin(); 00177 for (; iter != arg.end(); ++iter) { 00178 h = 31 * h + (*iter); 00179 } 00180 } 00181 return h; 00182 } 00183 }; 00184 00185 template<> 00186 struct HashCode<const std::string> : public HashCodeUnaryBase<const std::string&> { 00187 int operator()(const std::string& arg) const { 00188 int h = 0; 00189 if (h == 0 && arg.length() > 0) { 00190 std::string::const_iterator iter = arg.begin(); 00191 for (; iter != arg.end(); ++iter) { 00192 h = 31 * h + (*iter); 00193 } 00194 } 00195 return h; 00196 } 00197 }; 00198 00199 template<typename T> 00200 struct HashCode< decaf::lang::Pointer<T> > : public HashCodeUnaryBase<decaf::lang::Pointer<T> > { 00201 int operator()(decaf::lang::Pointer<T> arg) const { 00202 if (arg != NULL) { 00203 return HashCode<const T>()(*arg); 00204 } 00205 return 0; 00206 } 00207 }; 00208 00209 }} 00210 00211 #endif /* _DECAF_UTIL_HASHCODE_H_ */
1.6.1