Created
November 7, 2016 20:00
-
-
Save erica/59e64778bf59877122b1c3ee79e118fa 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
/// Exponentiation operator | |
infix operator ** | |
extension IntegerArithmetic { | |
/// Returns base ^^ exp | |
/// - parameter base: the base value | |
/// - parameter exp: the exponentiation value | |
static func **(base: Self, exp: Int) -> Self { | |
return repeatElement(base, count: exp).reduce(1 as! Self, *) | |
} | |
} | |
public struct LaundryOptions: OptionSet, CustomStringConvertible { | |
public var rawValue: Int { return _rawValue } | |
public init(rawValue: Int) { self._rawValue = rawValue } | |
private let _rawValue: Int // not assignable publicly | |
/// Backing string-based flag enumeration | |
private enum LaundryFlags: String { | |
case lowWater, lowHeat, gentleCycle, tumbleDry | |
// Returns [hash: rawValue] dictionary | |
static var memberDict: Dictionary<Int, String> = [lowWater, lowHeat, gentleCycle, tumbleDry].reduce([:]) { | |
var dict = $0; dict[$1.hashValue] = "\($1)"; return dict | |
} | |
} | |
// Simple flags are built from built-shifted enumeration hash values | |
public static let lowWater = LaundryOptions(rawValue: 1 << LaundryFlags.lowWater.hashValue) | |
public static let lowHeat = LaundryOptions(rawValue: 1 << LaundryFlags.lowHeat.hashValue) | |
public static let gentleCycle = LaundryOptions(rawValue: 1 << LaundryFlags.gentleCycle.hashValue) | |
public static let tumbleDry = LaundryOptions(rawValue: 1 << LaundryFlags.tumbleDry.hashValue) | |
// Compound sets cannot be initialized with strings | |
// as their math cannot be established from positions | |
public static let energyStar: LaundryOptions = [.lowWater, .lowHeat] | |
public static let gentleStar: LaundryOptions = energyStar.union(gentleCycle) | |
// String based initialization | |
public init(strings: [String]) { | |
let set: LaundryOptions = strings | |
.flatMap({ LaundryFlags(rawValue: $0) }) // to enumeration | |
.map({ 1 << $0.hashValue }) // to Int, to flag | |
.flatMap({ LaundryOptions(rawValue: $0) }) // to option set | |
.reduce([]) { $0.union($1) } // joined | |
_rawValue = set.rawValue | |
} | |
/// returns set members as strings | |
public var description: String { | |
let members = LaundryFlags.memberDict.reduce([]) { | |
return (rawValue & 1 << $1.key) != 0 | |
? $0 + [$1.value] : $0 | |
} | |
return members.joined(separator: ", ") | |
} | |
} | |
let array = ["gentleCycle", "tumbleDry"] | |
let optionSet = LaundryOptions(strings: array) // gentleCycle, tumbleDry |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment