Re: [swift-users] How to dispatch on the size of Int?
I agree, there should be a platform condition that just indicates native word size, such as arch(32bit) and arch(64bit). > On Nov 23, 2016, at 2:18 PM, Martin Rwrote: > > 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 : >> >> 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 >>> 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.size == 4 { >>> foo_impl(value: Int32(value)) >>> } else { >>> foo_impl(value: Int64(value)) >>> } >>> } >>> >>> or >>> >>> func foo2(value: Int) { >>> switch MemoryLayout.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
Re: [swift-users] How to dispatch on the size of Int?
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: > > 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 >> 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.size == 4 { >>foo_impl(value: Int32(value)) >>} else { >>foo_impl(value: Int64(value)) >>} >>} >> >> or >> >>func foo2(value: Int) { >>switch MemoryLayout.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
[swift-users] How to dispatch on the size of Int?
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.size == 4 { foo_impl(value: Int32(value)) } else { foo_impl(value: Int64(value)) } } or func foo2(value: Int) { switch MemoryLayout.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