Approaches for fixed-size arrays

Reminded me of an ugly way of parametrising generics with numbers.

You can't do this directly in current swift (pseudocode):

struct S<n: Int, T> { ... }

But if you need it badly...

protocol Bit {
    static var val: Int { get }
}
struct O: Bit {
    static var val: Int { 0 }
}
struct I: Bit {
    static var val: Int { 1 }
}

struct Size<BF:Bit, BE:Bit, BD:Bit, BC:Bit, BB:Bit, BA:Bit, B9:Bit, B8:Bit, B7:Bit, B6:Bit, B5:Bit, B4:Bit, B3:Bit, B2:Bit, B1:Bit, B0:Bit> {
    static var val: Int {
        // too complex expression for the compiler, let's split it into several.
        let w1 = B0.val <<  0 + B1.val <<  1 + B2.val <<  2 + B3.val <<  3
        let w2 = B4.val <<  4 + B5.val <<  5 + B6.val <<  6 + B7.val <<  7
        let w3 = B8.val <<  8 + B9.val <<  9 + BA.val << 10 + BB.val << 11
        let w4 = BC.val << 12 + BD.val << 13 + BE.val << 14 + BF.val << 15
        return w1 + w2 + w3 + w4
    }
    var val: Int { Self.val }
}

Usage example:

let type = Size<O,O,O,I,  O,O,I,O,  O,O,I,I,  O,I,O,O>()
print(String(format: "0x%0X", type.val)) // 0x1234

Extending this to 64 bit numbers is left as an exercise to the reader :rofl:

6 Likes