Kamil Harasimowicz
Kamil Harasimowicz

Reputation: 4994

Binary operator '<<' cannot be applied to two 'T' operands

I want to create a generic function which can create bit mask for future usage. Here is my code:

import Foundation

class BitParserUtils {

    static let hexPositionOffset: Int = 4

    static func doubleHexMask<T: UnsignedInteger>(offset: Int) -> T {
        var mask: T = 0xFF
        mask = mask << ((offset * hexPositionOffset) as! T)

        return mask
    }
}

But I got a debug error:

Binary operator '<<' cannot be applied to two 'T' operands

I don't understand why and how to fix that. Anybody can explain me what I am doing wrong and how to fix that?

Example of usage

let maskU64: UInt64 = BitParserUtils.doubleHexMask(offset: 4)
let maskU32: UInt32 = BitParserUtils.doubleHexMask(offset: 1)
let maskU16: UInt16 = BitParserUtils.doubleHexMask(offset: 0)

Upvotes: 1

Views: 346

Answers (2)

Martin R
Martin R

Reputation: 539765

As Tomasz Wójcik already said, the left shift operator is in Swift 3 only defined for concrete integer types, but not for the UnsignedInteger protocol.

A possible workaround is to replace the left shift by a repeated multiplication:

func doubleHexMask<T: UnsignedInteger>(offset: Int) -> T {
    var mask: T = 0xFF
    for _ in 0..<offset {
        mask = mask &* 16
    }
    return mask
}

This also makes the forced cast as! T unnecessary. The "overflow operator &*" is used here so that bits moved beyond the bounds of the integer’s storage are discarded, corresponding to what the left shift operator does.

Upvotes: 2

Tomasz W&#243;jcik
Tomasz W&#243;jcik

Reputation: 962

Use FixedWidthInteger instead of UnsignedInteger.

There is no UnsignedInteger overload for << operator:

http://swiftdoc.org/v3.1/operator/ltlt/

Note: this requires Xcode 9 (Swift 3.2/4.0)

Upvotes: 2

Related Questions