PointerIntPair.h revision b79a01111d1ed14ec92b969fb995906268733c12
1//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the PointerIntPair class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_POINTERINTPAIR_H
15#define LLVM_ADT_POINTERINTPAIR_H
16
17#include <cassert>
18
19namespace llvm {
20
21template<typename T>
22struct DenseMapInfo;
23
24/// PointerIntPair - This class implements a pair of a pointer and small
25/// integer.  It is designed to represent this in the space required by one
26/// pointer by bitmangling the integer into the low part of the pointer.  This
27/// can only be done for small integers: typically up to 3 bits, but it depends
28/// on the alignment returned by the allocator in use.
29///
30template <typename PointerTy, unsigned IntBits, typename IntType=unsigned>
31class PointerIntPair {
32  intptr_t Value;
33public:
34  PointerIntPair() : Value(0) {}
35  PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
36    setPointer(Ptr);
37    setInt(Int);
38  }
39
40  PointerTy getPointer() const {
41    return reinterpret_cast<PointerTy>(Value & ~((1 << IntBits)-1));
42  }
43
44  IntType getInt() const {
45    return (IntType)(Value & ((1 << IntBits)-1));
46  }
47
48  void setPointer(PointerTy Ptr) {
49    intptr_t PtrVal = reinterpret_cast<intptr_t>(Ptr);
50    assert((PtrVal & ((1 << IntBits)-1)) == 0 &&
51           "Pointer is not sufficiently aligned");
52    Value = PtrVal | (intptr_t)getInt();
53  }
54
55  void setInt(IntType Int) {
56    intptr_t IntVal = Int;
57    assert(IntVal < (1 << IntBits) && "Integer too large for field");
58    Value = reinterpret_cast<intptr_t>(getPointer()) | IntVal;
59  }
60
61  void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
62  void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
63
64  bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
65  bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
66  bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
67  bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
68  bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
69  bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
70};
71
72// Provide specialization of DenseMapInfo for PointerIntPair.
73template<typename PointerTy, unsigned IntBits, typename IntType>
74struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
75  typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
76  static Ty getEmptyKey() {
77    return Ty(reinterpret_cast<PointerTy>(-1 << IntBits),
78              IntType((1 << IntBits)-1));
79  }
80  static Ty getTombstoneKey() {
81    return Ty(reinterpret_cast<PointerTy>(-2 << IntBits), IntType(0));
82  }
83  static unsigned getHashValue(Ty V) {
84    uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
85    return unsigned(IV) ^ unsigned(IV >> 9);
86  }
87  static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
88  static bool isPod() { return true; }
89};
90
91} // end namespace llvm
92#endif
93