Arbitrary C callback wrappers in Swift - c

I have a C library with a lot of callbacks in the form
void asynchronous_thing(..., void* userInfo, SOMECBTYPE cb)
I am writing unit tests for these in Swift/XCT, and am wondering what the best solution to pass vars into the closure that Xcode/Swift generates for me automatically (I am providing one answer but my Swift is sub-par, so chances are high there is a much more elegant way to do this).

This is the solution I have:
class CUserInfoClass<T> {
let v: T
init(_ v: T) {
self.v = v
}
init(_ userInfo: UnsafeMutableRawPointer) {
self.v = CUserInfoCallback<T>(userInfo).v.v
}
}
class CExpectation : CUserInfoClass<XCTestExpectation> {
func fulfill() {
self.v.fulfill()
}
}
class CUserInfoCallback<T> {
let v: CUserInfoClass<T>
init(_ v: CUserInfoClass<T>) {
self.v = v
}
init(_ userInfo: UnsafeMutableRawPointer) {
self.v = Unmanaged<CUserInfoClass<T>>.fromOpaque(userInfo).takeUnretainedValue()
}
func wrap() -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(Unmanaged.passUnretained(self.v).toOpaque())
}
}
I use this in the following manner:
func testAsyncThingie() {
let exp = CUserInfoCallback(CUserInfoClass(expectation(description: "Wait for async thingie")))
DoAsyncThing(exp.wrap()) {
(ui, err) in
XCTAssertNil(err)
CExpectation(ui!).fulfill()
}
waitForExpectations(timeout: 10, handler: nil)
}
where DoAsyncThing is
void DoAsyncThing(void*, void (*)(void* userInfo, const char* error))

Related

swift - Casting an Array vs an ArraySlice using protocols

In this code snippet
protocol MyProtocol {}
extension Int: MyProtocol {}
let a: Array<MyProtocol> = Array<Int>()
let b: ArraySlice<MyProtocol> = a[...]
let c: Array<Int> = a as! Array<Int>
let d: ArraySlice<Int> = b as! ArraySlice<Int>
d warns with Cast from 'ArraySlice<MyProtocol>' to unrelated type 'ArraySlice<Int>' always fails.
Why can't a Slice be cast in the same way as the original Array? Can this snippet be modified to give the Array casting behaviour to the Slice?
This is basically due to how generic variance in Swift works.
Only few types are variant in Swift, including Array<T> and Set<T>. Most other types, and the types you define, are invariant.
Invariance means that T<A> and T<B> are unrelated types even if A and B are related.
Array<T> and Set<T> are covariant, which means that a Array<A> can be assigned to a variable of type Array<B> if A is a subtype of B. You can force it to go the other way (like you did in the third line) by using as!.
ArraySlice<T>, like many other types, is simply invariant. You need to do this to convert:
let d: ArraySlice<Int> = ArraySlice(b.map { $0 as! Int })
As an addendum answer to the correct answer by #Sweeper for people who are looking for type-flexible performant copy-by-ref arrays, I ended up rolling a solution which wraps an array in a class and exposes some of the API for an array.
Not a great solution, but it does what I need it to. Boo Apple for not keeping their APIs for this sort of thing consistent.
class ArrayReference<T>: Collection {
private(set) var array : Array<T>
init(_ encapsulating: Array<T>? = nil) {
self.array = encapsulating ?? []
}
var startIndex: Int {
get {
return array.startIndex
}
}
var endIndex: Int {
get {
return array.endIndex
}
}
var count : Int {
get {
return array.count
}
}
func index(after i: Int) -> Int {
return array.index(after: i)
}
subscript (index: Int) -> T {
get { return array[index] }
set(newValue) { array[index] = newValue }
}
func append(_ newValue: T) {
array.append(newValue)
}
func removeAll() {
array.removeAll()
}
var first: T? {
if array.count > 0 {
return array[0]
} else {
return nil
}
}
var last: T? {
if array.count > 0 {
return array[array.count - 1]
} else {
return nil
}
}
func asType<C>(_ type: C.Type) -> ArrayReference<C>? {
if let array = self.array as? Array<C> {
return ArrayReference<C>(array)
} else {
return nil
}
}
}
extension ArrayReference: Equatable where T: Equatable {
static func == (lhs: ArrayReference<T>, rhs: ArrayReference<T>) -> Bool {
if lhs.count == rhs.count {
var equal = true
for (lhs, rhs) in zip(lhs, rhs) {
equal = equal && (lhs == rhs)
}
return equal
} else {
return false
}
}
}

