<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hmm. Well, Int is fairly common, and encompasses more than we’re ever likely to need for shifts, so it may make sense to use Self &lt;&lt; Int as the baseline for the shifts. As for supporting smaller types, I’m not sure how it could be done in the protocol as a specific requirement unless it was something like:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> BitwiseIntegerType : </span>BitwiseOperationsType<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">, </span>IntegerType<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;" class="">&nbsp; &nbsp; <font color="#bb2ca2" class="">...</font></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> &lt;&lt; (lhs:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Self</span>, rhs:<span style="color: rgb(112, 61, 170);" class="">SignedIntegerType</span>) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Self</span></div><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">func</span><span style="font-family: Menlo; font-size: 11px;" class="">&nbsp;&lt;&lt; </span><span style="font-family: Menlo; font-size: 11px;" class="">(lhs:</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Self</span><span style="font-family: Menlo; font-size: 11px;" class="">, rhs:</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">UnsignedIntegerType</span><span style="font-family: Menlo; font-size: 11px;" class="">) -&gt;&nbsp;</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Self</span></div><div class=""><div style="margin: 0px; font-size: 11px; font-family: Menlo;" class="">}</div></div><div class=""><br class=""></div><div class="">Since those types can be easily converted to the maximum supported size and then processed accordingly, but that seems much the same as requiring a right-hand-side of Self to me, except that it requires two variations per operator.</div><div class=""><br class=""></div><div class="">I posted another discussion around simplifying casting of integers, specifically allowing implicit casts of any integer type so long as the type you’re casting to has a larger range; in other words, anywhere you can put an Int32 you could put an Int16, Int8, UInt16 or UInt8, but not a UInt32 or anything larger, as these could potentially lose information so should have a warning as normal (forcing the developer to do something explicitly).</div><div class=""><br class=""></div><div class="">Handling of integers is definitely tricky!</div><br class=""><div><blockquote type="cite" class=""><div class="">On 18 Jan 2016, at 18:11, Jacob Bandes-Storch &lt;<a href="mailto:jtbandes@gmail.com" class="">jtbandes@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I saw it mentioned somewhere that the standard library team wants to allow smaller types to be used, like &lt;&lt;(lhs: UInt64, rhs: UInt8). I'm not sure exactly how that would fit in here.<div class="gmail_extra">
<br class=""><div class="gmail_quote">On Mon, Jan 18, 2016 at 4:45 AM, Haravikk via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">So I recently discovered that the shift operators no longer appear to be defined anywhere, i.e- they seem to only be implemented by convention rather than being required by a protocol, which doesn’t seem ideal. The problem with this is that I wanted to implement some bitwise operations but there’s no longer an obvious place to do this, and I ended up having to implement my own concept of a BitwiseIntegerType, as you can see in the example below:<br class=""><div class=""><br class=""></div><div class=""><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(112,61,170)" class=""><span style="color:#bb2ca2" class="">protocol</span><span style="" class=""> BitwiseIntegerType : </span>BitwiseOperationsType<span style="" class="">, </span>IntegerType<span style="" class=""> {</span></div><span style="font-family:Menlo;font-size:11px" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)" class="">init</span><span style="font-family:Menlo;font-size:11px" class="">(</span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)" class="">_</span><span style="font-family:Menlo;font-size:11px" class="">&nbsp;value:</span><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)" class="">Int</span><span style="font-family:Menlo;font-size:11px" class="">)</span><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">init</span>(<span style="color:#bb2ca2" class="">_</span> value:<span style="color:#703daa" class="">UInt</span>)</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">func</span> &lt;&lt; (lhs:<span style="color:#703daa" class="">Self</span>, rhs:<span style="color:#703daa" class="">Self</span>) -&gt; <span style="color:#703daa" class="">Self</span></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">func</span> &gt;&gt; (lhs:<span style="color:#703daa" class="">Self</span>, rhs:<span style="color:#703daa" class="">Self</span>) -&gt; <span style="color:#703daa" class="">Self</span></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">func</span> &lt;&lt;= (<span style="color:#bb2ca2" class="">inout</span> lhs:<span style="color:#703daa" class="">Self</span>, rhs:<span style="color:#703daa" class="">Self</span>)</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">func</span> &gt;&gt;= (<span style="color:#bb2ca2" class="">inout</span> lhs:<span style="color:#703daa" class="">Self</span>, rhs:<span style="color:#703daa" class="">Self</span>)</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">}</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span>BitwiseIntegerType<span style="" class=""> {</span></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">static</span> <span style="color:#bb2ca2" class="">var</span> allOnes:<span style="color:#703daa" class="">Self</span> { <span style="color:#bb2ca2" class="">return</span> <span style="color:#3d1d81" class="">~</span><span style="color:#bb2ca2" class="">Self</span>.allZeros }</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">static</span> <span style="color:#bb2ca2" class="">var</span> numberOfBits:<span style="color:#703daa" class="">UInt</span> { <span style="color:#bb2ca2" class="">return</span> <span style="color:#703daa" class="">UInt</span>(<span style="color:#3d1d81" class="">sizeof</span>(<span style="color:#bb2ca2" class="">Self</span>) * <span style="color:#272ad8" class="">8</span>) }</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">static</span> <span style="color:#bb2ca2" class="">var</span> mostSignificantBit:<span style="color:#703daa" class="">Self</span> { <span style="color:#bb2ca2" class="">return</span> <span style="color:#bb2ca2" class="">Self</span>.allOnes <span style="color:#31595d" class="">&lt;&lt;</span> <span style="color:#bb2ca2" class="">Self</span>(<span style="color:#bb2ca2" class="">Self</span>.numberOfBits - <span style="color:#272ad8" class="">1</span>) }</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; <span style="color:#bb2ca2" class="">var</span> leadingZeros:<span style="color:#703daa" class="">UInt</span> {</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">if</span> <span style="color:#bb2ca2" class="">self</span> <span style="color:#3d1d81" class="">==</span> <span style="color:#bb2ca2" class="">Self</span>.allZeros { <span style="color:#bb2ca2" class="">return</span> <span style="color:#bb2ca2" class="">Self</span>.numberOfBits }</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">var</span> value = <span style="color:#bb2ca2" class="">self</span></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">var</span> width = <span style="color:#bb2ca2" class="">Self</span>.numberOfBits</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">var</span> mask = <span style="color:#bb2ca2" class="">Self</span>.allOnes</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">var</span> zeros:<span style="color:#703daa" class="">UInt</span> = <span style="color:#272ad8" class="">0</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">while</span> (value <span style="color:#3d1d81" class="">&amp;</span> <span style="color:#bb2ca2" class="">Self</span>.mostSignificantBit) <span style="color:#3d1d81" class="">==</span> <span style="color:#bb2ca2" class="">Self</span>.allZeros {</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">if</span> (value <span style="color:#3d1d81" class="">&amp;</span> mask) <span style="color:#3d1d81" class="">==</span> <span style="color:#bb2ca2" class="">Self</span>.allZeros {</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; zeros += width</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value <span style="color:#31595d" class="">&lt;&lt;=</span> <span style="color:#bb2ca2" class="">Self</span>(width)</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <span style="color:#bb2ca2" class="">else</span> {</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width /= <span style="color:#272ad8" class="">2</span></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mask <span style="color:#31595d" class="">&lt;&lt;=</span> <span style="color:#bb2ca2" class="">Self</span>(width)</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#bb2ca2" class="">return</span> zeros</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">&nbsp; &nbsp; }</div><div style="margin:0px;font-size:11px;font-family:Menlo" class="">}</div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">Int</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">Int8</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">Int16</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">Int32</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">Int64</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">UInt</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">UInt8</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">UInt16</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">UInt32</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#bb2ca2" class="">extension</span><span style="" class=""> </span><span style="color:#703daa" class="">UInt64</span><span style="" class=""> : </span>BitwiseIntegerType<span style="" class=""> {}</span></div><div style="margin:0px;font-size:11px;font-family:Menlo;min-height:13px" class=""><br class=""></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(0,132,0)" class=""><span style="color:#703daa" class="">Int64</span><span style="" class="">.mostSignificantBit&nbsp; &nbsp; </span>// -9223372036854775808</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#272ad8" class="">1234567</span><span style="" class="">.</span>leadingZeros<span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:#008400" class="">// 43</span></div></div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(79,129,135)" class=""><span style="color:#008400" class=""><br class=""></span></div>I think that the best solution would be to add the shift operators to BitwiseOperationsType, while declaring a BitwiseIntegerType similar to what I’ve done above that groups BitwiseOperationsType with IntegerType to create a distinction between binary-based integers and integers that could be based on some other mechanism in future, as well as to declare the required initializers from Int and UInt types. This gives more flexibility in defining higher level protocol extensions that rely on the full range of bitwise operations, without having to move any of it further up (iirc some of these operators used to be in IntegerType).<div class=""><br class=""></div><div class="">Either way, the shift operators are currently declared by convention, which I don’t think is right, as they should surely be declared as a requirement somewhere.</div><div class=""><br class=""></div><div class="">Also, ignore the actual implementation of leadingZeros, it may not be the most efficient method, it’s just a useful illustration of something that can be done with the protocol declarations, I’ve also omitted warnings and such to keep things simple.</div><div class=""><br class=""></div><div class="">Just wondering what others think? One other issue I’m unsure about is that the required Int and Uint initialiizers should probably be of the truncatingBitPattern type for bitwise operations, but I wasn’t sure how to handle adding that to the types that don’t currently have these initializers (i.e- the 64-bit types that don’t need them since they can’t currently be initialized from anything bigger).</div></div><br class="">_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>