-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathTagged.swift
179 lines (142 loc) · 4.72 KB
/
Tagged.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright 2018 Yandex LLC. All rights reserved.
public struct Tagged<Tag, RawValue>: RawRepresentable {
public var rawValue: RawValue
public init(rawValue: RawValue) {
self.rawValue = rawValue
}
}
extension Tagged: Sendable where RawValue: Sendable {}
public protocol NumericTag: Sendable {}
extension Tagged: Equatable where RawValue: Equatable {}
extension Tagged: Hashable where RawValue: Hashable {}
extension Tagged: Comparable where RawValue: Comparable {
@inlinable
public static func <(lhs: Tagged, rhs: Tagged) -> Bool {
lhs.rawValue < rhs.rawValue
}
}
extension Tagged: CustomStringConvertible {
public var description: String {
String(describing: rawValue)
}
}
extension Tagged: CustomDebugStringConvertible {
public var debugDescription: String {
String(reflecting: rawValue)
}
}
extension Tagged: Encodable where RawValue: Encodable {
public func encode(to encoder: Encoder) throws {
try rawValue.encode(to: encoder)
}
}
extension Tagged: Decodable where RawValue: Decodable {
public init(from decoder: Decoder) throws {
try self.init(rawValue: .init(from: decoder))
}
}
extension Tagged: ExpressibleByIntegerLiteral where RawValue: ExpressibleByIntegerLiteral {
public typealias IntegerLiteralType = RawValue.IntegerLiteralType
@inlinable
public init(integerLiteral value: IntegerLiteralType) {
self.init(rawValue: .init(integerLiteral: value))
}
}
extension Tagged: ExpressibleByFloatLiteral where RawValue: ExpressibleByFloatLiteral {
public typealias FloatLiteralType = RawValue.FloatLiteralType
@inlinable
public init(floatLiteral value: FloatLiteralType) {
self.init(rawValue: .init(floatLiteral: value))
}
}
extension Tagged: ExpressibleByBooleanLiteral where RawValue: ExpressibleByBooleanLiteral {
public typealias BooleanLiteralType = RawValue.BooleanLiteralType
@inlinable
public init(booleanLiteral value: BooleanLiteralType) {
self.init(rawValue: .init(booleanLiteral: value))
}
}
extension Tagged: ExpressibleByNilLiteral where RawValue: ExpressibleByNilLiteral {
public init(nilLiteral _: Void) {
self.init(rawValue: nil)
}
}
extension Tagged: ExpressibleByUnicodeScalarLiteral
where RawValue: ExpressibleByUnicodeScalarLiteral {
public typealias UnicodeScalarLiteralType = RawValue.UnicodeScalarLiteralType
@inlinable
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
self.init(rawValue: .init(unicodeScalarLiteral: value))
}
}
extension Tagged: ExpressibleByExtendedGraphemeClusterLiteral
where RawValue: ExpressibleByExtendedGraphemeClusterLiteral {
public typealias ExtendedGraphemeClusterLiteralType = RawValue.ExtendedGraphemeClusterLiteralType
@inlinable
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
self.init(rawValue: .init(extendedGraphemeClusterLiteral: value))
}
}
extension Tagged: ExpressibleByStringLiteral where RawValue: ExpressibleByStringLiteral {
public typealias StringLiteralType = RawValue.StringLiteralType
@inlinable
public init(stringLiteral value: StringLiteralType) {
self.init(rawValue: .init(stringLiteral: value))
}
}
extension Tagged {
@inlinable
public func cast<U>() -> Tagged<U, RawValue> {
Tagged<U, RawValue>(rawValue: rawValue)
}
@inlinable
public func cast() -> Tagged<Tag, RawValue> {
assertionFailure("You don't need to cast value to same type")
return self
}
}
// Conforming to ExpressibleByArrayLiteral & ExpressibleByDictionaryLiteral is impossible
// due to https://bugs.swift.org/browse/SR-128
extension Tagged: AdditiveArithmetic where Tag: NumericTag, RawValue: AdditiveArithmetic {
@inlinable
public static func +(lhs: Tagged, rhs: Tagged) -> Tagged {
.init(rawValue: lhs.rawValue + rhs.rawValue)
}
@inlinable
public static func +=(lhs: inout Tagged, rhs: Tagged) {
lhs = lhs + rhs
}
@inlinable
public static func -(lhs: Tagged, rhs: Tagged) -> Tagged {
.init(rawValue: lhs.rawValue - rhs.rawValue)
}
@inlinable
public static func -=(lhs: inout Tagged, rhs: Tagged) {
lhs = lhs - rhs
}
@inlinable
public static var zero: Tagged {
.init(rawValue: RawValue.zero)
}
}
extension Tagged: Numeric where Tag: NumericTag, RawValue: Numeric {
public typealias Magnitude = RawValue.Magnitude
@inlinable
public init?(exactly source: some BinaryInteger) {
guard let value = RawValue(exactly: source) else {
return nil
}
self.init(rawValue: value)
}
public var magnitude: Magnitude {
rawValue.magnitude
}
@inlinable
public static func *(lhs: Tagged, rhs: Tagged) -> Tagged {
.init(rawValue: lhs.rawValue * rhs.rawValue)
}
@inlinable
public static func *=(lhs: inout Tagged, rhs: Tagged) {
lhs = lhs * rhs
}
}