Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163const std = @import("std");
pub const IntervalU8 = Interval(u8);pub const IntervalU16 = Interval(u16);pub const IntervalU32 = Interval(u32);pub const IntervalU64 = Interval(u64);pub const IntervalUsize = Interval(usize);
pub const IntervalI8 = Interval(i8);pub const IntervalI16 = Interval(i16);pub const IntervalI32 = Interval(i32);pub const IntervalI64 = Interval(i64);pub const IntervalIsize = Interval(isize);
pub const IntervalF32 = Interval(f32);pub const IntervalF64 = Interval(f64);
pub const IntervalIteratorType = enum { inclusive, exclusive,};
pub fn Interval(comptime T: type) type { if (@typeInfo(T) == .int) { return IntInterval(T); } else if (@typeInfo(T) == .float) { return FloatInterval(T); } else { @compileError("Interval only supports Int and Float Types!"); }}
fn IntInterval(comptime T: type) type { return struct { const Self = @This();
pub const empty: Self = .{ .min = std.math.inf(T), .max = -std.math.inf(T) }; pub const universe: Self = .{ .min = -std.math.inf(T), .max = std.math.inf(T) };
pub const Iterator = struct { interval: Self, current: T,
lower_boundry: IntervalIteratorType = .inclusive, upper_boundry: IntervalIteratorType = .exclusive,
pub fn init( interval: Self, lower_boundry: IntervalIteratorType, upper_boundry: IntervalIteratorType, ) Iterator { return .{ .interval = interval, .current = if (lower_boundry == .inclusive) interval.min else interval.min + 1, .lower_boundry = lower_boundry, .upper_boundry = upper_boundry, }; }
pub fn next(self: *Iterator) ?T { self.current += 1; if (self.current < self.interval.max or (self.current == self.interval.max and self.upper_boundry == .inclusive)) { return self.current - 1; } else return null; }
pub fn nextInc(self: *Iterator) ?T { self.current += 1; return if (self.current <= self.interval.max) self.current - 1 else null; }
pub fn nextExc(self: *Iterator) ?T { self.current += 1; return if (self.current < self.interval.max) self.current - 1 else null; } };
min: T, max: T,
pub fn init(min: T, max: T) Interval { return .{ .min = min, .max = max }; }
pub fn initI(a: Self, b: Self) Self { return Self{ .min = @min(a.min, b.min), .max = @max(a.max, b.max) }; }
pub fn contains(self: *const Self, x: T) bool { return self.min <= x and x <= self.max; }
pub fn surrounds(self: *const Self, x: T) bool { return self.min < x and x < self.max; }
pub fn clamp(self: *const Self, x: T) T { if (x < self.min) return self.min; if (x > self.max) return self.max; return x; }
pub fn expand(self: *const Self, delta: T) Interval { const padding = delta / 2; return .{ .min = self.min - padding, .max = self.max + padding }; }
pub fn size(self: *const Self) T { return self.max - self.min; }
pub fn iter(self: *const Self) Iterator { return Iterator{ .interval = self.*, .current = self.min, }; } };}
fn FloatInterval(comptime T: type) type { return struct { pub const empty: @This() = .{ .min = std.math.inf(T), .max = -std.math.inf(T) }; pub const universe: @This() = .{ .min = -std.math.inf(T), .max = std.math.inf(T) };
const Self = @This();
min: T, max: T,
pub fn init(min: T, max: T) Self { return Self{ .min = min, .max = max }; }
pub fn initI(a: Self, b: Self) Self { return Self{ .min = @min(a.min, b.min), .max = @max(a.max, b.max) }; }
pub fn contains(self: *const Self, x: T) bool { return self.min <= x and x <= self.max; }
pub fn surrounds(self: *const Self, x: T) bool { return self.min < x and x < self.max; }
pub fn clamp(self: *const Self, x: T) T { if (x < self.min) return self.min; if (x > self.max) return self.max; return x; }
pub fn expand(self: *const Self, delta: T) Self { const padding = delta / 2; return .{ .min = self.min - padding, .max = self.max + padding }; }
pub fn size(self: *const Self) T { return self.max - self.min; } };}