/// 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:
//===--------------------------------------------------------------------===//
/// 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
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); }
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*));