func foo_impl(value: Int32) { /* ... */ }
func foo_impl(value: Int64) { /* ... */ }

func foo(value: Int) {
    #if arch(i386) || arch(arm)
        foo_impl(value: Int32(value))
    #else
        foo_impl(value: Int64(value))
    #endif
}


> On Nov 23, 2016, at 1:31 PM, Martin R via swift-users <swift-users@swift.org> 
> wrote:
> 
> I wonder what the best way would be to call a specialized function dependent 
> on the size of `Int`. Let's say that I have two implementations
> 
>    func foo_impl(value: Int32) { /* ... */ }
>    func foo_impl(value: Int64) { /* ... */ }
> 
> and I want 
> 
>    func foo(value: Int)
> 
> to call the "right one" of them, according to the architecture (32-bit or 
> 64-bit).
> 
>    func foo(value: Int) { foo_impl(value: value) }
> 
> does not compile. (I assume that is because `Int` is not a type alias to 
> `Int32` or `Int64` but an independent type.)
> 
> This works: 
> 
>    func foo1(value: Int) {
>        if MemoryLayout<Int>.size == 4 {
>            foo_impl(value: Int32(value))
>        } else {
>            foo_impl(value: Int64(value))
>        }
>    }
> 
> or
> 
>    func foo2(value: Int) {
>        switch MemoryLayout<Int>.size {
>        case 4: foo_impl(value: Int32(value))
>        case 8: foo_impl(value: Int64(value))
>        default:
>            abort()
>        }
>    }
> 
> But a typo in the constants would go unnoticed and just call the wrong 
> function, or cause a runtime error instead of a compile-time error. And 
> perhaps `Int` can be an 128-bit integer in the future? The compiler would not 
> warn that the code needs to be updated.
> 
> This seems to be more promising:
> 
>    func foo3(value: Int) {
>        switch (__WORDSIZE) {
>        case 32: foo_impl(value: Int32(value)) // Warning: Will never be 
> executed
>        case 64: foo_impl(value: Int64(value))
>        }
>    }
> 
> Apparently the compiler "knows" which case will be executed, `foo3` does not 
> compile if there is no case matching actual integer size. But there is always 
> an annoying warning for the unused case. And I am not sure if it is 
> guaranteed that __WORDSIZE is the number of bits in an `Int`.
> 
> So my question is: What would be the best way to dispatch dependent on the 
> size of `Int`, such that
> 
> - The compiler checks the correctness.
> - The compiler optimizes the code so that no runtime check is done.
> - No warnings are produced.
> 
> If `Int` had a `native` property like `CGFloat` then I could simply call
> 
>    func foo(value: Int) { foo_impl(value: value.native) }
> 
> but I could not find such a property. (Would that be a reasonable thing to 
> ask on swift-evolution?)
> 
> Background: I am asking this just out of curiosity, but the question came up 
> when looking at the `hash_combine` function in the Boost library:
> 
>  http://www.boost.org/doc/libs/1_62_0/boost/functional/hash/hash.hpp 
> 
> with quite different implementations 
> 
>    inline void hash_combine_impl(boost::uint32_t& h1, boost::uint32_t k1)
>    inline void hash_combine_impl(boost::uint64_t& h, boost::uint64_t k)
> 
> and I wondered how this would be done in Swift.
> 
> Regards, 
> Martin
> 
> 
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to