Creating an UnsafeMutablePointer<UnsafeMutablePointer<Float>> parameter in Swift 3 - swift

The Swift signature of the Accelerate framework vDSP_biquadm() function includes parameter types of UnsafeMutablePointer<UnsafePointer<Float>> and UnsafeMutablePointer<UnsafeMutablePointer<Float>>.
How does one declare and create such types in Swift 3, and then fill these pointer arrays with references to several Swift arrays of type [Float].

When you need to pass multiple values for UnsafeMutablePointer<T> parameters, you need to declare a variable of type [T] (aka Array<T>) and pass it as an inout argument. In your case T is UnsafeMutablePointer<Float>.
So, if you want to start with [Float], you may need to write something like this:
let input: [Float] = [/*...*/]
var output: [Float] = Array(repeating: 0, count: outputTotalSize)
input.withUnsafeBufferPointer {inBuf in
let inputPtr = inBuf.baseAddress!
output.withUnsafeMutableBufferPointer {outBuf in
let outputPtr = outBuf.baseAddress!
var pInputs: [UnsafePointer<Float>] = [inputPtr,/*...*/]
var pOutputs: [UnsafeMutablePointer<Float>] = [outputPtr/*...*/]
vDSP_biquadm(setup, &pInputs, inStride, &pOutputs, outStride, length)
}
}

Related

Swift: inout with generic functions and constraints

I am making my first steps in Swift and got along the first problem. I am trying to pass an array by reference using inout on an generic function with constraints.
First, my application start point:
import Foundation
let sort = Sort()
sort.sort(["A", "B", "C", "D"])
And here my class with the actual problem:
import Foundation
class Sort {
func sort<T:Comparable>(items:[T]){
let startIndex = 0
let minIndex = 1
exchange(&items, firstIndex: startIndex, secondIndex: minIndex)
}
func exchange<T:Comparable>(inout array:[T], firstIndex:Int, secondIndex:Int) {
// do something with the array
}
}
I am getting the following error in Xcode on the line calling exchange:
Cannot convert value of type '[T]' to expected argument type '[_]'
Am I missing here something?
Update: Added complete project code.
It works with following modifications:
the array passed into it must be a var. As mentioned in the documentation, inouts must not be let or literals.
You cannot pass a constant or a literal value as the argument, because constants and literals cannot be modified.
items in declaration must also be inout to indicate that it must be var again
import Foundation
class Sort {
func sort<T:Comparable>(inout items:[T]){
let startIndex = 0
let minIndex = 1
exchange(&items, firstIndex: startIndex, secondIndex: minIndex)
}
func exchange<T:Comparable>(inout array:[T], firstIndex:Int, secondIndex:Int) {
// do something with the array
}
}
let sort = Sort()
var array = ["A", "B", "C", "D"]
sort.sort(&array)
You can "exchange" two values in an array by using the swift swap function.
e.g.
var a = [1, 2, 3, 4, 5]
swap(&a[0], &a[1])
would mean that a now is [2, 1, 3, 4, 5]

Swift: cannot convert value of type 'Self' to expected argument type 'UnsafePointer<Void>'

I do a bunch of work with [Uint8] arrays. But I often have to recast these as NSData objects to interface with iOS frameworks such as CoreBluetooth. So I have lots of code that might look something like:
var input:[UInt8] = [0x60, 0x0D, 0xF0, 0x0D]
let data = NSData(bytes: input, length: input.count)
Being tired of having to insert this extra let data = ... line, I thought I would just extend those arrays with a computed property to do the work. Then I could just do things like:
aBluetoothPeriperal.write(myBytes.nsdata, ...)
So it's basically just extension sugar. I can't extend Array, but I can extend a protocol:
extension SequenceType where Generator.Element == UInt8 {
var nsdata:NSData {
return NSData(bytes: self, length: self.count)
}
}
Which produces an error that looks like:
Playground execution failed: MyPlayground.playground:3:24: error: cannot convert value of type 'Self' to expected argument type 'UnsafePointer<Void>' (aka 'UnsafePointer<()>')
return NSData(bytes: self, length: self.count)
^~~~
Sadly, the more I use Swift--and I really do like some things about Swift--the more I'm reminded of my negative experiences with trying to understand reams of unhelpful compiler output when I tried my hand at C++ with lots of generics and stuff years ago. So please Obi Wan, help me see the light here!
NSData(bytes:, length:) takes an UnsafePointer<Void> as first parameter, and you cannot pass an arbitrary SequenceType here.
You can pass an Array which would be passed as the address of the
first array element. It is however not guaranteed that Array elements
are stored in contiguous memory.
Therefore:
Define an Array extension instead of a Sequence extension.
Use the withUnsafeBufferPointer() method to get a pointer
to contiguous array storage.
Possible solution:
extension Array where Element : IntegerType {
var nsdata : NSData {
return self.withUnsafeBufferPointer {
NSData(bytes: $0.baseAddress, length: self.count * strideof(Element))
}
}
}
let input:[UInt8] = [0x60, 0x0D, 0xF0, 0x0D]
print(input.nsdata) // <600df00d>
Swift does currently not allow to restrict an array extension
to a concrete type:
extension Array where Element == UInt8 { }
// error: same-type requirement makes generic parameter 'Element' non-generic
therefore it is generalized to any elements conforming to IntegerType.
For a sequence you could then do a conversion to an array first:
let data = Array(myUInt8sequence).nsdata
This seems to do what you want.
protocol ByteOnly: IntegerType {}
extension UInt8: ByteOnly {}
extension Array where Element: ByteOnly {
var n : NSData { return NSData(bytes: self, length: self.count) }
}
// does it work with UInt8
var input5:[UInt8] = [0x61, 0x0D, 0xF1, 0x0D]
let data5 = input5.n // YES
// does it work on ints?
var ints: [Int] = [3,4,5,6,7,8]
let idata5 = ints.n // no

