Panda3D
|
00001 // Filename: stl_compares.h 00002 // Created by: drose (28Sep04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef STL_COMPARES_H 00016 #define STL_COMPARES_H 00017 00018 #include "dtoolbase.h" 00019 #include "cmath.h" 00020 #include "nearly_zero.h" 00021 #include "addHash.h" 00022 00023 #include <assert.h> 00024 00025 #ifdef HAVE_STL_HASH 00026 #include <hash_map> // for hash_compare 00027 00028 template<class Key, class Compare = less<Key> > 00029 class stl_hash_compare : public stdext::hash_compare<Key, Compare> { 00030 public: 00031 INLINE bool is_equal(const Key &a, const Key &b) const { 00032 return !operator()(a, b) && !operator()(b, a); 00033 } 00034 }; 00035 00036 00037 #else 00038 00039 #include <map> // for less 00040 00041 // This is declared for the cases in which we don't have STL_HASH 00042 // available. 00043 template<class Key, class Compare = less<Key> > 00044 class stl_hash_compare : public Compare { 00045 public: 00046 INLINE size_t operator () (const Key &key) const { 00047 return (size_t)key; 00048 } 00049 INLINE bool operator () (const Key &a, const Key &b) const { 00050 return Compare::operator ()(a, b); 00051 } 00052 INLINE bool is_equal(const Key &a, const Key &b) const { 00053 return !operator()(a, b) && !operator()(b, a); 00054 } 00055 }; 00056 00057 #endif // HAVE_STL_HASH 00058 00059 //////////////////////////////////////////////////////////////////// 00060 // Class : floating_point_threshold 00061 // Description : Compares two floating point numbers, within threshold 00062 // of equivalence. 00063 //////////////////////////////////////////////////////////////////// 00064 template<class Key> 00065 class floating_point_threshold { 00066 public: 00067 INLINE floating_point_threshold(Key threshold = get_nearly_zero_value((Key)0)); 00068 INLINE bool operator () (const Key &a, const Key &b) const; 00069 const Key _threshold; 00070 }; 00071 00072 //////////////////////////////////////////////////////////////////// 00073 // Class : compare_to 00074 // Description : An STL function object class, this is intended to be 00075 // used on any ordered collection of class objects that 00076 // contain a compare_to() method. It defines the order 00077 // of the objects via compare_to(). 00078 //////////////////////////////////////////////////////////////////// 00079 template<class Key> 00080 class compare_to { 00081 public: 00082 INLINE bool operator () (const Key &a, const Key &b) const; 00083 INLINE bool is_equal(const Key &a, const Key &b) const; 00084 }; 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Class : indirect_less 00088 // Description : An STL function object class, this is intended to be 00089 // used on any ordered collection of pointers to classes 00090 // that contain an operator <() method. It defines the 00091 // order of the pointers via operator <(). 00092 //////////////////////////////////////////////////////////////////// 00093 template<class Key> 00094 class indirect_less { 00095 public: 00096 INLINE bool operator () (const Key &a, const Key &b) const; 00097 }; 00098 00099 //////////////////////////////////////////////////////////////////// 00100 // Class : indirect_compare_to 00101 // Description : An STL function object class, this is intended to be 00102 // used on any ordered collection of pointers to classes 00103 // that contain a compare_to() method. It defines the 00104 // order of the pointers via compare_to(). 00105 //////////////////////////////////////////////////////////////////// 00106 template<class Key> 00107 class indirect_compare_to { 00108 public: 00109 INLINE bool operator () (const Key &a, const Key &b) const; 00110 INLINE bool is_equal(const Key &a, const Key &b) const; 00111 }; 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Class : indirect_compare_names 00115 // Description : An STL function object class, this is intended to be 00116 // used on any ordered collection of pointers to classes 00117 // that define a get_name() method, particularly for 00118 // things that derive from Namable. It defines the 00119 // order of the pointers by case-sensitive name 00120 // comparison. 00121 //////////////////////////////////////////////////////////////////// 00122 template<class Key> 00123 class indirect_compare_names { 00124 public: 00125 INLINE bool operator () (const Key &a, const Key &b) const; 00126 INLINE bool is_equal(const Key &a, const Key &b) const; 00127 }; 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Class : integer_hash 00131 // Description : This is the default hash_compare class, which assumes 00132 // the Key is a size_t value or can be implicitly 00133 // converted to a size_t value (for instance, via a 00134 // size_t typecast operator). It is the same as the 00135 // system-provided hash_compare. 00136 //////////////////////////////////////////////////////////////////// 00137 template<class Key, class Compare = less<Key> > 00138 class integer_hash : public stl_hash_compare<Key, Compare> { 00139 public: 00140 INLINE static size_t add_hash(size_t start, const Key &key); 00141 }; 00142 00143 //////////////////////////////////////////////////////////////////// 00144 // Class : pointer_hash 00145 // Description : This is the default hash_compare class, which assumes 00146 // the Key is a pointer value. It is the same as the 00147 // system-provided hash_compare. 00148 //////////////////////////////////////////////////////////////////// 00149 class pointer_hash : public stl_hash_compare<const void *, less<const void *> > { 00150 public: 00151 INLINE static size_t add_hash(size_t start, const void *key); 00152 }; 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Class : floating_point_hash 00156 // Description : This hash_compare class hashes a float or a double. 00157 //////////////////////////////////////////////////////////////////// 00158 template<class Key> 00159 class floating_point_hash : public stl_hash_compare<Key> { 00160 public: 00161 INLINE floating_point_hash(Key threshold = get_nearly_zero_value((Key)0)); 00162 INLINE size_t operator () (const Key &key) const; 00163 INLINE bool operator () (const Key &a, const Key &b) const; 00164 INLINE size_t add_hash(size_t start, const Key &key) const; 00165 const Key _threshold; 00166 }; 00167 00168 //////////////////////////////////////////////////////////////////// 00169 // Class : sequence_hash 00170 // Description : This hash_compare class hashes a string. It assumes 00171 // the Key is a string or provides begin() and end() 00172 // methods that iterate through Key::value_type. 00173 //////////////////////////////////////////////////////////////////// 00174 template<class Key, class Compare = less<Key> > 00175 class sequence_hash : public stl_hash_compare<Key, Compare> { 00176 public: 00177 INLINE size_t operator () (const Key &key) const; 00178 INLINE bool operator () (const Key &a, const Key &b) const { 00179 return stl_hash_compare<Key, Compare>::operator () (a, b); 00180 } 00181 INLINE static size_t add_hash(size_t start, const Key &key); 00182 }; 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Class : method_hash 00186 // Description : This hash_compare class hashes a class object. It 00187 // assumes the Key provides a method called get_hash() 00188 // that returns a size_t. 00189 //////////////////////////////////////////////////////////////////// 00190 template<class Key, class Compare = less<Key> > 00191 class method_hash : public stl_hash_compare<Key, Compare> { 00192 public: 00193 INLINE size_t operator () (const Key &key) const; 00194 INLINE bool operator () (const Key &a, const Key &b) const { 00195 return stl_hash_compare<Key, Compare>::operator () (a, b); 00196 } 00197 }; 00198 00199 //////////////////////////////////////////////////////////////////// 00200 // Class : indirect_method_hash 00201 // Description : This hash_compare class hashes a pointer to a class 00202 // object. It assumes the Key is a pointer to a class 00203 // that provides a method called get_hash() that returns 00204 // a size_t. 00205 //////////////////////////////////////////////////////////////////// 00206 template<class Key, class Compare> 00207 class indirect_method_hash : public stl_hash_compare<Key, Compare> { 00208 public: 00209 INLINE size_t operator () (const Key &key) const; 00210 INLINE bool operator () (const Key &a, const Key &b) const { 00211 return stl_hash_compare<Key, Compare>::operator () (a, b); 00212 } 00213 }; 00214 00215 #include "stl_compares.I" 00216 00217 typedef floating_point_hash<float> float_hash; 00218 typedef floating_point_hash<double> double_hash; 00219 typedef integer_hash<int> int_hash; 00220 typedef integer_hash<size_t> size_t_hash; 00221 typedef sequence_hash<string> string_hash; 00222 typedef sequence_hash<wstring> wstring_hash; 00223 00224 template<class Key> 00225 class indirect_less_hash : public indirect_method_hash<Key, indirect_less<Key> > { 00226 }; 00227 00228 template<class Key> 00229 class indirect_compare_to_hash : public indirect_method_hash<Key, indirect_compare_to<Key> > { 00230 }; 00231 00232 template<class Key> 00233 class indirect_compare_names_hash : public indirect_method_hash<Key, indirect_compare_names<Key> > { 00234 }; 00235 00236 #endif 00237 00238