Skip to content

Instantly share code, notes, and snippets.

@natecook1000
Last active May 27, 2021 19:37
Show Gist options
  • Save natecook1000/3b15b8bd974c8c08b3df to your computer and use it in GitHub Desktop.
Save natecook1000/3b15b8bd974c8c08b3df to your computer and use it in GitHub Desktop.
Open-ended range operators for Swift
// Open-ended range operators
//
// 100... is equivalent to 100...Int.max
// ...-100 is equivalent to Int.min...-100
// ..<3 is equivalent to Int.min..<3
import Swift
/// Conforming types provide static `max` and `min` constants.
protocol MinMaxType {
class var min: Self { get }
class var max: Self { get }
}
// extend relevant types
extension Int : MinMaxType {}
extension Int8 : MinMaxType {}
extension Int16 : MinMaxType {}
extension Int32 : MinMaxType {}
extension Int64 : MinMaxType {}
extension UInt : MinMaxType {}
extension UInt8 : MinMaxType {}
extension UInt16 : MinMaxType {}
extension UInt32 : MinMaxType {}
extension UInt64 : MinMaxType {}
// declare the prefix and postfix operators
prefix operator ..< { }
prefix operator ... { }
postfix operator ..< { }
postfix operator ... { }
/// Forms a closed range that contains both `T.min` and `value`
prefix func ...<T: ForwardIndexType where T: Comparable, T: MinMaxType>(value: T) -> Range<T> {
return Range(start: T.min, end: value.successor())
}
/// Returns a closed interval from `T.min` through `value`
prefix func ...<T: Comparable where T: MinMaxType>(value: T) -> ClosedInterval<T> {
return ClosedInterval(T.min, value)
}
/// Forms a half-open range that contains `T.min`, but not `value`
prefix func ..<<T: ForwardIndexType where T: Comparable, T: MinMaxType>(value: T) -> Range<T> {
return Range(start: T.min, end: value)
}
/// Returns a half-open interval from `T.min` to `value`
prefix func ..<<T: Comparable where T: MinMaxType>(value: T) -> HalfOpenInterval<T> {
return HalfOpenInterval(T.min, value)
}
/// Forms a half-open range that contains `value`, but not `T.max`
postfix func ..<<T: ForwardIndexType where T: Comparable, T: MinMaxType>(value: T) -> Range<T> {
return Range(start: value, end: T.max)
}
// a closed range containing `T.max` fails, since it would need to call `T.max.successor()`
/// Returns a closed interval from `value` through `T.max`
postfix func ...<T: Comparable where T: MinMaxType>(value: T) -> ClosedInterval<T> {
return ClosedInterval(value, T.max)
}
// example:
for i in 1...10 {
switch i {
case ...3:
println("...3")
case 4..<6:
println("4..<6")
case 6...:
println("6...")
default:
println("no match")
}
}
/*
...3
...3
...3
4..<6
4..<6
6...
6...
6...
6...
6...
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment