<html><head><style>
body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        padding:1em;
        margin:auto;
        background:#fefefe;
}

h1, h2, h3, h4, h5, h6 {
        font-weight: bold;
}

h1 {
        color: #000000;
        font-size: 28pt;
}

h2 {
        border-bottom: 1px solid #CCCCCC;
        color: #000000;
        font-size: 24px;
}

h3 {
        font-size: 18px;
}

h4 {
        font-size: 16px;
}

h5 {
        font-size: 14px;
}

h6 {
        color: #777777;
        background-color: inherit;
        font-size: 14px;
}

hr {
        height: 0.2em;
        border: 0;
        color: #CCCCCC;
        background-color: #CCCCCC;
    display: inherit;
}

p, blockquote, ul, ol, dl, li, table, pre {
        margin: 15px 0;
}

a, a:visited {
        color: #4183C4;
        background-color: inherit;
        text-decoration: none;
}

#message {
        border-radius: 6px;
        border: 1px solid #ccc;
        display:block;
        width:100%;
        height:60px;
        margin:6px 0px;
}

button, #ws {
        font-size: 12 pt;
        padding: 4px 6px;
        border-radius: 5px;
        border: 1px solid #bbb;
        background-color: #eee;
}

code, pre, #ws, #message {
        font-family: Monaco;
        font-size: 10pt;
        border-radius: 3px;
        background-color: #F8F8F8;
        color: inherit;
}

code {
        border: 1px solid #EAEAEA;
        margin: 0 2px;
        padding: 0 5px;
}

pre {
        border: 1px solid #CCCCCC;
        overflow: auto;
        padding: 4px 8px;
}

pre > code {
        border: 0;
        margin: 0;
        padding: 0;
}

#ws { background-color: #f8f8f8; }


.bloop_markdown table {
border-collapse: collapse;  
font-family: Helvetica, arial, freesans, clean, sans-serif;  
color: rgb(51, 51, 51);  
font-size: 15px; line-height: 25px;
padding: 0; }

.bloop_markdown table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
     
.bloop_markdown table tr:nth-child(2n) {
background-color: #f8f8f8; }

.bloop_markdown table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr th :first-child, table tr td :first-child {
margin-top: 0; }

.bloop_markdown table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }

.bloop_markdown blockquote{
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

code, pre, #ws, #message {
    word-break: normal;
    word-wrap: normal;
}

hr {
    display: inherit;
}

.bloop_markdown :first-child {
    -webkit-margin-before: 0;
}

code, pre, #ws, #message {
    font-family: Menlo, Consolas, Liberation Mono, Courier, monospace;
}


