this repo has no description
at main 4.9 kB view raw
1const std = @import("std"); 2 3pub const IntervalU8 = Interval(u8); 4pub const IntervalU16 = Interval(u16); 5pub const IntervalU32 = Interval(u32); 6pub const IntervalU64 = Interval(u64); 7pub const IntervalUsize = Interval(usize); 8 9pub const IntervalI8 = Interval(i8); 10pub const IntervalI16 = Interval(i16); 11pub const IntervalI32 = Interval(i32); 12pub const IntervalI64 = Interval(i64); 13pub const IntervalIsize = Interval(isize); 14 15pub const IntervalF32 = Interval(f32); 16pub const IntervalF64 = Interval(f64); 17 18pub const IntervalIteratorType = enum { 19 inclusive, 20 exclusive, 21}; 22 23pub fn Interval(comptime T: type) type { 24 if (@typeInfo(T) == .int) { 25 return IntInterval(T); 26 } else if (@typeInfo(T) == .float) { 27 return FloatInterval(T); 28 } else { 29 @compileError("Interval only supports Int and Float Types!"); 30 } 31} 32 33fn IntInterval(comptime T: type) type { 34 return struct { 35 const Self = @This(); 36 37 pub const empty: Self = .{ .min = std.math.inf(T), .max = -std.math.inf(T) }; 38 pub const universe: Self = .{ .min = -std.math.inf(T), .max = std.math.inf(T) }; 39 40 pub const Iterator = struct { 41 interval: Self, 42 current: T, 43 44 lower_boundry: IntervalIteratorType = .inclusive, 45 upper_boundry: IntervalIteratorType = .exclusive, 46 47 pub fn init( 48 interval: Self, 49 lower_boundry: IntervalIteratorType, 50 upper_boundry: IntervalIteratorType, 51 ) Iterator { 52 return .{ 53 .interval = interval, 54 .current = if (lower_boundry == .inclusive) interval.min else interval.min + 1, 55 .lower_boundry = lower_boundry, 56 .upper_boundry = upper_boundry, 57 }; 58 } 59 60 pub fn next(self: *Iterator) ?T { 61 self.current += 1; 62 if (self.current < self.interval.max or (self.current == self.interval.max and self.upper_boundry == .inclusive)) { 63 return self.current - 1; 64 } else return null; 65 } 66 67 pub fn nextInc(self: *Iterator) ?T { 68 self.current += 1; 69 return if (self.current <= self.interval.max) self.current - 1 else null; 70 } 71 72 pub fn nextExc(self: *Iterator) ?T { 73 self.current += 1; 74 return if (self.current < self.interval.max) self.current - 1 else null; 75 } 76 }; 77 78 min: T, 79 max: T, 80 81 pub fn init(min: T, max: T) Interval { 82 return .{ .min = min, .max = max }; 83 } 84 85 pub fn initI(a: Self, b: Self) Self { 86 return Self{ .min = @min(a.min, b.min), .max = @max(a.max, b.max) }; 87 } 88 89 pub fn contains(self: *const Self, x: T) bool { 90 return self.min <= x and x <= self.max; 91 } 92 93 pub fn surrounds(self: *const Self, x: T) bool { 94 return self.min < x and x < self.max; 95 } 96 97 pub fn clamp(self: *const Self, x: T) T { 98 if (x < self.min) return self.min; 99 if (x > self.max) return self.max; 100 return x; 101 } 102 103 pub fn expand(self: *const Self, delta: T) Interval { 104 const padding = delta / 2; 105 return .{ .min = self.min - padding, .max = self.max + padding }; 106 } 107 108 pub fn size(self: *const Self) T { 109 return self.max - self.min; 110 } 111 112 pub fn iter(self: *const Self) Iterator { 113 return Iterator{ 114 .interval = self.*, 115 .current = self.min, 116 }; 117 } 118 }; 119} 120 121fn FloatInterval(comptime T: type) type { 122 return struct { 123 pub const empty: @This() = .{ .min = std.math.inf(T), .max = -std.math.inf(T) }; 124 pub const universe: @This() = .{ .min = -std.math.inf(T), .max = std.math.inf(T) }; 125 126 const Self = @This(); 127 128 min: T, 129 max: T, 130 131 pub fn init(min: T, max: T) Self { 132 return Self{ .min = min, .max = max }; 133 } 134 135 pub fn initI(a: Self, b: Self) Self { 136 return Self{ .min = @min(a.min, b.min), .max = @max(a.max, b.max) }; 137 } 138 139 pub fn contains(self: *const Self, x: T) bool { 140 return self.min <= x and x <= self.max; 141 } 142 143 pub fn surrounds(self: *const Self, x: T) bool { 144 return self.min < x and x < self.max; 145 } 146 147 pub fn clamp(self: *const Self, x: T) T { 148 if (x < self.min) return self.min; 149 if (x > self.max) return self.max; 150 return x; 151 } 152 153 pub fn expand(self: *const Self, delta: T) Self { 154 const padding = delta / 2; 155 return .{ .min = self.min - padding, .max = self.max + padding }; 156 } 157 158 pub fn size(self: *const Self) T { 159 return self.max - self.min; 160 } 161 }; 162}