<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Updated proposal:<div class=""><br class=""></div><div class=""><h1 style="box-sizing: border-box; font-size: 32px; margin-right: 0px; margin-bottom: 16px; margin-left: 0px; line-height: 1.5; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255); margin-top: 0px !important;" class="">Remove <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: inherit; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">NonObjectiveCBase</code> and <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: inherit; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code></h1><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">Proposal: <a href="https://github.com/aschwaighofer/swift-evolution/blob/remove_nonobjectivecbase/proposals/0000-remove-nonobjectivecbase.md" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none;" class="">SE-0000</a></li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Author: <a href="https://github.com/aschwaighofer" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none;" class="">Arnold Schwaighofer</a></li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Status: <span style="box-sizing: border-box; font-weight: 600;" class="">Pitch</span></li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Review manager: TBD</li></ul><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.5; font-size: 24px; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-introduction" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/tree/remove_nonobjectivecbase#introduction" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Introduction</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Remove <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">NonObjectiveCBase</code> and <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced<T: NonObjectiveCBase>(_ object: T)</code>. <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> can be replaced by <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferencedNonObjC<T: AnyObject>(_ object: T)</code>. This replacement is as performant as the call to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> in cases where the compiler has static knowledge that the type of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">object</code> is a native Swift class. This change will remove surface API.</p><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">Swift-evolution thread: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160711/024515.html" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none;" class="">Pitch</a></li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Swift bug: <a href="http://bugs.swift.org/browse/SR-1962" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none;" class="">SR-1962</a></li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Branch with change to stdlib: <a href="https://github.com/aschwaighofer/swift/tree/remove_nonobjectivecbase" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none;" class="">remove_nonobjectivecbase</a></li></ul><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.5; font-size: 24px; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-motivation" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/tree/remove_nonobjectivecbase#motivation" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Motivation</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Today we have <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> which only works on subclasses of NonObjectiveCBase, and we have <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferencedNonObjC</code> which also works on <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@objc</code> classes.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> SwiftKlazz <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">NonObjectiveCBase</span> {}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> ObjcKlazz <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> NSObject {}
expectTrue(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">isUniquelyReferenced</span>(SwiftKlazz()))
expectFalse(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">isUniquelyReferencedNonObjC</span>(ObjcKlazz()))
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Would not compile:</span>
expectFalse(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">isUniquelyReferenced</span>(ObjcKlazz()))</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">In most cases we expect developers to be using the ManagedBufferPointer type. In cases where they want to use a custom class they would use <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> today and can use <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferencedNonObjC</code> in the future.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> SwiftKlazz {}
expectTrue(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">isUniquelyReferencedNonObjC</span>(SwiftKlazz()))</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Removing <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced<T : NonObjectiveCBase></code> will allow us to remove the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">NonObjectiveCBase</code> class from the standard library thereby further shrinking API surface.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.5; font-size: 24px; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-proposed-solution" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/tree/remove_nonobjectivecbase#proposed-solution" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Proposed solution</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Remove <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced<T : NonObjectiveCBase></code> and remove the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">NonObjectiveCBase</code> class from the standard library. Clients of the the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> API can be migrated to use <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferencedNonObjC</code>. In most cases -- where the type of the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">object</code> parameter is statically known to be a native non-<code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@objc</code> class -- the resulting code will have identical performance characteristics. In cases where the type is statically not known it will have the slight overhead of first checking that the dynamic type is not an <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@objc</code> class.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.5; font-size: 24px; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-detailed-design" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/tree/remove_nonobjectivecbase#detailed-design" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Detailed design</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Todays APIs that can be used to check uniqueness is the family of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> functions.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// Returns `true` iff `object` is a non-`@objc` class instance with</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// a single strong reference.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// * Does *not* modify `object`; the use of `inout` is an</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// implementation artifact.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// * If `object` is an Objective-C class instance, returns `false`.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// * Weak references do not affect the result of this function.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// Useful for implementing the copy-on-write optimization for the</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// deep storage of value types:</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// mutating func modifyMe(_ arg: X) {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// if isUniquelyReferencedNonObjC(&myStorage) {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// myStorage.modifyInPlace(arg)</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// else {</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// myStorage = self.createModified(myStorage, arg)</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// }</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// }</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">isUniquelyReferencedNonObjC</span><T <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">AnyObject</span>>(<span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">_</span> <span class="pl-smi" style="box-sizing: border-box;">object</span>: <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">inout</span> <span class="pl-smi" style="box-sizing: border-box;">T</span>) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Bool</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">isUniquelyReferencedNonObjC</span><T <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">AnyObject</span>>(<span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">_</span> <span class="pl-smi" style="box-sizing: border-box;">object</span>: <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">inout</span> <span class="pl-smi" style="box-sizing: border-box;">T</span>?) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Bool</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// A common base class for classes that need to be non-`@objc`,</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// recognizably in the type system.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">NonObjectiveCBase</span> {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">init</span>() {}
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">isUniquelyReferenced</span><T <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">NonObjectiveCBase</span>>(
<span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">_</span> <span class="pl-smi" style="box-sizing: border-box;">object</span>: <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">inout</span> <span class="pl-smi" style="box-sizing: border-box;">T</span>
) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Bool</span></pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">And the somewhat higher level APIs that can be used to model a storage with several elements <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">ManagedBufferPointer</code>.</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// Contains a buffer object, and provides access to an instance of</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `Header` and contiguous storage for an arbitrary number of</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `Element` instances stored in that buffer.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// For most purposes, the `ManagedBuffer` class works fine for this</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// purpose, and can simply be used on its own. However, in cases</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// where objects of various different classes must serve as storage,</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `ManagedBufferPointer` is needed.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// A valid buffer class is non-`@objc`, with no declared stored</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// properties. Its `deinit` must destroy its</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// stored `Header` and any constructed `Element`s.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `Header` and contiguous storage for an arbitrary number of</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `Element` instances stored in that buffer.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">struct</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedBufferPointer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Equatable</span> {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// Create with new storage containing an initial `Header` and space</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// for at least `minimumCapacity` `element`s.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// - parameter bufferClass: The class of the object used for storage.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// - parameter minimumCapacity: The minimum number of `Element`s that</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// must be able to be stored in the new buffer.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// - parameter initialHeader: A function that produces the initial</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `Header` instance stored in the buffer, given the `buffer`</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// object and a function that can be called on it to get the actual</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// number of allocated elements.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// - Precondition: `minimumCapacity >= 0`, and the type indicated by</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `bufferClass` is a non-`@objc` class with no declared stored</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// properties. The `deinit` of `bufferClass` must destroy its</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// stored `Header` and any constructed `Element`s.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">init</span>(
bufferClass: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">AnyClass</span>,
minimumCapacity: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span>,
initialHeader: <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">@noescape</span> (buffer: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">AnyObject</span>, capacity: <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">@noescape</span> (<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">AnyObject</span>) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span>) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">throws</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> Header
) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">rethrows</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// Returns `true` iff `self` holds the only strong reference to its buffer.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// See `isUniquelyReferenced` for details.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">mutating</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">holdsUniqueReference</span>() <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Bool</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// Returns `true` iff either `self` holds the only strong reference</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// to its buffer or the pinned has been 'pinned'.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">///</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// See `isUniquelyReferenced` for details.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">mutating</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">holdsUniqueOrPinnedReference</span>() <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Bool</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">internal</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> _nativeBuffer: Builtin<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>NativeObject
}
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// A class whose instances contain a property of type `Header` and raw</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// storage for an array of `Element`, whose size is determined at</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// instance creation.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedBuffer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedProtoBuffer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// Create a new instance of the most-derived class, calling</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// `initialHeader` on the partially-constructed object to</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">/// generate an initial `Header`.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">public</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">final</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">create</span>(
minimumCapacity: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span>,
initialHeader: <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">@noescape</span> (<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedProtoBuffer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>) throws <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> Header
) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">rethrows</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedBuffer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> {
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> p <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">try</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedBufferPointer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>(
bufferClass: <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">self</span>,
minimumCapacity: minimumCapacity,
initialHeader: { buffer, _ <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">in</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">try</span> initialHeader(
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">unsafeDowncast</span>(buffer, to: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedProtoBuffer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">>.</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">self</span>))
})
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">return</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">unsafeDowncast</span>(p<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">buffer</span>, to: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">ManagedBuffer</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Header, Element<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">>.</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">self</span>)
}
}
</pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">We propose to remove the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">NonObjectiveCBase</code> class and <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced<T: NonObjectiveCBase>(_ object: T></code>.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.5; font-size: 24px; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-impact-on-existing-code" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/tree/remove_nonobjectivecbase#impact-on-existing-code" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Impact on existing code</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Existing code that uses <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> will need to remove the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">NonObjectiveCBase</code> base class and replace calls to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> by <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferencedNonObjC</code>. The old API will be marked unavailable to help migration.</p><h2 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.5; font-size: 24px; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-alternatives-considered" class="anchor" href="https://github.com/aschwaighofer/swift-evolution/tree/remove_nonobjectivecbase#alternatives-considered" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Alternatives considered</h2><div style="box-sizing: border-box; margin-top: 0px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255); margin-bottom: 0px !important;" class="">Leave the status quo and pay for type safety with additional API surface. Another alternative we considered -- the first version of this proposal -- was to replace the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferenced</code> API by an <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferencedUnsafe<T: AnyObject>(_ object: T)</code> API that would assume the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">object</code> to be a non-@objc class and only check this precondition under -Onone. There is however no good reason to keep this API given that the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">isUniquelyReferencedNonObjC</code> is as performant when the type is statically known to be non-<code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">@objc</code> class.</div><blockquote type="cite" class="">On Jul 16, 2016, at 10:12 PM, Arnold via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class="">Sent from my iPhone<br class=""><br class="">On Jul 16, 2016, at 9:41 PM, Arnold <<a href="mailto:aschwaighofer@apple.com" class="">aschwaighofer@apple.com</a>> wrote:<br class=""><br class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class=""><br class="">Sent from my iPhone<br class=""><br class="">On Jul 16, 2016, at 9:23 PM, Andrew Trick <atrick@apple.com> wrote:<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">On Jul 16, 2016, at 9:17 PM, Arnold <aschwaighofer@apple.com> wrote:<br class=""><br class=""><br class=""><br class="">On Jul 16, 2016, at 8:45 PM, Andrew Trick <atrick@apple.com> wrote:<br class=""><br class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""><blockquote type="cite" class="">On Jul 16, 2016, at 8:36 PM, Arnold <aschwaighofer@apple.com> wrote:<br class=""><br class="">Thank you for the feedback. Answers online.<br class=""><br class="">Sent from my iPhone<br class=""><br class="">On Jul 16, 2016, at 7:38 PM, Andrew Trick <atrick@apple.com> wrote:<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">On Jul 16, 2016, at 6:46 PM, Arnold Schwaighofer via swift-evolution <swift-evolution@swift.org> wrote:<br class=""><br class="">Replace isUniquelyReferenced<T : NonObjectiveCBase> by isUniquelyReferencedUnsafe<T: AnyObject> and remove the NonObjectiveCBase class from the standard library.<br class=""><br class=""><br class=""></blockquote><br class="">So we’ll have:<br class=""><br class="">- isUniquelyReferencedNonObjC(object): true iff object is uniquely referenced and NonObjC<br class=""><br class="">- isUniquelyReferencedUnsafe(object): true iff object is uniquely reference, assert NonObjC<br class=""><br class="">I’m going to be picky. The “Unsafe” suffix doesn’t make sense to me. If you think this is an unsafe API then it should be:<br class="">“unsafeIsUniquelyReferenced”.<br class=""><br class="">But I don’t really see how it is unsafe in the usual sense. If you want to convey that the programmer needs to satisfy some precondition, which is not generally associated with unsafety, then it should be:<br class="">“isUniquelyReferencedAssumingNonObjC”<br class=""><br class=""></blockquote><br class="">Makes sense to me. I think it is unsafe in the sense if you don't satisfy the precondition the resulting behavior is undefined in modes other than -Onone and not checked by a precondition predicate that traps.<br class=""><br class=""><blockquote type="cite" class="">unsafeIsUniquelyReferenced<br class=""></blockquote><br class="">I find it kind of nice to recognize a predicate by the 'is' prefix. All unsafe APIs start with the word unsafe though. I could not find an unsafe freestanding predicate.<br class=""><br class="">[As the implementor of the underlying builtin you may remember that it is not actually undefined and will return a implementation defined value (false) for objc classes. But we might not want to guarantee this going forward.]<br class=""></blockquote><br class="">Oh yeah. I think I only kept the two versions for fear of breaking the API. Since you’re renaming the second one anyway, why not just delete it with a fixit that it's renamed to isUniquelyReferencedNonObjC?<br class=""><br class="">The “assuming” version of the API is extremely confusing in addition to being useless.<br class=""></blockquote><br class="">The unsafe version would allow us to emit more efficient code (in the future) for a static unknown object type but we know it is a native type (but not which so we can't just cast it, this is public API so we can't cast to Builtin.NativeObject).<br class=""><br class=""> var self: AnyObject // really: AnyNativeObject<br class=""> ...<br class=""> if (!unsafeIsUniquelyReferenced(&self))<br class=""> self = self.copy()<br class=""> }<br class=""><br class="">I admit this is somewhat contrived and am happy to just nuke the API if we agree there is no value in the use case above.<br class=""></blockquote><br class="">There is no sense advertising this API under some new name if it hasn’t even been implemented. The API can be added when it makes sense.<br class=""><br class="">+1 for eliminating it.<br class=""></blockquote><br class="">Today you can implement something similar using NonObjectiveCBase as your base class:<br class=""><br class=""> var self: NonObjectiveCBase<br class=""> ...<br class=""> if (isUniquelyReferenced(&self) {...}<br class=""><br class="">And get the runtime performance of the native check.<br class=""></blockquote><br class="">Actually, this code could just implement their own 'class NonObjCBase' base class and just use isUniquelyReferencedNonObj for the same performance as before ...<br class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="">If we implemented 'unsafeIsUniquelyReferenced' we would just unsafeBitCast the 'object' argument to Builtin.NativeObject and get the same performance.<br class=""><br class="">I admit that this may be far fetched but I am trying to anticipated possible use cases that work today.<br class=""><br class="">That use case will still work after nuking the API using the 'NonObjC' variant albeit slightly slower.<br class=""><br class="">If we need to support it with best performance we can always bring the API back as you said.<br class=""><br class="">+1 for nuking it from me<br class=""><br class="">I will change the proposal.<br class=""></blockquote>_______________________________________________<br class="">swift-evolution mailing list<br class="">swift-evolution@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></blockquote><br class=""></div></body></html>