[swift-evolution] [Discussion][Expericment] D-like slicing syntax
Dave Abrahams
dabrahams at apple.com
Mon Feb 29 16:22:47 CST 2016
on Sat Feb 27 2016, Daniel Duan <swift-evolution at swift.org> wrote:
> Dave Abrahams via swift-evolution <swift-evolution at ...> writes:
>
>>
>>
>> on Sat Feb 20 2016, Daniel Duan <swift-evolution <at> swift.org> wrote:
>>
>
>> Why not just make
>>
>> x[..<$-2]
>>
>> work? You can create unary overloads for ..<
>
> Hi Dave, I took another stab at it today. The code is in the following link as
> well as end of this email:
> https://gist.github.com/dduan/fcd33a09fae4640fc83c
>
> This implementation is almost good IMO :)
What's the case that keeps it from actually being good?
> struct Dollar {}
>
> let $ = Dollar()
>
> struct BInt: IntegerLiteralConvertible {
> let bool: Bool
> let int: UInt
> func relativeTo(total: Int) -> Int {
> return bool ? total - Int(int) : Int(int)
> }
> init(_ b: Bool, _ n: UInt) {
> bool = b
> int = n
> }
> init(integerLiteral value: Int) {
> bool = false
> int = UInt(value)
> }
> }
>
> func -(h: Dollar, d: UInt) -> BInt { return BInt(true, d) }
>
> typealias IncompleteRange = (BInt?, BInt?)
>
> prefix operator ..< {}
> prefix func ..<(end: BInt) -> IncompleteRange {
> return (nil, end)
> }
>
> postfix operator ..< {}
> postfix func ..<(start: BInt) -> IncompleteRange {
> return (start, nil)
> }
> prefix operator ... {}
> prefix func ...(end: BInt) -> IncompleteRange {
> return (nil, BInt(end.bool, end.int+1))
> }
> postfix operator ... {}
> postfix func ...(start: BInt) -> IncompleteRange {
> return (start, nil)
> }
>
> func ..<(start: BInt, end: BInt) -> IncompleteRange {
> return (start, end)
> }
>
> func ...(start: BInt, end: BInt) -> IncompleteRange {
> return (start, BInt(end.bool, end.int+1))
> }
>
> internal func normalize(range: IncompleteRange, total: Int) -> (Int, Int) {
> var actualStart = range.0 == nil ? 0 : range.0!.relativeTo(total)
> var actualEnd = range.1 == nil ? total : range.1!.relativeTo(total)
> actualStart = actualStart < 0 ? total + actualStart : actualStart
> actualEnd = actualEnd < 0 ? total + actualEnd : actualEnd
> return (actualStart, actualEnd)
> }
>
> extension CollectionType {
> subscript(halfRange: IncompleteRange) -> Self.SubSequence {
> let (safeStart, safeEnd) = normalize(
> halfRange,
> total: self.count as! Int
> )
> let safeStartIndex = startIndex.advancedBy(
> safeStart as! Self.Index.Distance)
> let safeEndIndex = startIndex.advancedBy(
> safeEnd as! Self.Index.Distance)
> return self[safeStartIndex..<safeEndIndex]
> }
> }
>
> let s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>
> // all of these expression results in [6, 7, 8, 9]
> s[6...]
> s[($-4)...]
> s[6..<s.count]
> s[6..<$-0]
> s[$-4...9]
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
--
-Dave
More information about the swift-evolution
mailing list