Swift stdlib default implemention for Greate operation - swift

extension Decimal: LCDecimalPrecise {
public static func == (lhs: Decimal, rhs: Decimal) -> Bool {
return !((lhs - rhs).doubleValue > LCMetricUnit.moneyPrecise ||
(rhs - lhs).doubleValue > LCMetricUnit.moneyPrecise)
}
public static func < (lhs: Decimal, rhs: Decimal) -> Bool {
return (lhs - rhs).doubleValue < -LCMetricUnit.moneyPrecise
}
public static func > (lhs: Decimal, rhs: Decimal) -> Bool {
return (lhs - rhs).doubleValue > LCMetricUnit.moneyPrecise
}
}
after overriding the first two methods(> operator method ignored), then calling the method of the following for example:
if Decimal(string: "1") > Decimal(string: "2") {//TODO sth}
I think the less(<) operator will expect to be called according the document and source code,
When debugging, it doesn't be called. So strange!!! Finally, we implement greater operation to work around this problem.

Related

How to check if two structs have the same generic parameter type in Swift?

While checking out this repository https://github.com/Samasaur1/DiceKit I stumbled on following piece of code implementing Comparable/Hashable this way:
public struct DieSide<OutputType: Hashable>: Hashable {
public let value: OutputType
// snip
public static func == (lhs: DieSide, rhs: DieSide) -> Bool { //IMPORTANT NOTE: THIS DOES NOT ACCEPT DieSides WITH DIFFERENT GENERIC ARGUMENTS
guard type(of: lhs.value) == type(of: rhs.value) else {
return false
}
return lhs.value == rhs.value
}
// snip
}
You can find the code here.
I believe this check could be done on the language level using where clause instead of checking the types of the arguments in the code and especially - so the comment won't be necessary anymore.
One approach I tried is this one, but that clearly doesn't work (Neither type in same-type constraint ('error type' or 'error type') refers to a generic parameter or associated type):
public static func == (lhs: DieSide, rhs: DieSide) -> Bool where lhs.value.Type == rhs.value.Type {
return lhs.value == rhs.value
}
I also searched for similar answers but was able to find solutions for languages other than Swift at the moment.
Any help on accessing the generic parameters' types appreciated.
The guard statement in that code is pointless. It is impossible for type(of: lhs.value) == type(of: rhs.value) to be false.
The first of these is just shorthand for the second.
public static func == (lhs: DieSide, rhs: DieSide) -> Bool {
lhs.value == rhs.value
}
public static func == (lhs: DieSide<OutputType>, rhs: DieSide<OutputType>) -> Bool {
lhs.value == rhs.value
}
(You can also use Self instead of DieSide.)

What is the Swift equivalent for Java's Comparator Interface

I have the following Java code below that I am trying to convert into Swift accordingly. Can somebody help me on this issue. Thanks
public class CarsSortById implements Comparator<Cars>{
#Override
public int compare(Cars car1, Cars car2) {
return (car1.getCarId() < car2.getCarId()) ? -1:
(car1.getCarId() > car2.getCarId() ) ? 1:0 ;
}
}
Swift equivalent of Comparable<T>
Is the Comparable protocol. It requires that your type define an < operator. Since it derives from the Equatable protocol, you need to define the == operator, as well:
class Car {
let id: Int
// other fields
}
extension Car: Equatable {
static func == (lhs: Car, rhs: Car) -> Bool {
return lhs.id == rhs.id
}
}
extension Car: Comparable {
static func < (lhs: Car, rhs: Car) -> Bool {
return lhs.id < rhs.id
}
}
Swift equivalent of Comparator<T>
In Java, Comparator is an interface that lets you define sorting functions in addition to the one a type defines for itself via the Comparable Interface. Interfaces like this are necessary because Java didn't support lambdas prior to 1.8. And after Java 1.8, interfaces form the basis of lambdas.
Swift doesn't have an equivalent interface (called a protocol, in Swift). There's no need, since Swift can let you just define closures without the #functionalinterface cruft of Java.
Usually, Java Comparators are only used once. In this case, just call sort with a custom sorting closure:
let carsSortedByID = cars.sorted { $0.id < $1.id }
If you need to resume the sorting closure, you could assign it to a variable. Naturally, it would make sense to store these as static variable in an extension on the type that they sort.:
extension Car {
static let idSorter: (Car, Car) -> Bool = { $0.id < $1.id }
}
let carsSortedByID = cars.sorted(by: Car.idSorter)
As already mentioned in other answers and in the comment, in swift there is nothing for that. It is just closure.
But here is how you define Comparable
class Car {
var id = -1
}
extension Car: Comparable {
static func == (lhs: Car, rhs: Car) -> Bool {
return lhs.id == rhs.id
}
static func < (lhs: Car, rhs: Car) -> Bool {
return lhs.id < rhs.id
}
}
If you're looking to specifically replicate the Java Comparator behavior where it returns a negative number for "less than", zero for "equal", or a positive number for "greater than", you could write a function that returns a ComparisonResult.
ComparisonResult is an enum with the cases .orderedAscending, .orderedSame, and .orderedDescending.
You could rewrite your function in Swift:
extension Car {
func compare(with other: Car) -> ComparisonResult {
return self.carId < other.carId
? .orderedDescending
: self.carId > other.carId ? .orderedAscending : .orderedSame
}
}

Bit field larger than 64 shifts in Swift?

How would I construct an OptionSetType with a raw value greater than 64 bit shifts (i.e. Int64) that is still able to be encoded using NSCoder? I have more than 64 potential bitwise options to combine.
So I eventually had to create my own primitive struct which was a pain in the ass, since the library #appzYourLife provided does not actually meet every protocol required of UnsignedIntegerTypes. The following is an extension I wrote that actually allows me to write things like
let a: UInt256 = 30
let b: UInt256 = 1 << 98
print(a + b)
which would output to the console:
0x00000000:00000000:00000000:00000000:00000004:00000000:00000000:0000001E
The extension is pretty lengthy and does not yet implement multiplication and devision or bit-shifting numbers other than 1. This version also supports encoding with and NSCoder
//
// UInt256.swift
// NoodleKit
//
// Created by NoodleOfDeath on 7/10/16.
// Copyright © 2016 NoodleOfDeath. All rights reserved.
//
import Foundation
// Bit Shifting only supports lhs = 1
#warn_unused_result
public func << (lhs: UInt256, rhs: UInt256) -> UInt256 {
if lhs > 1 { print("Warning: Only supports binary bitshifts (i.e. 1 << n, where n < 256. Shifting any other numbers than 1 may result in unexpected behavior.") }
if rhs > 255 { fatalError("shift amount is larger than type size in bits") }
let shift = UInt64(rhs.parts[7]) % 32
let offset = Int(rhs.parts[7] / 32)
var parts = [UInt32]()
for i in (0 ..< 8) {
let part: UInt64 = (i + offset < 8 ? UInt64(lhs.parts[i + offset]) : 0)
let sum32 = UInt32(part << shift)
parts.append(sum32)
}
return UInt256(parts)
}
#warn_unused_result
public func >> (lhs: UInt256, rhs: UInt256) -> UInt256 {
if lhs > 1 { print("Warning: Only supports binary bitshifts (i.e. 1 << n, where n < 256. Shifting any other numbers than 1 may result in unexpected behavior.") }
if rhs > 255 { fatalError("shift amount is larger than type size in bits") }
let shift = UInt64(rhs.parts[7]) % 32
let offset = Int(rhs.parts[7] / 32)
var parts = [UInt32]()
for i in (0 ..< 8) {
let part: UInt64 = (i - offset > 0 ? UInt64(lhs.parts[i - offset]) : 0)
let sum32 = UInt32(part >> shift)
parts.append(sum32)
}
return UInt256(parts)
}
#warn_unused_result
public func == (lhs: UInt256, rhs: UInt256) -> Bool {
return lhs.parts == rhs.parts
}
#warn_unused_result
public func < (lhs: UInt256, rhs: UInt256) -> Bool {
for i in 0 ..< 8 {
guard lhs.parts[i] < rhs.parts[i] else { continue }
return true
}
return false
}
#warn_unused_result
public func > (lhs: UInt256, rhs: UInt256) -> Bool {
for i in 0 ..< 8 {
guard lhs.parts[i] > rhs.parts[i] else { continue }
return true
}
return false
}
#warn_unused_result
public func <= (lhs: UInt256, rhs: UInt256) -> Bool {
return lhs < rhs || lhs == rhs
}
#warn_unused_result
public func >= (lhs: UInt256, rhs: UInt256) -> Bool {
return lhs > rhs || lhs == rhs
}
/// Adds `lhs` and `rhs`, returning the result and trapping in case of
/// arithmetic overflow (except in -Ounchecked builds).
#warn_unused_result
public func + (lhs: UInt256, rhs: UInt256) -> UInt256 {
var parts = [UInt32]()
var carry = false
for i in (0 ..< 8).reverse() {
let lpart = UInt64(lhs.parts[i])
let rpart = UInt64(rhs.parts[i])
let comp = lpart == UInt64(UInt32.max) && rpart == UInt64(UInt32.max)
let sum64 = lpart + rpart + (carry || comp ? 1 : 0)
let sum32 = UInt32((sum64 << 32) >> 32)
carry = sum64 > UInt64(UInt32.max)
parts.insert(sum32, atIndex: 0)
}
return UInt256(parts)
}
/// Adds `lhs` and `rhs`, returning the result and trapping in case of
/// arithmetic overflow (except in -Ounchecked builds).
public func += (inout lhs: UInt256, rhs: UInt256) {
lhs = lhs + rhs
}
/// Subtracts `lhs` and `rhs`, returning the result and trapping in case of
/// arithmetic overflow (except in -Ounchecked builds).
#warn_unused_result
public func - (lhs: UInt256, rhs: UInt256) -> UInt256 {
var parts = [UInt32]()
var borrow = false
var gave = false
for i in (0 ..< 8).reverse() {
borrow = lhs.parts[i] < rhs.parts[i]
let lpart = UInt64(lhs.parts[i]) - (gave ? 1 : 0) + (borrow ? UInt64(UInt32.max) : 0)
let rpart = UInt64(rhs.parts[i])
let sum64 = lpart - rpart
let sum32 = UInt32((sum64 << 32) >> 32)
gave = borrow
parts.insert(sum32, atIndex: 0)
}
return UInt256(parts)
}
public func -= (inout lhs: UInt256, rhs: UInt256) {
lhs = lhs - rhs
}
/// Multiplies `lhs` and `rhs`, returning the result and trapping in case of
/// arithmetic overflow (except in -Ounchecked builds).
/// - Complexity: O(64)
#warn_unused_result
public func * (lhs: UInt256, rhs: UInt256) -> UInt256 {
// TODO: - Not Implemented
return UInt256()
}
public func *= (inout lhs: UInt256, rhs: UInt256) {
lhs = lhs * rhs
}
/// Divides `lhs` and `rhs`, returning the result and trapping in case of
/// arithmetic overflow (except in -Ounchecked builds).
#warn_unused_result
public func / (lhs: UInt256, rhs: UInt256) -> UInt256 {
// TODO: - Not Implemented
return UInt256()
}
public func /= (inout lhs: UInt256, rhs: UInt256) {
lhs = lhs / rhs
}
/// Divides `lhs` and `rhs`, returning the remainder and trapping in case of
/// arithmetic overflow (except in -Ounchecked builds).
#warn_unused_result
public func % (lhs: UInt256, rhs: UInt256) -> UInt256 {
// TODO: - Not Implemented
return UInt256()
}
public func %= (inout lhs: UInt256, rhs: UInt256) {
lhs = lhs % rhs
}
public extension UInt256 {
#warn_unused_result
public func toIntMax() -> IntMax {
return Int64(parts[6] << 32) + Int64(parts[7])
}
#warn_unused_result
public func toUIntMax() -> UIntMax {
return UInt64(parts[6] << 32) + UInt64(parts[7])
}
/// Adds `lhs` and `rhs`, returning the result and a `Bool` that is
/// `true` iff the operation caused an arithmetic overflow.
public static func addWithOverflow(lhs: UInt256, _ rhs: UInt256) -> (UInt256, overflow: Bool) {
var parts = [UInt32]()
var carry = false
for i in (0 ..< 8).reverse() {
let lpart = UInt64(lhs.parts[i])
let rpart = UInt64(rhs.parts[i])
let comp = lpart == UInt64(UInt32.max) && rpart == UInt64(UInt32.max)
let sum64 = lpart + rpart + (carry || comp ? 1 : 0)
let sum32 = UInt32((sum64 << 32) >> 32)
carry = sum64 > UInt64(UInt32.max)
parts.insert(sum32, atIndex: 0)
}
return (UInt256(parts), parts[0] > 0x8fffffff)
}
/// Subtracts `lhs` and `rhs`, returning the result and a `Bool` that is
/// `true` iff the operation caused an arithmetic overflow.
public static func subtractWithOverflow(lhs: UInt256, _ rhs: UInt256) -> (UInt256, overflow: Bool) {
// TODO: -
var parts = [UInt32]()
var borrow = false
var gave = false
for i in (0 ..< 8).reverse() {
borrow = lhs.parts[i] < rhs.parts[i]
let lpart = UInt64(lhs.parts[i]) - (gave ? 1 : 0) + (borrow ? UInt64(UInt32.max) : 0)
let rpart = UInt64(rhs.parts[i])
let sum64 = lpart - rpart
let sum32 = UInt32((sum64 << 32) >> 32)
gave = borrow
parts.insert(sum32, atIndex: 0)
}
return (UInt256(parts), parts[0] > 0x8fffffff)
}
/// Multiplies `lhs` and `rhs`, returning the result and a `Bool` that is
/// `true` iff the operation caused an arithmetic overflow.
public static func multiplyWithOverflow(lhs: UInt256, _ rhs: UInt256) -> (UInt256, overflow: Bool) {
// TODO: - Not Implemented
return (UInt256(), false)
}
/// Divides `lhs` and `rhs`, returning the result and a `Bool` that is
/// `true` iff the operation caused an arithmetic overflow.
public static func divideWithOverflow(lhs: UInt256, _ rhs: UInt256) -> (UInt256, overflow: Bool) {
// TODO: - Not Implemented
return (UInt256(), false)
}
/// Divides `lhs` and `rhs`, returning the remainder and a `Bool` that is
/// `true` iff the operation caused an arithmetic overflow.
public static func remainderWithOverflow(lhs: UInt256, _ rhs: UInt256) -> (UInt256, overflow: Bool) {
// TODO: - Not Implemented
return (UInt256(), false)
}
}
public struct UInt256 : UnsignedIntegerType, Comparable, Equatable {
public typealias IntegerLiteralType = UInt256
public typealias Distance = Int32
public typealias Stride = Int32
private let parts: [UInt32]
private var part0: UInt32 { return parts[0] }
private var part1: UInt32 { return parts[1] }
private var part2: UInt32 { return parts[2] }
private var part3: UInt32 { return parts[3] }
private var part4: UInt32 { return parts[4] }
private var part5: UInt32 { return parts[5] }
private var part6: UInt32 { return parts[6] }
private var part7: UInt32 { return parts[7] }
public static var max: UInt256 {
return UInt256([.max, .max, .max, .max, .max, .max, .max, .max])
}
public var description: String {
var hex = "0x"
for i in 0 ..< parts.count {
let part = parts[i]
hex += String(format:"%08X", part)
if i + 1 < parts.count {
hex += ":"
}
}
return "\(hex)"
}
public var componentDescription: String {
return "\(parts)"
}
public var hashValue: Int {
return (part0.hashValue + part1.hashValue + part2.hashValue + part3.hashValue + part4.hashValue + part5.hashValue + part6.hashValue + part7.hashValue).hashValue
}
public var data: NSData {
let bytes = [part0, part1, part2, part3, part4, part5, part6, part7]
return NSData(bytes: bytes, length: 32)
}
public init(_builtinIntegerLiteral builtinIntegerLiteral: _MaxBuiltinIntegerType) {
self.init(UInt64(_builtinIntegerLiteral: builtinIntegerLiteral))
}
public init() { parts = [0, 0, 0, 0, 0, 0, 0, 0] }
public init(_ newParts: [UInt32]) {
var zeros = UInt256().parts
zeros.replaceRange((8 - newParts.count ..< 8), with: newParts)
parts = zeros
}
public init(_ v: Int8) {
self.init(UInt64(v))
}
public init(_ v: UInt8) {
self.init(UInt64(v))
}
public init(_ v: Int16) {
self.init(UInt64(v))
}
public init(_ v: UInt16) {
self.init(UInt64(v))
}
public init(_ v: Int32) {
self.init(UInt64(v))
}
public init(_ v: UInt32) {
self.init(UInt64(v))
}
public init(_ v: Int) {
self.init(UInt64(v))
}
public init(_ v: UInt) {
self.init(UInt64(v))
}
public init(_ v: Int64) {
self.init(UInt64(v))
}
public init(_ v: UInt64) {
self.init([UInt32(v >> 32), UInt32((v << 32) >> 32)])
}
public init(integerLiteral value: IntegerLiteralType) {
parts = value.parts
}
public init?(data: NSData) {
var parts = [UInt32]()
let size = sizeof(UInt32)
for i in 0 ..< 8 {
var part = UInt32()
data.getBytes(&part, range: NSMakeRange(i * size, size))
parts.append(part)
}
guard parts.count == 8 else { return nil }
self.init(parts)
}
#warn_unused_result
public func advancedBy(n: Stride) -> UInt256 {
return self + UInt256(n)
}
#warn_unused_result
public func advancedBy(n: Distance, limit: UInt256) -> UInt256 {
return limit - UInt256(n) > self ? self + UInt256(n) : limit
}
#warn_unused_result
public func distanceTo(end: UInt256) -> Distance {
return end - self
}
/// Returns the previous consecutive value in a discrete sequence.
///
/// If `UInt256` has a well-defined successor,
/// `UInt256.successor().predecessor() == UInt256`. If `UInt256` has a
/// well-defined predecessor, `UInt256.predecessor().successor() ==
/// UInt256`.
///
/// - Requires: `UInt256` has a well-defined predecessor.
#warn_unused_result
public func predecessor() -> UInt256 {
return advancedBy(-1)
}
#warn_unused_result
public func successor() -> UInt256 {
return advancedBy(1)
}
}
extension UInt256 : BitwiseOperationsType {}
/// Returns the intersection of bits set in `lhs` and `rhs`.
///
/// - Complexity: O(1).
#warn_unused_result
public func & (lhs: UInt256, rhs: UInt256) -> UInt256 {
var parts = [UInt32]()
for i in 0 ..< 8 {
parts.append(lhs.parts[i] & rhs.parts[i])
}
return UInt256(parts)
}
/// Returns the union of bits set in `lhs` and `rhs`.
///
/// - Complexity: O(1).
#warn_unused_result
public func | (lhs: UInt256, rhs: UInt256) -> UInt256 {
var parts = [UInt32]()
for i in 0 ..< 8 {
parts.append(lhs.parts[i] | rhs.parts[i])
}
return UInt256(parts)
}
/// Returns the bits that are set in exactly one of `lhs` and `rhs`.
///
/// - Complexity: O(1).
#warn_unused_result
public func ^ (lhs: UInt256, rhs: UInt256) -> UInt256 {
var parts = [UInt32]()
for i in 0 ..< 8 {
parts.append(lhs.parts[i] ^ rhs.parts[i])
}
return UInt256(parts)
}
/// Returns `x ^ ~UInt256.allZeros`.
///
/// - Complexity: O(1).
#warn_unused_result
prefix public func ~ (x: UInt256) -> UInt256 {
return x ^ ~UInt256.allZeros
}
public extension UInt256 {
public static var allZeros: UInt256 {
return UInt256()
}
}
public extension NSCoder {
public func encodeUInt256(unsignedInteger: UInt256, forKey key: String) {
encodeObject(unsignedInteger.data, forKey: key)
}
public func decodeUInt256ForKey(key: String) -> UInt256 {
guard let data = decodeObjectForKey(key) as? NSData else { return UInt256() }
return UInt256(data: data) ?? UInt256()
}
}
Disclaimer: I never tried
I suppose you can build your own Int128.
E.g. this library defined a UInt256 type.
Once you have your new type you can simply use it with OptionSetType I guess.
struct YourOptions : OptionSetType{
let rawValue : Int128
init(rawValue:Int128) {
self.rawValue = rawValue
}
}

Ternary operator in Swift Error

Why does this code gives error(Swift 2.2) :
Expected Expresion
at return line
func == (lhs: Employee, rhs: Employee) -> Int {
return (lhs.empName == rhs.empName && lhs.empCode == rhs.empCode)?1:0
}
There's no need to use the ternary operator here — x ? true : false is exactly the same as x. I'd write:
func ==(lhs: Employee, rhs: Employee) -> Bool {
return lhs.empName == rhs.empName && lhs.empCode == rhs.empCode
}
Silly. There has to be a space between the BOOL being checked upon and the ?
So flag?expressionA:expressionB won't work.
Instead flag ?expressionA:expressionB will work.
Maybe compiler assumes flag? as optional chaining.
This works
func == (lhs: Employee, rhs: Employee) -> Int {
return (lhs.empName == rhs.empName && lhs.empCode == rhs.empCode) ?1:0
}

Compare Day/Month in Swift Struct

I would like sort an array of SpecialDay instances: [struct1, struct2, struct3, ...] using the code below:
struct SpecialDay: Hashable, Comparable {
var day: Int
var month: Int
var hashValue: Int {
return (31 &* day.hashValue &+ month.hashValue)
}
}
func ==(lhs: SpecialDay, rhs: SpecialDay) -> Bool {
return lhs.day == rhs.day && lhs.month == rhs.month
}
func <(lhs: SpecialDay, rhs: SpecialDay) -> Bool {
return lhs.day < rhs.day && lhs.month <= rhs.month
}
Sorting would be done like this:
let newArray = currentArray.sorted({ $0 < $1 })
I think I only need to find the right logic behind the comparable method:
func <(lhs: SpecialDay, rhs: SpecialDay) -> Bool
... but I am pulling my teeth on this one. My currently implemented logic is obviously not sorting correctly.
Any hints would be greatly appreciated.
The problem is the and in this line:
return lhs.day < rhs.day && lhs.month <= rhs.month
If the lhs month is less than the rhs it should always return true not taking into account the day. However, when you and with the comparison to days, you can get a false for the days not being less and a true for the months, which results in a false. You need something just a little more complicated:
func <(lhs: SpecialDay, rhs: SpecialDay) -> Bool {
if lhs.month < rhs.month { return true }
else if lhs.month > rhs.month { return false }
else {
return lhs.day < rhs.day
}
}