#ifndef LLVM_ADT_VALUEMAP_H
#define LLVM_ADT_VALUEMAP_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/type_traits.h"
#include <iterator>
namespace llvm {
template<typename KeyT, typename ValueT, typename Config>
class ValueMapCallbackVH;
template<typename DenseMapT, typename KeyT>
class ValueMapIterator;
template<typename DenseMapT, typename KeyT>
class ValueMapConstIterator;
template<typename KeyT>
struct ValueMapConfig {
enum { FollowRAUW = true };
struct ExtraData {};
template<typename ExtraDataT>
static void onRAUW(const ExtraDataT & , KeyT , KeyT ) {}
template<typename ExtraDataT>
static void onDelete(const ExtraDataT &, KeyT ) {}
template<typename ExtraDataT>
static sys::Mutex *getMutex(const ExtraDataT &) { return NULL; }
};
template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> >
class ValueMap {
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;
ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION;
ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION;
public:
typedef KeyT key_type;
typedef ValueT mapped_type;
typedef std::pair<KeyT, ValueT> value_type;
explicit ValueMap(unsigned NumInitBuckets = 64)
: Map(NumInitBuckets), Data() {}
explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
: Map(NumInitBuckets), Data(Data) {}
~ValueMap() {}
typedef ValueMapIterator<MapT, KeyT> iterator;
typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
inline iterator begin() { return iterator(Map.begin()); }
inline iterator end() { return iterator(Map.end()); }
inline const_iterator begin() const { return const_iterator(Map.begin()); }
inline const_iterator end() const { return const_iterator(Map.end()); }
bool empty() const { return Map.empty(); }
unsigned size() const { return Map.size(); }
void resize(size_t Size) { Map.resize(Size); }
void clear() { Map.clear(); }
bool count(const KeyT &Val) const {
return Map.find_as(Val) != Map.end();
}
iterator find(const KeyT &Val) {
return iterator(Map.find_as(Val));
}
const_iterator find(const KeyT &Val) const {
return const_iterator(Map.find_as(Val));
}
ValueT lookup(const KeyT &Val) const {
typename MapT::const_iterator I = Map.find_as(Val);
return I != Map.end() ? I->second : ValueT();
}
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
std::pair<typename MapT::iterator, bool> map_result=
Map.insert(std::make_pair(Wrap(KV.first), KV.second));
return std::make_pair(iterator(map_result.first), map_result.second);
}
template<typename InputIt>
void insert(InputIt I, InputIt E) {
for (; I != E; ++I)
insert(*I);
}
bool erase(const KeyT &Val) {
typename MapT::iterator I = Map.find_as(Val);
if (I == Map.end())
return false;
Map.erase(I);
return true;
}
void erase(iterator I) {
return Map.erase(I.base());
}
value_type& FindAndConstruct(const KeyT &Key) {
return Map.FindAndConstruct(Wrap(Key));
}
ValueT &operator[](const KeyT &Key) {
return Map[Wrap(Key)];
}
bool isPointerIntoBucketsArray(const void *Ptr) const {
return Map.isPointerIntoBucketsArray(Ptr);
}
const void *getPointerIntoBucketsArray() const {
return Map.getPointerIntoBucketsArray();
}
private:
ValueMapCVH Wrap(KeyT key) const {
return ValueMapCVH(key, const_cast<ValueMap*>(this));
}
};
template<typename KeyT, typename ValueT, typename Config>
class ValueMapCallbackVH : public CallbackVH {
friend class ValueMap<KeyT, ValueT, Config>;
friend struct DenseMapInfo<ValueMapCallbackVH>;
typedef ValueMap<KeyT, ValueT, Config> ValueMapT;
typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT;
ValueMapT *Map;
ValueMapCallbackVH(KeyT Key, ValueMapT *Map)
: CallbackVH(const_cast<Value*>(static_cast<const Value*>(Key))),
Map(Map) {}
public:
KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); }
virtual void deleted() {
ValueMapCallbackVH Copy(*this);
sys::Mutex *M = Config::getMutex(Copy.Map->Data);
if (M)
M->acquire();
Config::onDelete(Copy.Map->Data, Copy.Unwrap()); Copy.Map->Map.erase(Copy); if (M)
M->release();
}
virtual void allUsesReplacedWith(Value *new_key) {
assert(isa<KeySansPointerT>(new_key) &&
"Invalid RAUW on key of ValueMap<>");
ValueMapCallbackVH Copy(*this);
sys::Mutex *M = Config::getMutex(Copy.Map->Data);
if (M)
M->acquire();
KeyT typed_new_key = cast<KeySansPointerT>(new_key);
Config::onRAUW(Copy.Map->Data, Copy.Unwrap(), typed_new_key);
if (Config::FollowRAUW) {
typename ValueMapT::MapT::iterator I = Copy.Map->Map.find(Copy);
if (I != Copy.Map->Map.end()) {
ValueT Target(I->second);
Copy.Map->Map.erase(I); Copy.Map->insert(std::make_pair(typed_new_key, Target));
}
}
if (M)
M->release();
}
};
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() {
return VH(PointerInfo::getEmptyKey(), NULL);
}
static inline VH getTombstoneKey() {
return VH(PointerInfo::getTombstoneKey(), NULL);
}
static unsigned getHashValue(const VH &Val) {
return PointerInfo::getHashValue(Val.Unwrap());
}
static unsigned getHashValue(const KeyT &Val) {
return PointerInfo::getHashValue(Val);
}
static bool isEqual(const VH &LHS, const VH &RHS) {
return LHS == RHS;
}
static bool isEqual(const KeyT &LHS, const VH &RHS) {
return LHS == RHS.getValPtr();
}
};
template<typename DenseMapT, typename KeyT>
class ValueMapIterator :
public std::iterator<std::forward_iterator_tag,
std::pair<KeyT, typename DenseMapT::mapped_type>,
ptrdiff_t> {
typedef typename DenseMapT::iterator BaseT;
typedef typename DenseMapT::mapped_type ValueT;
BaseT I;
public:
ValueMapIterator() : I() {}
ValueMapIterator(BaseT I) : I(I) {}
BaseT base() const { return I; }
struct ValueTypeProxy {
const KeyT first;
ValueT& second;
ValueTypeProxy *operator->() { return this; }
operator std::pair<KeyT, ValueT>() const {
return std::make_pair(first, second);
}
};
ValueTypeProxy operator*() const {
ValueTypeProxy Result = {I->first.Unwrap(), I->second};
return Result;
}
ValueTypeProxy operator->() const {
return operator*();
}
bool operator==(const ValueMapIterator &RHS) const {
return I == RHS.I;
}
bool operator!=(const ValueMapIterator &RHS) const {
return I != RHS.I;
}
inline ValueMapIterator& operator++() { ++I;
return *this;
}
ValueMapIterator operator++(int) { ValueMapIterator tmp = *this; ++*this; return tmp;
}
};
template<typename DenseMapT, typename KeyT>
class ValueMapConstIterator :
public std::iterator<std::forward_iterator_tag,
std::pair<KeyT, typename DenseMapT::mapped_type>,
ptrdiff_t> {
typedef typename DenseMapT::const_iterator BaseT;
typedef typename DenseMapT::mapped_type ValueT;
BaseT I;
public:
ValueMapConstIterator() : I() {}
ValueMapConstIterator(BaseT I) : I(I) {}
ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other)
: I(Other.base()) {}
BaseT base() const { return I; }
struct ValueTypeProxy {
const KeyT first;
const ValueT& second;
ValueTypeProxy *operator->() { return this; }
operator std::pair<KeyT, ValueT>() const {
return std::make_pair(first, second);
}
};
ValueTypeProxy operator*() const {
ValueTypeProxy Result = {I->first.Unwrap(), I->second};
return Result;
}
ValueTypeProxy operator->() const {
return operator*();
}
bool operator==(const ValueMapConstIterator &RHS) const {
return I == RHS.I;
}
bool operator!=(const ValueMapConstIterator &RHS) const {
return I != RHS.I;
}
inline ValueMapConstIterator& operator++() { ++I;
return *this;
}
ValueMapConstIterator operator++(int) { ValueMapConstIterator tmp = *this; ++*this; return tmp;
}
};
}
#endif