Strideable

protocol Strideable

A type representing continuous, one-dimensional values that can be offset and measured.

Inheritance Comparable
Conforming Types BinaryInteger, Double, Float, Float80, FloatingPoint, UnsafeMutableRawPointer, UnsafeRawPointer
Associated Types
associatedtype Stride

You can use a type that conforms to the Strideable protocol with the stride(from:to:by:) and stride(from:through:by:) functions. For example, you can use stride(from:to:by:) to iterate over an interval of floating-point values:

for radians in stride(from: 0.0, to: .pi * 2, by: .pi / 2) {
    let degrees = Int(radians * 180 / .pi)
    print("Degrees: \(degrees), radians: \(radians)")
}
// Degrees: 0, radians: 0.0
// Degrees: 90, radians: 1.5707963267949
// Degrees: 180, radians: 3.14159265358979
// Degrees: 270, radians: 4.71238898038469

The last parameter of these functions is of the associated Stride type---the type that represents the distance between any two instances of the Strideable type.

Types that have an integer Stride can be used as the boundaries of a countable range or as the lower bound of an iterable one-sided range. For example, you can iterate over a range of Int and use sequence and collection methods.

var sum = 0
for x in 1...100 {
    sum += x
}
// sum == 5050

let digits = (0..<10).map(String.init)
// ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

Conforming to the Strideable Protocol

To add Strideable conformance to a custom type, choose a Stride type that can represent the distance between two instances and implement the advanced(by:) and distance(to:) methods. For example, this hypothetical Date type stores its value as the number of days before or after January 1, 2000:

struct Date: Equatable, CustomStringConvertible {
    var daysAfterY2K: Int

    var description: String {
        // ...
    }
}

The Stride type for Date is Int, inferred from the parameter and return types of advanced(by:) and distance(to:):

extension Date: Strideable {
    func advanced(by n: Int) -> Date {
        var result = self
        result.daysAfterY2K += n
        return result
    }

    func distance(to other: Date) -> Int {
        return other.daysAfterY2K - self.daysAfterY2K
    }
}

The Date type can now be used with the stride(from:to:by:) and stride(from:through:by:) functions and as the bounds of an iterable range.

let startDate = Date(daysAfterY2K: 0)   // January 1, 2000
let endDate = Date(daysAfterY2K: 15)    // January 16, 2000

for date in stride(from: startDate, to: endDate, by: 7) {
    print(date)
}
// January 1, 2000
// January 8, 2000
// January 15, 2000

Important: The Strideable protocol provides default implementations for the equal-to (==) and less-than (<) operators that depend on the Stride type's implementations. If a type conforming to Strideable is its own Stride type, it must provide concrete implementations of the two operators to avoid infinite recursion.

Instance Methods

func advanced(by n: Self.Stride) -> Self Required

Returns a value that is offset the specified distance from this value.

Use the advanced(by:) method in generic code to offset a value by a specified distance. If you're working directly with numeric values, use the addition operator (+) instead of this method.

func addOne<T: Strideable>(to x: T) -> T
    where T.Stride: ExpressibleByIntegerLiteral
{
    return x.advanced(by: 1)
}

let x = addOne(to: 5)
// x == 6
let y = addOne(to: 3.5)
// y = 4.5

If this type's Stride type conforms to BinaryInteger, then for a value x, a distance n, and a value y = x.advanced(by: n), x.distance(to: y) == n. Using this method with types that have a noninteger Stride may result in an approximation.

  • Parameter n: The distance to advance this value.

Complexity: O(1)

Declaration

func advanced(by n: Self.Stride) -> Self
func distance(to other: Self) -> Self.Stride Required

Returns the distance from this value to the given value, expressed as a stride.

If this type's Stride type conforms to BinaryInteger, then for two values x and y, and a distance n = x.distance(to: y), x.advanced(by: n) == y. Using this method with types that have a noninteger Stride may result in an approximation.

  • Parameter other: The value to calculate the distance to.

Complexity: O(1)

Declaration

func distance(to other: Self) -> Self.Stride

Default Implementations

func ...(maximum: Self) -> PartialRangeThrough<Self>

Returns a partial range up to, and including, its upper bound.

Use the prefix closed range operator (prefix ...) to create a partial range of any type that conforms to the Comparable protocol. This example creates a PartialRangeThrough<Double> instance that includes any value less than or equal to 5.0.

