I'm trying to create an operator for numbers. For example an operator that increments a number by 10.
This is the code I wrote:
prefix operator +++{}
prefix operator +++<T>(inout operand: T) -> T{
operand += 10
return operand
}
There is an error with my +=
operator. it requires numeric operands. so I did this:
protocol Numeric {}
extension Int: Numeric {}
extension Float: Numeric {}
extension Double: Numeric {}
prefix operator +++ {}
prefix operator +++<T: Numeric>(inout operand: T) -> T {
operand += 10
return operand
}
But it failed to compile. Anybody have any ideas?
The problem is that your Numeric
protocol does not guarantee a +=
operator will be present.
Consider this:
// Numeric imposes no requirements, so this will compile
extension Range: Numeric { }
// but Range has no += operator, so +++ could not work
Instead, you would have to add +=
as a requirement of Numeric
:
protocol Numeric: IntegerLiteralConvertible {
func +=(inout lhs: Self,rhs: Self)
}
Note, you also need Numeric
to conform to IntegerLiteralConvertible
so that you can create a 10
of the appropriate type to add to it.
Now, this compiles and runs fine, because Numeric
guarantees all the features it uses will be available:
prefix operator +++{}
prefix func +++<T: Numeric>(inout operand: T) -> T {
operand += 10
return operand
}
var i = 10
+++i // i is now 20
That said, there is already a protocol that does what you need: Strideable
, to which all the standard numeric types conform.
protocol Strideable {
// (actually _Strideable but don’t worry about that)
/// A type that can represent the distance between two values of `Self`.
typealias Stride : SignedNumberType
// note, SignedNumberType conforms to IntegerLiteralConvertible
/// Returns a `Self` `x` such that `self.distanceTo(x)` approximates
/// `n`.
///
/// - Complexity: O(1).
///
/// - SeeAlso: `RandomAccessIndexType`'s `advancedBy`, which
/// provides a stronger semantic guarantee.
func advancedBy(n: Self.Stride) -> Self
}
And an implementation of +=
that uses it:
func +=<T : Strideable>(inout lhs: T, rhs: T.Stride)
This means you can implement +++
like this:
prefix func +++<T: Strideable>(inout operand: T) -> T {
operand = operand.advancedBy(10)
return operand
}