diff --git a/pkg/macos/build.zig b/pkg/macos/build.zig index aed7e5d28..942100e45 100644 --- a/pkg/macos/build.zig +++ b/pkg/macos/build.zig @@ -28,7 +28,7 @@ pub fn build(b: *std.Build) !void { lib.linkFramework("CoreFoundation"); lib.linkFramework("CoreGraphics"); lib.linkFramework("CoreText"); - try apple_sdk.addPaths(b, lib); + if (!target.isNative()) try apple_sdk.addPaths(b, lib); b.installArtifact(lib); diff --git a/pkg/macos/foundation/array.zig b/pkg/macos/foundation/array.zig index 4524cda6b..ce9a0b109 100644 --- a/pkg/macos/foundation/array.zig +++ b/pkg/macos/foundation/array.zig @@ -1,6 +1,9 @@ const std = @import("std"); const Allocator = std.mem.Allocator; +const base = @import("base.zig"); const cftype = @import("type.zig"); +const ComparisonResult = base.ComparisonResult; +const Range = base.Range; pub const Array = opaque { pub fn create(comptime T: type, values: []*const T) Allocator.Error!*Array { @@ -38,6 +41,52 @@ pub const Array = opaque { extern "c" var kCFTypeArrayCallBacks: anyopaque; }; +pub const MutableArray = opaque { + pub fn createCopy(array: *Array) Allocator.Error!*MutableArray { + return CFArrayCreateMutableCopy( + null, + 0, + array, + ) orelse error.OutOfMemory; + } + + pub fn release(self: *MutableArray) void { + cftype.CFRelease(self); + } + + pub fn sortValues( + self: *MutableArray, + comptime Elem: type, + comptime Context: type, + context: ?*Context, + comptime comparator: ?*const fn ( + a: *const Elem, + b: *const Elem, + context: ?*Context, + ) ComparisonResult, + ) void { + CFArraySortValues( + self, + Range.init(0, Array.CFArrayGetCount(@ptrCast(self))), + comparator, + context, + ); + } + + extern "c" fn CFArrayCreateMutableCopy( + allocator: ?*anyopaque, + capacity: usize, + array: *Array, + ) ?*MutableArray; + + extern "c" fn CFArraySortValues( + array: *MutableArray, + range: Range, + comparator: ?*const anyopaque, + context: ?*anyopaque, + ) void; +}; + test "array" { const testing = std.testing; @@ -52,4 +101,43 @@ test "array" { const ch = arr.getValueAtIndex(u8, 0); try testing.expectEqual(@as(u8, 'h'), ch.*); } + + // Can make it mutable + var mut = try MutableArray.createCopy(arr); + defer mut.release(); +} + +test "array sorting" { + const testing = std.testing; + + const str = "hello"; + var values = [_]*const u8{ &str[0], &str[1] }; + const arr = try Array.create(u8, &values); + defer arr.release(); + const mut = try MutableArray.createCopy(arr); + defer mut.release(); + + mut.sortValues( + u8, + void, + null, + struct { + fn compare(a: *const u8, b: *const u8, _: ?*void) ComparisonResult { + if (a.* > b.*) return .greater; + if (a.* == b.*) return .equal; + return .less; + } + }.compare, + ); + + { + const mutarr: *Array = @ptrCast(mut); + const ch = mutarr.getValueAtIndex(u8, 0); + try testing.expectEqual(@as(u8, 'e'), ch.*); + } + { + const mutarr: *Array = @ptrCast(mut); + const ch = mutarr.getValueAtIndex(u8, 1); + try testing.expectEqual(@as(u8, 'h'), ch.*); + } }