let throughFive = ...5.0

throughFive.contains(4.0)     // true
throughFive.contains(5.0)     // true
throughFive.contains(6.0)     // false

You can use this type of partial range of a collection's indices to represent the range from the start of the collection up to, and including, the partial range's upper bound.

let numbers = [10, 20, 30, 40, 50, 60, 70]
print(numbers[...3])
// Prints "[10, 20, 30, 40]"
  • Parameter maximum: The upper bound for the range.

Declaration

prefix public static func ...(maximum: Self) -> PartialRangeThrough<Self>
func ...(minimum: Self) -> PartialRangeFrom<Self>

Returns a partial range extending upward from a lower bound.

Use the postfix range operator (postfix ...) to create a partial range of any type that conforms to the Comparable protocol. This example creates a PartialRangeFrom<Double> instance that includes any value greater than or equal to 5.0.

let atLeastFive = 5.0...

atLeastFive.contains(4.0)     // false
atLeastFive.contains(5.0)     // true
atLeastFive.contains(6.0)     // true

You can use this type of partial range of a collection's indices to represent the range from the partial range's lower bound up to the end of the collection.

let numbers = [10, 20, 30, 40, 50, 60, 70]
print(numbers[3...])
// Prints "[40, 50, 60, 70]"
  • Parameter minimum: The lower bound for the range.

Declaration

postfix public static func ...(minimum: Self) -> PartialRangeFrom<Self>
func ...(minimum: Self, maximum: Self) -> ClosedRange<Self>

Returns a closed range that contains both of its bounds.

Use the closed range operator (...) to create a closed range of any type that conforms to the Comparable protocol. This example creates a ClosedRange<Character> from "a" up to, and including, "z".

let lowercase = "a"..."z"
print(lowercase.contains("z"))
// Prints "true"

Declaration

public static func ...(minimum: Self, maximum: Self) -> ClosedRange<Self>
func ..<(maximum: Self) -> PartialRangeUpTo<Self>

Returns a partial range up to, but not including, its upper bound.

Use the prefix half-open range operator (prefix ..<) to create a partial range of any type that conforms to the Comparable protocol. This example creates a PartialRangeUpTo<Double> instance that includes any value less than 5.0.

let upToFive = ..<5.0

upToFive.contains(3.14)       // true
upToFive.contains(6.28)       // false
upToFive.contains(5.0)        // false

You can use this type of partial range of a collection's indices to represent the range from the start of the collection up to, but not including, the partial range's upper bound.

let numbers = [10, 20, 30, 40, 50, 60, 70]
print(numbers[..<3])
// Prints "[10, 20, 30]"
  • Parameter maximum: The upper bound for the range.

Declaration

prefix public static func ..<(maximum: Self) -> PartialRangeUpTo<Self>
func ..<(minimum: Self, maximum: Self) -> Range<Self>

Returns a half-open range that contains its lower bound but not its upper bound.

Use the half-open range operator (..<) to create a range of any type that conforms to the Comparable protocol. This example creates a Range<Double> from zero up to, but not including, 5.0.

let lessThanFive = 0.0..<5.0
print(lessThanFive.contains(3.14))  // Prints "true"
print(lessThanFive.contains(5.0))   // Prints "false"

Declaration

public static func ..<(minimum: Self, maximum: Self) -> Range<Self>
func <=(lhs: Self, rhs: Self) -> Bool

Returns a Boolean value indicating whether the value of the first argument is less than or equal to that of the second argument.

This is the default implementation of the less-than-or-equal-to operator (<=) for any type that conforms to Comparable.

Declaration

@inlinable public static func <=(lhs: Self, rhs: Self) -> Bool
func >(lhs: Self, rhs: Self) -> Bool

Returns a Boolean value indicating whether the value of the first argument is greater than that of the second argument.

This is the default implementation of the greater-than operator (>) for any type that conforms to Comparable.

Declaration

@inlinable public static func >(lhs: Self, rhs: Self) -> Bool
func >=(lhs: Self, rhs: Self) -> Bool

Returns a Boolean value indicating whether the value of the first argument is greater than or equal to that of the second argument.

This is the default implementation of the greater-than-or-equal-to operator (>=) for any type that conforms to Comparable.

Declaration

@inlinable public static func >=(lhs: Self, rhs: Self) -> Bool