How to Properly Sort Array of Objects on Numeric Property

I have an array of objects like this, but with 16 properties:
class anObject: NSObject {
#objc var number: Int
#objc var name: String
#objc var price: Double
subscript(key: String) -> Any? {
return self.value(forKey: key)
}
}
I am able to sort my array on any property very easily by, for instance:
sortedArray = unsortedArray.sorted(by: { $0.name < $1.name } )
Now I am grouping my array so that I can populate a UITableView with sections and rows. I group it like this:
var groupedArray = Dictionary<String, Array<myObject>>()
for item in myArray {
// Verify each grouping is initialized only once
if groupedArray[item[byProperty] as! String] == nil {
groupedArray[item[byProperty] as! String] = Array<Items>()
}
// Add the item into the correct subarray
groupedArray[item[byProperty] as! String]?.append(item)
}
I can then sort the grouped array by doing this:
return groupedArray.sorted { $0.0 < $1.0 }
And this works great, except that two of my properties are Doubles. When I sort on those two properties, Swift sorts the groups alphabetically:
10.5, 11.5, 12, 1.5, 2.0 . . .
rather than numerically
1.5, 2.0, 10.5, 11.5, 12 . . .
I have managed to pad the Doubles by checking to see if they are too short and inserting a 0 at the front of the String. This works in that they are now sorted in correct order, but eventually I am going to have to strip that leading 0 off the front, and it seems like an ugly solution.
How do I properly sort the grouped array given that the Doubles have to be used as Strings?
When you start casting strings all over the place, you likely need to start changing the design of things. Why not make the dictionary keys some object you've designed instead of a string? This is a sample of what I mean:
struct DoubleKey {
let value: Double
}
extension DoubleKey: Hashable {
var hashValue: Int {
return value.hashValue
}
static func ==(lhs: DoubleKey, rhs: DoubleKey) -> Bool {
return lhs.value == rhs.value
}
}
extension DoubleKey: Comparable {
static func <(lhs: DoubleKey, rhs: DoubleKey) -> Bool {
return lhs.value < rhs.value
}
}
let a = DoubleKey(value: 10.0)
let b = DoubleKey(value: 20.0)
let c = DoubleKey(value: -10.0)
let dictionary: [DoubleKey: String] = [a: "10", b: "20", c: "-10"]
let sortedDictionary = dictionary.sorted { $0.0 < $1.0 }
So instead of [String: Array<myobject>] you have: [DoubleKey: Array<MyObject> or [IntegerKey: Array<MyObject>] or even [StringKey: Array<MyObject>
You could implement many variations of your own specialized key, and write some protocols if you need additional functionality. If you need to store a string in your key, then add a property, or better yet, conform it to a protocol that defines the behavior of what you need and implement it.
Additional Key
struct StringKey {
let value: String
}
extension StringKey: Hashable {
var hashValue: Int {
return value.hashValue
}
static func ==(lhs: StringKey, rhs: StringKey) -> Bool {
return lhs.value == rhs.value
}
}
extension StringKey: Comparable {
static func <(lhs: StringKey, rhs: StringKey) -> Bool {
return lhs.value < rhs.value
}
}
let a = StringKey(value: "a")
let b = StringKey(value: "c")
let c = StringKey(value: "b")
let dictionary: [StringKey: String] = [a: "10", b: "20", c: "-10"]
let sortedDictionary = dictionary.sorted { $0.0 < $1.0 }
Now what?
//EXAMPLE
protocol ViewableString {
func view() -> String
}
extension StringKey: ViewableString {
func view() -> String {
return value
}
}
extension DoubleKey: ViewableString {
func view() -> String {
return String(value)
}
}
let array: [ViewableString] = [a, b, c]
array[0].view()
Program to the protocols!
Hopefully this helps!
Ok. Completely different answer. Again, you are trying to fit many objects of different types in the same container. This feels like a bad idea to me. Maybe you have to. But here is one way using enums:
enum SpecialKey {
case integer(Int)
case double(Double)
case string(String)
func asString() -> String {
switch self {
case let .integer(a):
return String(a)
case let .double(a):
return String(a)
case let .string(a):
return a
}
}
}
extension SpecialKey: Comparable {
static func <(lhs: SpecialKey, rhs: SpecialKey) -> Bool {
switch (lhs, rhs) {
case let (.double(a), .double(b)):
return a < b
case let (.integer(a), .integer(b)):
return a < b
case let (.string(a), .string(b)):
return a < b
default:
return false //Add more cases with different comparisons!
}
}
static func ==(lhs: SpecialKey, rhs: SpecialKey) -> Bool {
switch (lhs, rhs) {
case (.integer(_), .integer(_)),
(.double(_), .double(_)),
(.string(_), .string(_)):
return true
default:
return false
}
}
}
extension SpecialKey: Hashable {
var hashValue: Int {
switch self {
case let .integer(a):
return a.hashValue
case let .double(a):
return a.hashValue
case let .string(a):
return a.hashValue
}
}
}
let a = SpecialKey.integer(10)
let b = SpecialKey.string("something")
let c = SpecialKey.double(10.5)
let dictionary: [SpecialKey: String] = [a: "a", b: "b", c: "c"]
This is probably more like what you're looking for.

Retrieve array with objects of similar property

I have my two objects (Obj1 & Obj2) defined as below:
class Obj1: NSObject {
var code : String
init(code: String) {
self.code = code
}
}
class Obj2: NSObject {
var codeObj : Obj1
var value : Double
init(primary: Currency, value: Double) {
self.primary = primary
self.value = value
}
}
I have an array of Obj2 and I'm trying to update the array [Obj2] in such a way that the array only contains Obj2 whose codeObj.code are equal. Will including the Equatable protocol help in this?
I have tried this:
let filteredArray = array1.filter( { (c1: Obj2) -> Bool in
return conversion2.contains(where: { (c2: Obj2) -> Bool in
return c1.codeObj.code == c2.codeObj.code;
})
}) + array2.filter( { (c2: Obj2) -> Bool in
return conversion1.contains(where: { (c1: Obj2) -> Bool in
return c1.codeObj.code == c2.codeObj.code;
})
})
IS there a way to simplify this?
The only way for me is adding equatable to the objects like this:
class Obj1: NSObject {
var code : String
init(code: String) {
self.code = code
}
static func ==(lhs: Obj1, rhs: Obj1) -> Bool {
return lhs.code == rhs.code
}
}
class Obj2: NSObject {
var codeObj : Obj1
var value : Double
init(obj: Obj1, value: Double) {
self.codeObj = obj
self.value = value
}
static func ==(lhs: Obj2, rhs: Obj2) -> Bool {
return lhs.codeObj == rhs.codeObj
}
}
And to filter for equals, use for example:
// Test objects
let obj1A = Obj1(code: "aaa")
let obj1B = Obj1(code: "aba")
let obj1C = Obj1(code: "aaa")
let obj1D = Obj1(code: "cca")
let obj1E = Obj1(code: "aba")
let obj1F = Obj1(code: "xca")
let obj2A = Obj2(obj: obj1A, value: 12.0)
let obj2B = Obj2(obj: obj1B, value: 12.0)
let obj2C = Obj2(obj: obj1C, value: 23.0)
let obj2D = Obj2(obj: obj1D, value: 46.0)
let obj2E = Obj2(obj: obj1E, value: 23.0)
let obj2F = Obj2(obj: obj1F, value: 4.0)
var array = [obj2A, obj2B, obj2C, obj2D, obj2E, obj2F]
var onlyEqual = [Obj2]()
for object in array {
let count = array.filter({ $0 == object }).count
if count > 1 {
onlyEqual.append(object)
}
}
Where onlyEqual contains:
aaa
aba
aaa
aba

Convert Array extension to SequenceType?

I'm putting together some common functions I use in my app and came up with the below extensions:
public extension CollectionType {
public func toArray() -> [Self.Generator.Element] {
return self.map { $0 }
}
}
public extension Array {
public func any(fn: (Element) -> Bool) -> Bool {
return self.filter(fn).count > 0
}
public func all(fn: (Element) -> Bool) -> Bool {
return self.filter(fn).count == self.count
}
public func take(count:Int) -> [Element] {
var to = [Element]()
var i = 0
while i < self.count && i < count {
to.append(self[i++])
}
return to
}
public func skip(count:Int) -> [Element] {
var to = [Element]()
var i = count
while i < self.count {
to.append(self[i++])
}
return to
}
}
Can they be applied to a lower level type like SequenceType? Also, do I have to put #noescape anywhere in these functions?
Generally speaking, #noescape should be used anytime the closure isn't saved for later usage, it seems appropriate for both of the closures you have here.
It's not really clear what you mean by "can they be applied to a lower level type" More or less obviously, you could create versions of these extensions for some of the other protocols, but your existing skip function can only be applied to Array (btw, there's an existing function dropFirst on SequenceType that does exactly the same thing)
For both take and skip you might want to actually consider returning an ArraySlice as this avoids copying the original array:
extension Array {
func take(count:Int) -> ArraySlice<Element> {
return self[0..<count]
}
func drop(count:Int) -> ArraySlice<Element> {
return self[count..<self.count]
}
}
Note that for both of these, you probably (may) want to add some error detection/handling as they'll blow up if count > self.count.
Likewise, using contains to implement any and all is probably more efficient since it doesn't result in building a new array just for the count:
extension Array {
func any(#noescape predicate:(Element)->Bool) -> Bool {
return contains(predicate)
}
func all(#noescape predicate:(Element)->Bool) -> Bool {
return !contains { !predicate($0) }
}
}
As an example of defining some of these as extensions to SequenceType:
extension SequenceType {
func any(#noescape predicate:(Generator.Element)->Bool) -> Bool {
return contains(predicate)
}
func all(#noescape predicate:(Generator.Element)->Bool) -> Bool {
return !contains { !predicate($0) }
}
func drop(count:Int) -> Self.SubSequence {
return self.dropFirst(count)
}
}
And, as an example of implementing take as a Sequence extension:
struct TakeFromSequenceSequence<S:SequenceType> : SequenceType {
var limit : Int
var sequence : S
func generate() -> AnyGenerator<S.Generator.Element> {
var generator = sequence.generate()
var limit = self.limit
return anyGenerator {
guard limit > 0 else {
return nil
}
limit = limit - 1
return generator.next()
}
}
}
extension SequenceType {
func take(count:Int) -> TakeFromSequenceSequence<Self> {
return TakeFromSequenceSequence(limit: count, sequence: self)
}
}

Static struct in Rust

I'm playing with Nickel.rs to build a todo list example. As closures are not supported for the moment, I am trying to find another way deal with the simple structure I implemented.
Here is my code :
extern crate nickel;
use std::io::net::ip::Ipv4Addr;
use nickel::{Nickel, Request, Response};
struct TaskList {
list: Vec<String>
}
impl TaskList {
fn new() -> TaskList {
TaskList { list: Vec::new() }
}
fn add_task (&mut self, task: &str) {
&self.list.push(task.to_string());
}
fn get_tasks (&self) -> Vec<String> {
self.list.to_vec()
}
}
fn main() {
let mut server = Nickel::new();
static mut sample : TaskList = TaskList { list: Vec::new() };
sample.add_task("First");
sample.add_task("Second");
fn fetch_tasks (_request: &Request, response: &mut Response) {
response.send(sample.get_tasks().to_string())
}
server.utilize(Nickel::static_files("./public"));
server.get("/task", fetch_tasks);
server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
}
But the compiler write me this : "mutable static items are not allowed to have destructors"
Do you have any advice on how I can solve this ?
I'm not really sure what you're trying to achieve.
If you want the TaskList to exist on the heap, use Box. However, stack scope should be valid event inside server.listen(), so I don't see why you'd need TaskList to be a static mut?
If you want to mess around with static variables, you have to do it unsafely, like this:
use std::mem::transmute;
use std::ptr;
struct Static {
v: int
}
impl Static {
fn whatever(&mut self) {
println!("Write to static");
self.v += 1;
}
}
static mut _data:*const Static = 0 as *const Static;
unsafe fn get<'a>() -> &'a mut Static {
if _data == ptr::null::<Static>() {
// Notice this is a Box<Static>, which is a *Static allocated on the heap
// transmute(Static { v: 0 }) wouldn't work because once the stack scope ends
// the instance would no longer be valid; Box<T> lasts beyond the call to get()
_data = transmute(box Static { v: 0 });
}
return transmute(_data);
}
unsafe fn release() {
ptr::read::<Static>(_data);
}
impl Drop for Static {
fn drop(&mut self) {
println!("Dropped static");
}
}
fn main() {
unsafe {
let foo = get();
foo.whatever();
}
unsafe {
let foo = get();
foo.whatever();
}
unsafe {
release();
}
println!("Done");
}
I really strongly recommend against it though, unless there's a very good reason.
Most of the time you can assume the a variable you create in one scope:
{
let foo = Bar;
...
} <-- End
Will continue to be valid until the end of that scope.
A sub call like server.get is still inside the main() { } scope where sample is defined.
It'll still be valid.

Resources