diff options
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r-- | include/llvm/ADT/APFloat.h | 1 | ||||
-rw-r--r-- | include/llvm/ADT/DenseMap.h | 23 | ||||
-rw-r--r-- | include/llvm/ADT/FoldingSet.h | 28 | ||||
-rw-r--r-- | include/llvm/ADT/Hashing.h | 90 | ||||
-rw-r--r-- | include/llvm/ADT/SmallPtrSet.h | 3 | ||||
-rw-r--r-- | include/llvm/ADT/StringExtras.h | 21 | ||||
-rw-r--r-- | include/llvm/ADT/StringMap.h | 2 | ||||
-rw-r--r-- | include/llvm/ADT/Triple.h | 7 | ||||
-rw-r--r-- | include/llvm/ADT/ValueMap.h | 24 |
9 files changed, 91 insertions, 108 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index d40727d..2b466f9 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -320,6 +320,7 @@ namespace llvm { const fltSemantics &getSemantics() const { return *semantics; } bool isZero() const { return category == fcZero; } bool isNonZero() const { return category != fcZero; } + bool isNormal() const { return category == fcNormal; } bool isNaN() const { return category == fcNaN; } bool isInfinity() const { return category == fcInfinity; } bool isNegative() const { return sign; } diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 672147d..8d4a19d 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -30,12 +30,11 @@ namespace llvm { template<typename KeyT, typename ValueT, typename KeyInfoT = DenseMapInfo<KeyT>, - typename ValueInfoT = DenseMapInfo<ValueT>, bool IsConst = false> + bool IsConst = false> class DenseMapIterator; template<typename KeyT, typename ValueT, - typename KeyInfoT = DenseMapInfo<KeyT>, - typename ValueInfoT = DenseMapInfo<ValueT> > + typename KeyInfoT = DenseMapInfo<KeyT> > class DenseMap { typedef std::pair<KeyT, ValueT> BucketT; unsigned NumBuckets; @@ -80,7 +79,7 @@ public: typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator; typedef DenseMapIterator<KeyT, ValueT, - KeyInfoT, ValueInfoT, true> const_iterator; + KeyInfoT, true> const_iterator; inline iterator begin() { // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets(). return empty() ? end() : iterator(Buckets, Buckets+NumBuckets); @@ -256,7 +255,7 @@ public: private: void CopyFrom(const DenseMap& other) { if (NumBuckets != 0 && - (!isPodLike<KeyInfoT>::value || !isPodLike<ValueInfoT>::value)) { + (!isPodLike<KeyT>::value || !isPodLike<ValueT>::value)) { const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) { if (!KeyInfoT::isEqual(P->first, EmptyKey) && @@ -285,7 +284,7 @@ private: Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets)); - if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value) + if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT)); else for (size_t i = 0; i < NumBuckets; ++i) { @@ -502,12 +501,12 @@ public: }; template<typename KeyT, typename ValueT, - typename KeyInfoT, typename ValueInfoT, bool IsConst> + typename KeyInfoT, bool IsConst> class DenseMapIterator { typedef std::pair<KeyT, ValueT> Bucket; typedef DenseMapIterator<KeyT, ValueT, - KeyInfoT, ValueInfoT, true> ConstIterator; - friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, ValueInfoT, true>; + KeyInfoT, true> ConstIterator; + friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>; public: typedef ptrdiff_t difference_type; typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type; @@ -528,7 +527,7 @@ public: // const_iterator and the default copy constructor is used. // Otherwise this is a copy constructor for iterator. DenseMapIterator(const DenseMapIterator<KeyT, ValueT, - KeyInfoT, ValueInfoT, false>& I) + KeyInfoT, false>& I) : Ptr(I.Ptr), End(I.End) {} reference operator*() const { @@ -566,9 +565,9 @@ private: } }; -template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT> +template<typename KeyT, typename ValueT, typename KeyInfoT> static inline size_t -capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT, ValueInfoT> &X) { +capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) { return X.getMemorySize(); } diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index d2e0b8f..7d7c777 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -193,12 +193,11 @@ protected: virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0; /// NodeEquals - Instantiations of the FoldingSet template implement /// this function to compare the given node with the given ID. - virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, + virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID) const=0; - /// NodeEquals - Instantiations of the FoldingSet template implement + /// ComputeNodeHash - Instantiations of the FoldingSet template implement /// this function to compute a hash value for the given node. - virtual unsigned ComputeNodeHash(Node *N, - FoldingSetNodeID &TempID) const = 0; + virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0; }; //===----------------------------------------------------------------------===// @@ -220,7 +219,7 @@ template<typename T> struct DefaultFoldingSetTrait { // to compute a temporary ID if necessary. The default implementation // just calls Profile and does a regular comparison. Implementations // can override this to provide more efficient implementations. - static inline bool Equals(T &X, const FoldingSetNodeID &ID, + static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID); // ComputeHash - Compute a hash value for X, using TempID to @@ -249,7 +248,7 @@ struct DefaultContextualFoldingSetTrait { static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) { X.Profile(ID, Context); } - static inline bool Equals(T &X, const FoldingSetNodeID &ID, + static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID, Ctx Context); static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID, Ctx Context); @@ -344,7 +343,7 @@ template<class T> class FoldingSetBucketIterator; template<typename T> inline bool DefaultFoldingSetTrait<T>::Equals(T &X, const FoldingSetNodeID &ID, - FoldingSetNodeID &TempID) { + unsigned IDHash, FoldingSetNodeID &TempID) { FoldingSetTrait<T>::Profile(X, TempID); return TempID == ID; } @@ -358,6 +357,7 @@ template<typename T, typename Ctx> inline bool DefaultContextualFoldingSetTrait<T, Ctx>::Equals(T &X, const FoldingSetNodeID &ID, + unsigned IDHash, FoldingSetNodeID &TempID, Ctx Context) { ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context); @@ -387,15 +387,14 @@ private: } /// NodeEquals - Instantiations may optionally provide a way to compare a /// node with a specified ID. - virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, + virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID) const { T *TN = static_cast<T *>(N); - return FoldingSetTrait<T>::Equals(*TN, ID, TempID); + return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID); } - /// NodeEquals - Instantiations may optionally provide a way to compute a + /// ComputeNodeHash - Instantiations may optionally provide a way to compute a /// hash value directly from a node. - virtual unsigned ComputeNodeHash(Node *N, - FoldingSetNodeID &TempID) const { + virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const { T *TN = static_cast<T *>(N); return FoldingSetTrait<T>::ComputeHash(*TN, TempID); } @@ -465,10 +464,11 @@ private: ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context); } virtual bool NodeEquals(FoldingSetImpl::Node *N, - const FoldingSetNodeID &ID, + const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID) const { T *TN = static_cast<T *>(N); - return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, TempID, Context); + return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID, + Context); } virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N, FoldingSetNodeID &TempID) const { diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index 81a5117..53032ee 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -505,13 +505,10 @@ namespace detail { /// recursive combining of arguments used in hash_combine. It is particularly /// useful at minimizing the code in the recursive calls to ease the pain /// caused by a lack of variadic functions. -class hash_combine_recursive_helper { - const size_t seed; +struct hash_combine_recursive_helper { char buffer[64]; - char *const buffer_end; - char *buffer_ptr; - size_t length; hash_state state; + const size_t seed; public: /// \brief Construct a recursive hash combining helper. @@ -519,10 +516,7 @@ public: /// This sets up the state for a recursive hash combine, including getting /// the seed and buffer setup. hash_combine_recursive_helper() - : seed(get_execution_seed()), - buffer_end(buffer + array_lengthof(buffer)), - buffer_ptr(buffer), - length(0) {} + : seed(get_execution_seed()) {} /// \brief Combine one chunk of data into the current in-flight hash. /// @@ -530,7 +524,8 @@ public: /// the data. If the buffer is full, it hashes the buffer into its /// hash_state, empties it, and then merges the new chunk in. This also /// handles cases where the data straddles the end of the buffer. - template <typename T> void combine_data(T data) { + template <typename T> + char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) { if (!store_and_advance(buffer_ptr, buffer_end, data)) { // Check for skew which prevents the buffer from being packed, and do // a partial store into the buffer to fill it. This is only a concern @@ -561,6 +556,7 @@ public: partial_store_size)) abort(); } + return buffer_ptr; } #if defined(__has_feature) && __has_feature(__cxx_variadic_templates__) @@ -570,11 +566,12 @@ public: /// This function recurses through each argument, combining that argument /// into a single hash. template <typename T, typename ...Ts> - hash_code combine(const T &arg, const Ts &...args) { - combine_data( get_hashable_data(arg)); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T &arg, const Ts &...args) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg)); // Recurse to the next argument. - return combine(args...); + return combine(length, buffer_ptr, buffer_end, args...); } #else @@ -583,37 +580,43 @@ public: template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, const T6 &arg6) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3, arg4, arg5, arg6); + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6); } template <typename T1, typename T2, typename T3, typename T4, typename T5> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3, arg4, arg5); + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5); } template <typename T1, typename T2, typename T3, typename T4> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3, arg4); + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4); } template <typename T1, typename T2, typename T3> - hash_code combine(const T1 &arg1, const T2 &arg2, const T3 &arg3) { - combine_data(get_hashable_data(arg1)); - return combine(arg2, arg3); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2, const T3 &arg3) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2, arg3); } template <typename T1, typename T2> - hash_code combine(const T1 &arg1, const T2 &arg2) { - combine_data(get_hashable_data(arg1)); - return combine(arg2); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1, const T2 &arg2) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end, arg2); } template <typename T1> - hash_code combine(const T1 &arg1) { - combine_data(get_hashable_data(arg1)); - return combine(); + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, + const T1 &arg1) { + buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1)); + return combine(length, buffer_ptr, buffer_end); } #endif @@ -623,7 +626,7 @@ public: /// The base case when combining arguments recursively is reached when all /// arguments have been handled. It flushes the remaining buffer and /// constructs a hash_code. - hash_code combine() { + hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) { // Check whether the entire set of values fit in the buffer. If so, we'll // use the optimized short hashing routine and skip state entirely. if (length == 0) @@ -663,7 +666,7 @@ public: template <typename ...Ts> hash_code hash_combine(const Ts &...args) { // Recursively hash each argument using a helper class. ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(args...); + return helper.combine(0, helper.buffer, helper.buffer + 64, args...); } #else @@ -674,36 +677,39 @@ template <typename ...Ts> hash_code hash_combine(const Ts &...args) { template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, - const T4 &arg4, const T5 &arg5, const T6 &arg6) { + const T4 &arg4, const T5 &arg5, const T6 &arg6) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3, arg4, arg5, arg6); + return helper.combine(0, helper.buffer, helper.buffer + 64, + arg1, arg2, arg3, arg4, arg5, arg6); } template <typename T1, typename T2, typename T3, typename T4, typename T5> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, - const T4 &arg4, const T5 &arg5) { + const T4 &arg4, const T5 &arg5) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3, arg4, arg5); + return helper.combine(0, helper.buffer, helper.buffer + 64, + arg1, arg2, arg3, arg4, arg5); } template <typename T1, typename T2, typename T3, typename T4> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, - const T4 &arg4) { + const T4 &arg4) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3, arg4); + return helper.combine(0, helper.buffer, helper.buffer + 64, + arg1, arg2, arg3, arg4); } template <typename T1, typename T2, typename T3> hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2, arg3); + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3); } template <typename T1, typename T2> hash_code hash_combine(const T1 &arg1, const T2 &arg2) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1, arg2); + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2); } template <typename T1> hash_code hash_combine(const T1 &arg1) { ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(arg1); + return helper.combine(0, helper.buffer, helper.buffer + 64, arg1); } #endif diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 70693d5..498a034 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -126,9 +126,6 @@ protected: private: bool isSmall() const { return CurArray == SmallArray; } - unsigned Hash(const void *Ptr) const { - return static_cast<unsigned>(((uintptr_t)Ptr >> 4) & (CurArraySize-1)); - } const void * const *FindBucketFor(const void *Ptr) const; void shrink_and_clear(); diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 4e0e018..655d884 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -15,12 +15,7 @@ #define LLVM_ADT_STRINGEXTRAS_H #include "llvm/Support/DataTypes.h" -#include "llvm/ADT/APFloat.h" -#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/StringRef.h" -#include <cctype> -#include <cstdio> -#include <string> namespace llvm { template<typename T> class SmallVectorImpl; @@ -101,22 +96,6 @@ static inline std::string itostr(int64_t X) { return utostr(static_cast<uint64_t>(X)); } -static inline std::string ftostr(double V) { - char Buffer[200]; - sprintf(Buffer, "%20.6e", V); - char *B = Buffer; - while (*B == ' ') ++B; - return B; -} - -static inline std::string ftostr(const APFloat& V) { - if (&V.getSemantics() == &APFloat::IEEEdouble) - return ftostr(V.convertToDouble()); - else if (&V.getSemantics() == &APFloat::IEEEsingle) - return ftostr((double)V.convertToFloat()); - return "<unknown format in ftostr>"; // error -} - /// StrInStrNoCase - Portable version of strcasestr. Locates the first /// occurrence of string 's1' in string 's2', ignoring case. Returns /// the offset of s2 in s1 or npos if s2 cannot be found. diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index 097418e..b4497a2 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -239,7 +239,7 @@ public: explicit StringMap(AllocatorTy A) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {} - explicit StringMap(const StringMap &RHS) + StringMap(const StringMap &RHS) : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { assert(RHS.empty() && "Copy ctor from non-empty stringmap not implemented yet!"); diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 102c95a..f5f99d0 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -72,7 +72,9 @@ public: Apple, PC, - SCEI + SCEI, + BGP, + BGQ }; enum OSType { UnknownOS, @@ -95,7 +97,8 @@ public: Haiku, Minix, RTEMS, - NativeClient + NativeClient, + CNK // BG/P Compute-Node Kernel }; enum EnvironmentType { UnknownEnvironment, diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h index d1f4e5a..707d07d 100644 --- a/include/llvm/ADT/ValueMap.h +++ b/include/llvm/ADT/ValueMap.h @@ -35,7 +35,7 @@ namespace llvm { -template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> +template<typename KeyT, typename ValueT, typename Config> class ValueMapCallbackVH; template<typename DenseMapT, typename KeyT> @@ -72,13 +72,11 @@ struct ValueMapConfig { }; /// See the file comment. -template<typename KeyT, typename ValueT, typename Config = ValueMapConfig<KeyT>, - typename ValueInfoT = DenseMapInfo<ValueT> > +template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> > class ValueMap { - friend class ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT>; - typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> ValueMapCVH; - typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>, - ValueInfoT> MapT; + friend class ValueMapCallbackVH<KeyT, ValueT, Config>; + typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH; + typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH> > MapT; typedef typename Config::ExtraData ExtraData; MapT Map; ExtraData Data; @@ -190,11 +188,11 @@ private: // This CallbackVH updates its ValueMap when the contained Value changes, // according to the user's preferences expressed through the Config object. -template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> +template<typename KeyT, typename ValueT, typename Config> class ValueMapCallbackVH : public CallbackVH { - friend class ValueMap<KeyT, ValueT, Config, ValueInfoT>; + friend class ValueMap<KeyT, ValueT, Config>; friend struct DenseMapInfo<ValueMapCallbackVH>; - typedef ValueMap<KeyT, ValueT, Config, ValueInfoT> ValueMapT; + typedef ValueMap<KeyT, ValueT, Config> ValueMapT; typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT; ValueMapT *Map; @@ -244,9 +242,9 @@ public: } }; -template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> -struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > { - typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH; +template<typename KeyT, typename ValueT, typename Config> +struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > { + typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH; typedef DenseMapInfo<KeyT> PointerInfo; static inline VH getEmptyKey() { |