Yes, I had forgotten about that, thank you! That would satisfy all criteria. And with
func foo(value: Int) { #if arch(i386) || arch(arm) foo_impl(value: Int32(value)) #elseif arch(x86_64) || arch(arm64) foo_impl(value: Int64(value)) #endif } it should be „future-safe“, i.e. fail to compile on a new platform. (I would still prefer a solution which does not require me to know about all possible processor architectures.) > Am 23.11.2016 um 23:06 schrieb Hooman Mehr <hoo...@mac.com>: > > 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