<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Aug 16, 2015 at 4:17 PM, Chandler Carruth via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Sun Aug 16 18:17:27 2015<br>
New Revision: 245192<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=245192&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=245192&view=rev</a><br>
Log:<br>
[ADT] Teach FoldingSet to be movable.<br>
<br>
This is a very minimal move support - it leaves the moved-from object in<br>
a zombie state that is only valid for destruction and move assignment.<br>
This seems fine to me, and leaving it in the default constructed state<br>
would require adding more state to the object and potentially allocating<br>
memory (!!!) and so seems like a Bad Idea.<br></blockquote><div><br></div><div>Might be worth a unit test (possibly with a move-only value, or even a move-and-copyable value that checks that it only gets moved - actually, I assume neither happens, so perhaps it can be done with a non-copyable, non-movable type?)<br><br>- Dave</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Modified:<br>
    llvm/trunk/include/llvm/ADT/FoldingSet.h<br>
    llvm/trunk/lib/Support/FoldingSet.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/ADT/FoldingSet.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/FoldingSet.h?rev=245192&r1=245191&r2=245192&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/FoldingSet.h?rev=245192&r1=245191&r2=245192&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ADT/FoldingSet.h (original)<br>
+++ llvm/trunk/include/llvm/ADT/FoldingSet.h Sun Aug 16 18:17:27 2015<br>
@@ -122,9 +122,10 @@ protected:<br>
   /// is greater than twice the number of buckets.<br>
   unsigned NumNodes;<br>
<br>
-  ~FoldingSetImpl();<br>
-<br>
   explicit FoldingSetImpl(unsigned Log2InitSize = 6);<br>
+  FoldingSetImpl(FoldingSetImpl &&Arg);<br>
+  FoldingSetImpl &operator=(FoldingSetImpl &&RHS);<br>
+  ~FoldingSetImpl();<br>
<br>
 public:<br>
   //===--------------------------------------------------------------------===//<br>
@@ -391,6 +392,10 @@ DefaultContextualFoldingSetTrait<T, Ctx><br>
 /// implementation of the folding set to the node class T.  T must be a<br>
 /// subclass of FoldingSetNode and implement a Profile function.<br>
 ///<br>
+/// Note that this set type is movable and move-assignable. However, its<br>
+/// moved-from state is not a valid state for anything other than<br>
+/// move-assigning and destroying. This is primarily to enable movable APIs<br>
+/// that incorporate these objects.<br>
 template <class T> class FoldingSet final : public FoldingSetImpl {<br>
 private:<br>
   /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a<br>
@@ -415,8 +420,13 @@ private:<br>
<br>
 public:<br>
   explicit FoldingSet(unsigned Log2InitSize = 6)<br>
-  : FoldingSetImpl(Log2InitSize)<br>
-  {}<br>
+      : FoldingSetImpl(Log2InitSize) {}<br>
+<br>
+  FoldingSet(FoldingSet &&Arg) : FoldingSetImpl(std::move(Arg)) {}<br>
+  FoldingSet &operator=(FoldingSet &&RHS) {<br>
+    (void)FoldingSetImpl::operator=(std::move(RHS));<br>
+    return *this;<br>
+  }<br>
<br>
   typedef FoldingSetIterator<T> iterator;<br>
   iterator begin() { return iterator(Buckets); }<br>
<br>
Modified: llvm/trunk/lib/Support/FoldingSet.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/FoldingSet.cpp?rev=245192&r1=245191&r2=245192&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/FoldingSet.cpp?rev=245192&r1=245191&r2=245192&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/FoldingSet.cpp (original)<br>
+++ llvm/trunk/lib/Support/FoldingSet.cpp Sun Aug 16 18:17:27 2015<br>
@@ -232,9 +232,29 @@ FoldingSetImpl::FoldingSetImpl(unsigned<br>
   Buckets = AllocateBuckets(NumBuckets);<br>
   NumNodes = 0;<br>
 }<br>
+<br>
+FoldingSetImpl::FoldingSetImpl(FoldingSetImpl &&Arg)<br>
+    : Buckets(Arg.Buckets), NumBuckets(Arg.NumBuckets), NumNodes(Arg.NumNodes) {<br>
+  Arg.Buckets = nullptr;<br>
+  Arg.NumBuckets = 0;<br>
+  Arg.NumNodes = 0;<br>
+}<br>
+<br>
+FoldingSetImpl &FoldingSetImpl::operator=(FoldingSetImpl &&RHS) {<br>
+  free(Buckets); // This may be null if the set is in a moved-from state.<br>
+  Buckets = RHS.Buckets;<br>
+  NumBuckets = RHS.NumBuckets;<br>
+  NumNodes = RHS.NumNodes;<br>
+  RHS.Buckets = nullptr;<br>
+  RHS.NumBuckets = 0;<br>
+  RHS.NumNodes = 0;<br>
+  return *this;<br>
+}<br>
+<br>
 FoldingSetImpl::~FoldingSetImpl() {<br>
   free(Buckets);<br>
 }<br>
+<br>
 void FoldingSetImpl::clear() {<br>
   // Set all but the last bucket to null pointers.<br>
   memset(Buckets, 0, NumBuckets*sizeof(void*));<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>