Last active
December 5, 2015 01:07
-
-
Save oisdk/d381e5939e33901fc797 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// IntervalTypes | |
protocol IntervalType { | |
typealias Value | |
func contains(v: Value) -> Bool | |
} | |
protocol OpenEndedIntervalType: IntervalType { | |
typealias Value: Comparable | |
var val: Value { get } | |
} | |
protocol OpenStartedIntervalTypeTo: IntervalType { | |
typealias Value: Comparable | |
var val: Value { get } | |
} | |
protocol OpenStartedIntervalTypeThrough: IntervalType { | |
typealias Value: Comparable | |
var val: Value { get } | |
} | |
// Interval Structs | |
struct OpenEndedInterval<C: Comparable>: OpenEndedIntervalType { internal let val: C } | |
struct OpenStartedIntervalTo<C: Comparable>: OpenStartedIntervalTypeTo { internal let val: C } | |
struct OpenStartedIntervalThrough<C: Comparable>: OpenStartedIntervalTypeTo { internal let val: C } | |
// Range structs | |
struct OpenEndedRange<I: ForwardIndexType where I: Comparable>: OpenEndedIntervalType { | |
var val: I | |
} | |
struct OpenStartedRangeTo<I: BidirectionalIndexType where I: Comparable>: OpenStartedIntervalTypeTo { | |
var val: I | |
} | |
struct OpenStartedRangeThrough<I: BidirectionalIndexType where I: Comparable>: OpenStartedIntervalTypeTo { | |
var val: I | |
} | |
// Generators | |
struct EndlessIncrement<I: ForwardIndexType>: GeneratorType { | |
private var i: I | |
mutating func next() -> I? { | |
defer { i = i.successor() } | |
return i | |
} | |
} | |
struct EndlessPostDecrement<I: BidirectionalIndexType>: GeneratorType { | |
private var i: I | |
mutating func next() -> I? { | |
defer { i = i.predecessor() } | |
return i | |
} | |
} | |
struct EndlessPrefDecrement<I: BidirectionalIndexType>: GeneratorType { | |
private var i: I | |
mutating func next() -> I? { | |
i = i.predecessor() | |
return i | |
} | |
} | |
// SequenceType | |
extension OpenEndedRange: LazySequenceType { | |
func generate() -> EndlessIncrement<I> { | |
return EndlessIncrement(i: val) | |
} | |
} | |
extension OpenStartedRangeTo: LazySequenceType { | |
func generate() -> EndlessPrefDecrement<I> { | |
return EndlessPrefDecrement(i: val) | |
} | |
} | |
extension OpenStartedRangeThrough: LazySequenceType { | |
func generate() -> EndlessPostDecrement<I> { | |
return EndlessPostDecrement(i: val) | |
} | |
} | |
// Operators | |
postfix operator ... {} | |
prefix operator ... {} | |
prefix operator ..< {} | |
postfix func ...<C: Comparable>(c: C) -> OpenEndedInterval<C> { | |
return OpenEndedInterval(val: c) | |
} | |
postfix func ...<I: ForwardIndexType>(c: I) -> OpenEndedRange<I> { | |
return OpenEndedRange(val: c) | |
} | |
prefix func ..<<C: Comparable>(c: C) -> OpenStartedIntervalTo<C> { | |
return OpenStartedIntervalTo(val: c) | |
} | |
prefix func ..<<C: BidirectionalIndexType>(c: C) -> OpenStartedRangeTo<C> { | |
return OpenStartedRangeTo(val: c) | |
} | |
prefix func ...<C: Comparable>(c: C) -> OpenStartedIntervalThrough<C> { | |
return OpenStartedIntervalThrough(val: c) | |
} | |
prefix func ...<C: BidirectionalIndexType>(c: C) -> OpenStartedRangeThrough<C> { | |
return OpenStartedRangeThrough(val: c) | |
} | |
// Contains | |
extension OpenEndedIntervalType { | |
func contains(e: Value) -> Bool { return val <= e } | |
} | |
extension OpenStartedIntervalTypeTo { | |
func contains(v: Value) -> Bool { return val > v } | |
} | |
extension OpenStartedIntervalTypeThrough { | |
func contains(v: Value) -> Bool { return val >= v } | |
} | |
// Pattern Matching | |
func ~=<I: IntervalType>(lhs: I, rhs: I.Value) -> Bool { | |
return lhs.contains(rhs) | |
} | |
// Indexing | |
extension CollectionType where Index: Comparable { | |
subscript(r: OpenEndedInterval<Index>) -> SubSequence { | |
return suffixFrom(r.val) | |
} | |
subscript(r: OpenStartedIntervalTo<Index>) -> SubSequence { | |
return prefixUpTo(r.val) | |
} | |
subscript(r: OpenStartedIntervalThrough<Index>) -> SubSequence { | |
return prefixThrough(r.val) | |
} | |
} | |
extension MutableCollectionType where Index: Comparable { | |
subscript(r: OpenEndedInterval<Index>) -> SubSequence { | |
get { return suffixFrom(r.val) } | |
set { self[r.val...endIndex] = newValue } | |
} | |
subscript(r: OpenStartedIntervalTo<Index>) -> SubSequence { | |
get { return prefixUpTo(r.val) } | |
set { self[startIndex..<r.val] = newValue } | |
} | |
subscript(r: OpenStartedIntervalThrough<Index>) -> SubSequence { | |
get { return prefixThrough(r.val) } | |
set { self[startIndex...r.val] = newValue } | |
} | |
} | |
extension CollectionType where Index: Comparable { | |
subscript(r: OpenEndedRange<Index>) -> SubSequence { | |
return suffixFrom(r.val) | |
} | |
} | |
extension CollectionType where Index: Comparable, Index: BidirectionalIndexType { | |
subscript(r: OpenStartedRangeTo<Index>) -> SubSequence { | |
return prefixUpTo(r.val) | |
} | |
subscript(r: OpenStartedRangeThrough<Index>) -> SubSequence { | |
return prefixThrough(r.val) | |
} | |
} | |
extension MutableCollectionType where Index: Comparable { | |
subscript(r: OpenEndedRange<Index>) -> SubSequence { | |
get { return suffixFrom(r.val) } | |
set { self[r.val...endIndex] = newValue } | |
} | |
} | |
extension MutableCollectionType where Index: Comparable, Index: BidirectionalIndexType { | |
subscript(r: OpenStartedRangeTo<Index>) -> SubSequence { | |
get { return prefixUpTo(r.val) } | |
set { self[startIndex..<r.val] = newValue } | |
} | |
subscript(r: OpenStartedRangeThrough<Index>) -> SubSequence { | |
get { return prefixThrough(r.val) } | |
set { self[startIndex...r.val] = newValue } | |
} | |
} | |
// Hopping | |
public struct RandomAccessHopCollection< | |
Base: CollectionType where | |
Base.Index : RandomAccessIndexType, | |
Base.Index.Distance : ForwardIndexType | |
> : CollectionType { | |
private let base: Base | |
private let by : Base.Index.Stride | |
private let fac : Base.Index.Distance | |
public var startIndex: Base.Index.Distance { return 0 } | |
public let endIndex: Base.Index.Distance | |
public subscript(i: Base.Index.Distance) -> Base.Generator.Element { | |
return base[base.startIndex.advancedBy(fac * i)] | |
} | |
private init(_ b: Base, _ by: Base.Index.Stride) { | |
base = b | |
self.by = by | |
fac = base.startIndex.distanceTo(base.startIndex.advancedBy(by)) | |
endIndex = (base.startIndex.distanceTo(base.endIndex.predecessor()) / fac).successor() | |
} | |
} | |
extension CollectionType where Index: RandomAccessIndexType, Index.Distance: ForwardIndexType { | |
public subscript(by by: Index.Stride) -> RandomAccessHopCollection<Self> { | |
return RandomAccessHopCollection(self, by) | |
} | |
} | |
extension RandomAccessHopCollection: CustomStringConvertible, CustomDebugStringConvertible { | |
public var debugDescription: String { | |
return Array(self).debugDescription | |
} | |
public var description: String { | |
return String(Array(self)) | |
} | |
} | |
extension CollectionType where | |
SubSequence: CollectionType, | |
Index == SubSequence.Index, | |
SubSequence.Index: RandomAccessIndexType, | |
SubSequence.Index.Distance: ForwardIndexType { | |
subscript(r: OpenEndedInterval<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> { | |
return suffixFrom(r.val)[by: by] | |
} | |
subscript(r: OpenStartedIntervalTo<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> { | |
return prefixUpTo(r.val)[by: by] | |
} | |
subscript(r: OpenStartedIntervalThrough<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> { | |
return prefixThrough(r.val)[by: by] | |
} | |
subscript(r: OpenEndedRange<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> { | |
return suffixFrom(r.val)[by: by] | |
} | |
subscript(r: OpenStartedRangeTo<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> { | |
return prefixUpTo(r.val)[by: by] | |
} | |
subscript(r: OpenStartedRangeThrough<Index>, by by: Index.Stride) -> RandomAccessHopCollection<SubSequence> { | |
return prefixThrough(r.val)[by: by] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment