[swift-evolution] [Pre-proposal] Standard Protocol for Bitwise Shifts and Binary-based Integers

Jacob Bandes-Storch jtbandes at gmail.com
Mon Jan 18 12:11:22 CST 2016


I saw it mentioned somewhere that the standard library team wants to allow
smaller types to be used, like <<(lhs: UInt64, rhs: UInt8). I'm not sure
exactly how that would fit in here.

On Mon, Jan 18, 2016 at 4:45 AM, Haravikk via swift-evolution <
swift-evolution at swift.org> wrote:

> 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:
>
> protocol BitwiseIntegerType : BitwiseOperationsType, IntegerType {
>     init(_ value:Int)
>     init(_ value:UInt)
>
>     func << (lhs:Self, rhs:Self) -> Self
>     func >> (lhs:Self, rhs:Self) -> Self
>     func <<= (inout lhs:Self, rhs:Self)
>     func >>= (inout lhs:Self, rhs:Self)
> }
>
> extension BitwiseIntegerType {
>     static var allOnes:Self { return ~Self.allZeros }
>     static var numberOfBits:UInt { return UInt(sizeof(Self) * 8) }
>
>     static var mostSignificantBit:Self { return Self.allOnes << Self(Self.numberOfBits
> - 1) }
>
>     var leadingZeros:UInt {
>         if self == Self.allZeros { return Self.numberOfBits }
>
>         var value = self
>         var width = Self.numberOfBits
>         var mask = Self.allOnes
>         var zeros:UInt = 0
>
>         while (value & Self.mostSignificantBit) == Self.allZeros {
>             if (value & mask) == Self.allZeros {
>                 zeros += width
>                 value <<= Self(width)
>             } else {
>                 width /= 2
>                 mask <<= Self(width)
>             }
>         }
>
>         return zeros
>     }
> }
>
> extension Int : BitwiseIntegerType {}
> extension Int8 : BitwiseIntegerType {}
> extension Int16 : BitwiseIntegerType {}
> extension Int32 : BitwiseIntegerType {}
> extension Int64 : BitwiseIntegerType {}
>
> extension UInt : BitwiseIntegerType {}
> extension UInt8 : BitwiseIntegerType {}
> extension UInt16 : BitwiseIntegerType {}
> extension UInt32 : BitwiseIntegerType {}
> extension UInt64 : BitwiseIntegerType {}
>
> Int64.mostSignificantBit    // -9223372036854775808
> 1234567.leadingZeros        // 43
>
> 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).
>
> 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.
>
> 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.
>
> 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).
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160118/064b0146/attachment.html>


More information about the swift-evolution mailing list