Introduce SmallPtrSetImpl<T *> which allows insert, erase, count, and

iteration. This alows the majority of operations to be performed without
encoding a specific small size. It follows the model of
SmallVectorImpl<T>.

llvm-svn: 200688
This commit is contained in:
Chandler Carruth 2014-02-03 11:24:21 +00:00
parent 173bd7ed2e
commit 784de75ca8
1 changed files with 45 additions and 22 deletions

View File

@ -235,30 +235,27 @@ struct RoundUpToPowerOfTwo {
}; };
/// SmallPtrSet - This class implements a set which is optimized for holding /// \brief A templated base class for \c SmallPtrSet which provides the
/// SmallSize or less elements. This internally rounds up SmallSize to the next /// typesafe interface that is common across all small sizes.
/// power of two if it is not already a power of two. See the comments above ///
/// SmallPtrSetImplBase for details of the algorithm. /// This is particularly useful for passing around between interface boundaries
template<class PtrType, unsigned SmallSize> /// to avoid encoding a particular small size in the interface boundary.
class SmallPtrSet : public SmallPtrSetImplBase { template <typename PtrType>
// Make sure that SmallSize is a power of two, round up if not. class SmallPtrSetImpl : public SmallPtrSetImplBase {
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
/// SmallStorage - Fixed size storage used in 'small mode'.
const void *SmallStorage[SmallSizePowTwo];
typedef PointerLikeTypeTraits<PtrType> PtrTraits; typedef PointerLikeTypeTraits<PtrType> PtrTraits;
public: protected:
SmallPtrSet() : SmallPtrSetImplBase(SmallStorage, SmallSizePowTwo) {} // Constructors that forward to the base.
SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImplBase(SmallStorage, that) {} SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that)
: SmallPtrSetImplBase(SmallStorage, that) {}
#if LLVM_HAS_RVALUE_REFERENCES #if LLVM_HAS_RVALUE_REFERENCES
SmallPtrSet(SmallPtrSet &&that) SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
: SmallPtrSetImplBase(SmallStorage, SmallSizePowTwo, std::move(that)) {} SmallPtrSetImpl &&that)
: SmallPtrSetImplBase(SmallStorage, SmallSize, std::move(that)) {}
#endif #endif
explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize)
: SmallPtrSetImplBase(SmallStorage, SmallSize) {}
template<typename It> public:
SmallPtrSet(It I, It E) : SmallPtrSetImplBase(SmallStorage, SmallSizePowTwo) {
insert(I, E);
}
/// insert - This returns true if the pointer was new to the set, false if it /// insert - This returns true if the pointer was new to the set, false if it
/// was already in the set. /// was already in the set.
bool insert(PtrType Ptr) { bool insert(PtrType Ptr) {
@ -290,11 +287,37 @@ public:
inline iterator end() const { inline iterator end() const {
return iterator(CurArray+CurArraySize, CurArray+CurArraySize); return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
} }
};
/// SmallPtrSet - This class implements a set which is optimized for holding
/// SmallSize or less elements. This internally rounds up SmallSize to the next
/// power of two if it is not already a power of two. See the comments above
/// SmallPtrSetImplBase for details of the algorithm.
template<class PtrType, unsigned SmallSize>
class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
typedef SmallPtrSetImpl<PtrType> BaseT;
// Make sure that SmallSize is a power of two, round up if not.
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
/// SmallStorage - Fixed size storage used in 'small mode'.
const void *SmallStorage[SmallSizePowTwo];
public:
SmallPtrSet() : BaseT(SmallStorage, SmallSizePowTwo) {}
SmallPtrSet(const SmallPtrSet &that) : BaseT(SmallStorage, that) {}
#if LLVM_HAS_RVALUE_REFERENCES
SmallPtrSet(SmallPtrSet &&that)
: BaseT(SmallStorage, SmallSizePowTwo, std::move(that)) {}
#endif
template<typename It>
SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) {
this->insert(I, E);
}
SmallPtrSet<PtrType, SmallSize> & SmallPtrSet<PtrType, SmallSize> &
operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) { operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
if (&RHS != this) if (&RHS != this)
CopyFrom(RHS); this->CopyFrom(RHS);
return *this; return *this;
} }
@ -302,7 +325,7 @@ public:
SmallPtrSet<PtrType, SmallSize>& SmallPtrSet<PtrType, SmallSize>&
operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) { operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
if (&RHS != this) if (&RHS != this)
MoveFrom(SmallSizePowTwo, std::move(RHS)); this->MoveFrom(SmallSizePowTwo, std::move(RHS));
return *this; return *this;
} }
#endif #endif