.send { color:#77bb77; }
.server { color:#7799bb; }
.error { color:#AA0000; }</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="bloop_markdown"><p>One note about the cloning:</p>

<pre><code class="xml">&lt;root&gt;
   &lt;first&gt;
      &lt;second/&gt;
   &lt;/first&gt;
&lt;/root&gt;
</code></pre>

<pre><code class="swift">var root = XML.Element(name: "root")
var first = XML.Element(name: "first")
var second = XML.Element(name: "second")
first.add(second)

root[first][second].add(root) // Lets say we don't clone here anything
</code></pre>

<p>In that scenario we would add <code>root</code> as the first item to <code>second</code>. </p>

<pre><code class="xml">&lt;root&gt;
   &lt;first&gt;
      &lt;second&gt;   &lt;- - - - - - - -+
         &lt;root&gt;                  | That would be the same item (baked with a class)
            &lt;first&gt;              | and that means that the inner `second` also has
               &lt;second/&gt; &lt;- - - -+ a child `root` =&gt; cycle graph.
            &lt;/first&gt;             |
         &lt;/root&gt;                 |
      &lt;/second&gt;  &lt;- - - - - - - -+
   &lt;/first&gt;
&lt;/root&gt;
</code></pre>

<p></p></div><div class="bloop_original_html"><style>body{font-family:Helvetica,Arial;font-size:13px}</style><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div> <br> <div id="bloop_sign_1474357057623046912" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">--&nbsp;<br>Adrian Zubarev<br>Sent with Airmail</div></div> <br><p class="airmail_on">Am 20. September 2016 um 09:37:22, Adrian Zubarev (<a href="mailto:adrian.zubarev@devandartist.com">adrian.zubarev@devandartist.com</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div></div><div>




<title></title>



<div class="bloop_markdown">
<p>True, but how do you traverse back the tree from an inner
node?</p>
<p>Lets look at this simple tree:</p>
<pre><code class="xml">&lt;root&gt;
   &lt;first&gt;
      &lt;second/&gt;
   &lt;/first&gt;
&lt;/root&gt;
</code></pre>
<pre><code class="swift">let second = /* get the second node */

second.parent // &lt;— How would you implement this with pure value type?
</code></pre>
<p>If parent were only a struct without a reference type behind the
scenes the parent will also contain the current child, where every
child has the parent and so one. The reference type is there as a
layer to achieve this.</p>
<ul>
<li>What kind of a layer does <code>indirect</code> add on
enums?</li>
<li>Can <code>indirect</code> solve the problem here and can it be
added to structs as well?</li>
</ul>
<p>If I’m missing here something, and there might be a true value
type solution for this problem, I’d throw the whole project away
and rebuild it from the beginning. :)</p>
<p>Best regards,</p>
</div>
<div class="bloop_original_html">

<div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;">
<br></div>
<br>
<div id="bloop_sign_1474356453107894784" class="bloop_sign">
<div style="font-family:helvetica,arial;font-size:13px">
--&nbsp;<br>
Adrian Zubarev<br>
Sent with Airmail</div>
</div>
<br>
<p class="airmail_on">Am 20. September 2016 um 08:56:20, Dave
Abrahams via swift-evolution (<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)
schrieb:</p>
<blockquote type="cite" class="clean_bq">
<div>
<div><span><br>
on Mon Sep 19 2016, Adrian Zubarev
&lt;swift-evolution@swift.org&gt; wrote:<br>
<br>
&gt; I think I just found a solution to my problem:<br>
&gt;<br>
&gt; /// - Parameter child: The new `child` to add to the
`children` array.<br>
&gt; public mutating func add(_ child: Element) {<br>
&gt;<br>
&gt; let clonedChildReference = Reference(cloning:
child.reference)<br>
&gt; let index = self.reference.children.endIndex<br>
&gt;<br>
&gt; self.mutableInsert(clonedChildReference, at: index,
isNotOwnReference: child.reference !== self.reference)<br>
&gt; }<br>
&gt;<br>
&gt; /// Warning: Pass only clonded nodes of type Element to this
function!<br>
<br>
I don't understand why any explicit cloning should be needed. An
XML<br>
tree can be modeled perfectly well using arrays of value types,
which<br>
will “clone” themselves as needed to maintain value
semantics.<br>
<br>
&gt; private mutating func mutableInsert(_ node: XML.Node, at
index: Int,<br>
&gt; isNotOwnReference: Bool) {<br>
&gt;<br>
&gt; // * If `self.reference` is NOT uniquely referenced and `node`
is a String,<br>
&gt; // we should rebuilt own reference.<br>
&gt; // * If `self.reference` is NOT uniquely referenced and `node`
is a Reference<br>
&gt; // `isNotOwnReference` is true, we should rebuilt own
reference.<br>
&gt; // * If `self.reference` is NOT uniquely referenced and `node`
is a clone<br>
&gt; // reference to `self.reference` where is `isNotOwnReference`
is false, we<br>
&gt; // should check if there are more than **two** strong
references to rebuild<br>
&gt; // own reference, otherwise it's an implementation artifact
and we can keep<br>
&gt; // old reference (any `node` of type Reference is cloned
before it's added<br>
&gt; // to the child array).<br>
&gt; let isNotKnownUniquelyReferenced =
!isKnownUniquelyReferenced(&amp;self.reference)<br>
&gt;<br>
&gt; var shouldRebuildReference = false<br>
&gt;<br>
&gt; switch node.kind {<br>
&gt;<br>
&gt; case .element(_):<br>
&gt; let hasMoreThanTwoStrongReferences =
(CFGetRetainCount(self.reference) - 1) &gt; 2<br>
&gt; shouldRebuildReference = (isNotKnownUniquelyReferenced
&amp;&amp; isNotOwnReference) ||
hasMoreThanTwoStrongReferences<br>
&gt;<br>
&gt; case .text(_):<br>
&gt; shouldRebuildReference = isNotKnownUniquelyReferenced<br>
&gt; }<br>
&gt;<br>
&gt; if shouldRebuildReference {<br>
&gt;<br>
&gt; self.reference = Reference(cloning: self.reference, wholeTree:
true)<br>
&gt; }<br>
&gt;<br>
&gt; self.reference.insert(node, at: index)<br>
&gt; }<br>
&gt; I’m using CFGetRetainCount(self.reference) to catch that
implementation artifact.<br>
&gt;<br>
&gt; --&nbsp;<br>
&gt; Adrian Zubarev<br>
&gt; Sent with Airmail<br>
&gt;<br>
&gt; Am 19. September 2016 um 09:59:24, Adrian Zubarev
(adrian.zubarev@devandartist.com) schrieb:<br>
&gt;<br>
&gt; Hello Dave,<br>
&gt;<br>
&gt; thank you for trying to help me. I’ll try to explain the issue
with some more details.<br>
&gt;<br>
&gt; First here is some code:<br>
&gt;<br>
&gt; extension XML {<br>
&gt;<br>
&gt; public struct Element {<br>
&gt;<br>
&gt; // public for testing<br>
&gt; public var reference: Reference<br>
&gt;<br>
&gt; public var name: String { return self.reference.name }<br>
&gt;<br>
&gt; public var children: [Element] {<br>
&gt;<br>
&gt; return self.reference.children.flatMap {<br>
&gt;<br>
&gt; guard case .element(let element) = $0.kind else { return nil
}<br>
&gt; return Element(wrapping: element)<br>
&gt; }<br>
&gt; }<br>
&gt;<br>
&gt; public init(name: String) {<br>
&gt;<br>
&gt; self.reference = Reference(name: name)<br>
&gt; }<br>
&gt;<br>
&gt; public mutating func add(_ child: Element) {<br>
&gt;<br>
&gt; self.mutableInsert(Reference(cloning: child.reference), at:
self.reference.children.endIndex)<br>
&gt; }<br>
&gt;<br>
&gt; // Ignore XML.Node, it's a String or Reference<br>
&gt; // Parameter `Node` is assumed to be a clone of a reference
passed to `add` or `insert` method.<br>
&gt; private mutating func mutableInsert(_ node: XML.Node, at
index: Int) {<br>
&gt;<br>
&gt; // Clone own reference all way up to the root<br>
&gt; if !isKnownUniquelyReferenced(&amp;self.reference) {<br>
&gt;<br>
&gt; self.reference = Reference(cloning: self.reference, wholeTree:
true)<br>
&gt; }<br>
&gt;<br>
&gt; // Extract a reference or just insert a string as a
child<br>
&gt; guard case .element(let nodeReference) = node.kind else
{<br>
&gt;<br>
&gt; self.reference.insert(node, at: index)<br>
&gt; return<br>
&gt; }<br>
&gt;<br>
&gt; // Check for possible debelopment bug<br>
&gt; if nodeReference === self.reference {<br>
&gt;<br>
&gt; fatalError("wrong usage of `mutableInsert` function")<br>
&gt; }<br>
&gt;<br>
&gt; self.reference.insert(nodeReference, at: index)<br>
&gt; }<br>
&gt;<br>
&gt; ...<br>
&gt; }<br>
&gt; }<br>
&gt;<br>
&gt; extension XML.Element {<br>
&gt;<br>
&gt; // public for testing<br>
&gt; public class Reference : XML.Node {<br>
&gt;<br>
&gt; let name: String<br>
&gt;<br>
&gt; private(set) weak var parent: Reference?<br>
&gt;<br>
&gt; private(set) var children: [XML.Node]<br>
&gt;<br>
&gt; var kind: XML.Node.Kind { return .element(self) }<br>
&gt;<br>
&gt; ...<br>
&gt; }<br>
&gt; }<br>
&gt; Now lets focus on the problem.<br>
&gt;<br>
&gt; Every Element is baked with it’s own Reference to be able to
traverse the tree from any of it’s node all way up to the root for
example.<br>
&gt;<br>
&gt; Lets look again at the scenario I already described:<br>
&gt;<br>
&gt; var root = XML.Element(name: "root")<br>
&gt; var elem = XML.Element(name: "elem")<br>
&gt;<br>
&gt; ObjectIdentifier(root.reference) // 0x000060000026ab40<br>
&gt; ObjectIdentifier(elem.reference) // 0x000060800026bb00<br>
&gt;<br>
&gt; isKnownUniquelyReferenced(&amp;root.reference) // true<br>
&gt; isKnownUniquelyReferenced(&amp;elem.reference) // true<br>
&gt;<br>
&gt; root.add(elem)<br>
&gt;<br>
&gt; isKnownUniquelyReferenced(&amp;root.reference) // true<br>
&gt;<br>
&gt; root.add(root)<br>
&gt;<br>
&gt; // The reference of root has changed even if the second
child<br>
&gt; // was cloned and added as a new object to the
reference.<br>
&gt; // 0x000060000026ab40 &lt;-- was thrown away<br>
&gt; isKnownUniquelyReferenced(&amp;root.reference) // true<br>
&gt;<br>
&gt; ObjectIdentifier(root.reference) // 0x000060000026c680 &lt;—
new one<br>
&gt; The way I’m adding children to the tree is that every passed
element of type XML.Element stores a Reference, which will be
cloned and added as a new standalone object to the children
array.<br>
&gt;<br>
&gt; The same happens when we try adding root as it’s own child. We
copy root struct which contains the same reference, then we clone
it inside add method, then we pass the new object to the
mutableInsert function. At that point we don’t need the old
reference anymore, I’m speaking of root.add(root). The problem here
is that at that time root.reference has 2 strong references which I
cannot escape.<br>
&gt;<br>
&gt; I could workaround the problem if I knew the reference counter
value, because I could check if the passed Element contains the
same reference first. And if it does and we have exactly 2 strong
references, I don’t need to recreate root.reference here.<br>
&gt;<br>
&gt; But I couldn’t find any API for that. :/<br>
&gt;<br>
&gt; --&nbsp;<br>
&gt; Adrian Zubarev<br>
&gt; Sent with Airmail<br>
&gt;<br>
&gt; Am 19. September 2016 um 05:50:57, Dave Abrahams via
swift-users (swift-users@swift.org) schrieb:<br>
&gt;<br>
&gt; on Sun Sep 18 2016, Adrian Zubarev
&lt;swift-users-AT-swift.org&gt; wrote:<br>
&gt;<br>
&gt;&gt; Dear Swift community,<br>
&gt;&gt;<br>
&gt;&gt; currently I’m building a value type XML library which is
baked behind<br>
&gt;&gt; the scene with a reference type to manage graph traversing
between<br>
&gt;&gt; nodes. I also like to COW optimize the xml graph, but I
run into one<br>
&gt;&gt; single problem atm.<br>
&gt;&gt;<br>
&gt;&gt; Image this xml tree:<br>
&gt;&gt;<br>
&gt;&gt; &lt;root&gt;<br>
&gt;&gt; &lt;item/&gt;<br>
&gt;&gt; &lt;/root&gt;<br>
&gt;&gt; It’s just a root element with one single child. As for
value types it<br>
&gt;&gt; should be totally fine to do something like this:<br>
&gt;&gt;<br>
&gt;&gt; // The given xml tree<br>
&gt;&gt; var root = XML.Element(name: "root")<br>
&gt;&gt; let item = XML.Element(name: "item")<br>
&gt;&gt; root.add(item)<br>
&gt;&gt;<br>
&gt;&gt; // The problematic behavior<br>
&gt;&gt; root.add(root)<br>
&gt;&gt; If this would be a simple value type without any
references behind the<br>
&gt;&gt; scenes you could imagine that the result of the last code
line will<br>
&gt;&gt; look like this:<br>
&gt;&gt;<br>
&gt;&gt; &lt;root&gt;<br>
&gt;&gt; &lt;item/&gt;<br>
&gt;&gt; &lt;root&gt;<br>
&gt;&gt; &lt;item/&gt;<br>
&gt;&gt; &lt;/root&gt;<br>
&gt;&gt; &lt;/root&gt;<br>
&gt;<br>
&gt; Yep, that's exactly the right answer for a tree with value
semantics.<br>
&gt; The simplest way to implement this tree is to use an Array for
the child<br>
&gt; nodes.<br>
&gt;<br>
&gt;&gt; Basically we copied the whole tree and added it as the
second child<br>
&gt;&gt; into the original root element.<br>
&gt;&gt;<br>
&gt;&gt; As for COW optimization this is a problem, just because
the passed<br>
&gt;&gt; root is a copy of a struct that contains the exact same
reference as<br>
&gt;&gt; the original root element.<br>
&gt;<br>
&gt; I don't understand why that's a problem.<br>
&gt;<br>
&gt;&gt; isKnownUniquelyReferenced(&amp;self.reference) will result
in false inside<br>
&gt;&gt; the add method.<br>
&gt;<br>
&gt; ...as it should.<br>
&gt;<br>
&gt;&gt; Is there any chance I could force my program to decrease
the reference<br>
&gt;&gt; counter of that last item after I’m sure I don’t need
it?!<br>
&gt;<br>
&gt; Which last item? When are you sure you don't need it? What
result do<br>
&gt; you hope for?<br>
&gt;<br>
&gt;&gt; A few more details: inside the add method I’m always
cloning the<br>
&gt;&gt; passed reference just because graphs aren’t that trivial
and otherwise<br>
&gt;&gt; I could possibly end up with a cycle graph, which would be
really<br>
&gt;&gt; bad. After that job I’m sure that I don’t need the passed
reference<br>
&gt;&gt; anymore and I need a way to escape from it.<br>
&gt;&gt;<br>
&gt;&gt; I’d appreciate any suggestions and help. :)<br>
&gt;<br>
&gt; It's not clear what you want to acheive nor can I picture the
code<br>
&gt; you're using to acheive it, so it's hard to give useful
feedback.<br>
&gt;<br>
&gt; Sorry,<br>
&gt;<br>
&gt; --<br>
&gt; -Dave<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; swift-users mailing list<br>
&gt; swift-users@swift.org<br>
&gt; https://lists.swift.org/mailman/listinfo/swift-users<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; swift-evolution@swift.org<br>
&gt; https://lists.swift.org/mailman/listinfo/swift-evolution<br>
&gt;<br>
<br>
--<br>
-Dave<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
https://lists.swift.org/mailman/listinfo/swift-evolution<br></span></div>
</div>
</blockquote>
</div>
<div class="bloop_markdown"></div>


</div></div></span></blockquote></div><div class="bloop_markdown"><p></p></div></body></html>