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