<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>