Reference to generic type 'Dictionary' requires arguments in <..> [duplicate]

let index1 = arc4random_uniform(10);
let x = array[index1];
The second line is giving following error
could not find an overload for 'subscript' that accepts the supplied arguments
let x = array[index1];
^~~~~~~~~~~~~
you have to convert the index to Int like e.g. this:
let index1: UInt32 = arc4random_uniform(10); // with the type of the value
let x = array[Int(index1)];
the Int is the proper index type rather than UInt32.
UPDATE
if you are not quiet happy to convert the index every individual time, you can also add an extension to Array with defining a new subscript for your generic index type(s), e.g. such extension would look with UInt32 like this:
extension Array {
subscript (index: UInt32) -> T {
get {
let intIndex : Int = Int(index)
return self[intIndex]
}
}
}
NOTE: I have not worked out the setter here.

Swift various ways of creating empty array what are differences between them?

I looked through docs some forums and found I can create an array in various ways. I am confused which one should we be using?
var testArray = [Int]()
testArray.append(1)
var anotherTestArray: [Int] = []
anotherTestArray.append(1)
var yetAnotherTestArray: Array<Int> = []
yetAnotherTestArray.append(1)
var yetYetYetAnotherTestArray = Array<Int>()
yetYetYetAnotherTestArray.append(1)
This is not empty array but It keeps it's type for each element to be strictly to an Int
var yetYetAnotherTestArray = [1]
I think the cleanest way to create an array is var testArray: [Int] = []
In swift array objects must be the same type. If you want to store different objects of different types use [AnyObject]. However, you should always know what is coming out of it. Since the returning type value will be AnyObject, you have to cast down the value to the type you want.
I really don't recommend using AnyObject as the type of your arrays unless you really know what you are doing.
Here is an example anyway:
let a: [AnyObject] = [1, "a"]
let b = a[0] // An Int
let c = a[1] // A String

Swift: Convert Int16 to Int32 (or NSInteger)

I'm really stuck! I'm not an expert at ObjC, and now I am trying to use Swift. I thought it would be much simpler, but it wasn't. I remember Craig said that they call Swift “Objective-C without C”, but there are too many C types in OS X's foundation. Documents said that many ObjC types will automatically convert, possibly bidirectionally, to Swift types. I'm curious: how about C types?
Here's where I'm stuck:
//array1:[String?], event.KeyCode.value:Int16
let s = array1[event.keyCode.value]; //return Int16 is not convertible to Int
I tried some things in ObjC:
let index = (Int) event.keyCode.value; //Error
or
let index = (Int32) event.keyCode.value; //Error again, Swift seems doesn't support this syntax
What is the proper way to convert Int16 to Int?
To convert a number from one type to another, you have to create a new instance, passing the source value as parameter - for example:
let int16: Int16 = 20
let int: Int = Int(int16)
let int32: Int32 = Int32(int16)
I used explicit types for variable declarations, to make the concept clear - but in all the above cases the type can be inferred:
let int16: Int16 = 20
let int = Int(int16)
let int32 = Int32(int16)
This is not how this type of casting works in Swift. Instead, use:
let a : Int16 = 1
let b : Int = Int(a)
So, you basically instantiate one variable on base of the other.
In my case "I was trying to convert core data Int16 to Int" explicit casting didn't worked. I did this way
let quantity_string:String = String(format:"%d",yourInt16value)
let quantity:Int = Int(quantity_string)