1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[ADT] Teach FoldingSet to be movable.

This is a very minimal move support - it leaves the moved-from object in
a zombie state that is only valid for destruction and move assignment.
This seems fine to me, and leaving it in the default constructed state
would require adding more state to the object and potentially allocating
memory (!!!) and so seems like a Bad Idea.

llvm-svn: 245192
This commit is contained in:
Chandler Carruth 2015-08-16 23:17:27 +00:00
parent 0d20382123
commit 32584972c5
2 changed files with 34 additions and 4 deletions

View File

@ -122,9 +122,10 @@ protected:
/// is greater than twice the number of buckets.
unsigned NumNodes;
~FoldingSetImpl();
explicit FoldingSetImpl(unsigned Log2InitSize = 6);
FoldingSetImpl(FoldingSetImpl &&Arg);
FoldingSetImpl &operator=(FoldingSetImpl &&RHS);
~FoldingSetImpl();
public:
//===--------------------------------------------------------------------===//
@ -391,6 +392,10 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
/// implementation of the folding set to the node class T. T must be a
/// subclass of FoldingSetNode and implement a Profile function.
///
/// Note that this set type is movable and move-assignable. However, its
/// moved-from state is not a valid state for anything other than
/// move-assigning and destroying. This is primarily to enable movable APIs
/// that incorporate these objects.
template <class T> class FoldingSet final : public FoldingSetImpl {
private:
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
@ -415,8 +420,13 @@ private:
public:
explicit FoldingSet(unsigned Log2InitSize = 6)
: FoldingSetImpl(Log2InitSize)
{}
: FoldingSetImpl(Log2InitSize) {}
FoldingSet(FoldingSet &&Arg) : FoldingSetImpl(std::move(Arg)) {}
FoldingSet &operator=(FoldingSet &&RHS) {
(void)FoldingSetImpl::operator=(std::move(RHS));
return *this;
}
typedef FoldingSetIterator<T> iterator;
iterator begin() { return iterator(Buckets); }

View File

@ -232,9 +232,29 @@ FoldingSetImpl::FoldingSetImpl(unsigned Log2InitSize) {
Buckets = AllocateBuckets(NumBuckets);
NumNodes = 0;
}
FoldingSetImpl::FoldingSetImpl(FoldingSetImpl &&Arg)
: Buckets(Arg.Buckets), NumBuckets(Arg.NumBuckets), NumNodes(Arg.NumNodes) {
Arg.Buckets = nullptr;
Arg.NumBuckets = 0;
Arg.NumNodes = 0;
}
FoldingSetImpl &FoldingSetImpl::operator=(FoldingSetImpl &&RHS) {
free(Buckets); // This may be null if the set is in a moved-from state.
Buckets = RHS.Buckets;
NumBuckets = RHS.NumBuckets;
NumNodes = RHS.NumNodes;
RHS.Buckets = nullptr;
RHS.NumBuckets = 0;
RHS.NumNodes = 0;
return *this;
}
FoldingSetImpl::~FoldingSetImpl() {
free(Buckets);
}
void FoldingSetImpl::clear() {
// Set all but the last bucket to null pointers.
memset(Buckets, 0, NumBuckets*sizeof(void*));