Last active
July 30, 2021 21:08
-
-
Save kkebo/8c655297c9fafd42c36abfe4d4e557d0 to your computer and use it in GitHub Desktop.
Rust の Box 的なやつを Swift で (Box はヒープに置くことが目的、BoxObject は参照にすることが目的)
This file contains hidden or 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
@propertyWrapper | |
public struct Box<Value> { | |
private var object: BoxObject<Value> | |
public var value: Value { | |
get { self.object.value } | |
set { | |
if !isKnownUniquelyReferenced(&self.object) { | |
self.object = self.object.copy() | |
} | |
self.object.value = newValue | |
} | |
} | |
public var wrappedValue: Value { | |
get { self.value } | |
set { self.value = newValue } | |
} | |
public init(_ value: Value) { | |
self.object = .init(value) | |
} | |
public init(wrappedValue: Value) { | |
self.init(wrappedValue) | |
} | |
} | |
extension Box: TextOutputStreamable { | |
public func write<Target>(to target: inout Target) where Target: TextOutputStream { | |
print(self.value, terminator: "", to: &target) | |
} | |
} | |
extension Box: Equatable where Value: Equatable { | |
public static func == (lhs: Self, rhs: Self) -> Bool { | |
lhs.value == rhs.value | |
} | |
} | |
extension Box: Comparable where Value: Comparable { | |
public static func < (lhs: Self, rhs: Self) -> Bool { | |
lhs.value < rhs.value | |
} | |
} | |
extension Box: Hashable where Value: Hashable { | |
public func hash(into hasher: inout Hasher) { | |
hasher.combine(self.value) | |
} | |
} | |
extension Box: Error where Value: Error {} | |
extension Box: Encodable where Value: Encodable { | |
public func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(self.value) | |
} | |
} | |
extension Box: Decodable where Value: Decodable { | |
public init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
self.init(try container.decode(Value.self)) | |
} | |
} | |
extension Box: CustomStringConvertible where Value: CustomStringConvertible { | |
public var description: String { self.value.description } | |
} | |
extension Box: CustomDebugStringConvertible where Value: CustomDebugStringConvertible { | |
public var debugDescription: String { self.value.debugDescription } | |
} |
This file contains hidden or 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
public final class BoxObject<Value> { | |
public var value: Value | |
public init(_ value: Value) { self.value = value } | |
public func copy() -> Self { | |
.init(self.value) | |
} | |
} | |
extension BoxObject: TextOutputStreamable { | |
public func write<Target>(to target: inout Target) where Target: TextOutputStream { | |
print(self.value, terminator: "", to: &target) | |
} | |
} | |
extension BoxObject: Equatable where Value: Equatable { | |
public static func == (lhs: BoxObject, rhs: BoxObject) -> Bool { | |
lhs.value == rhs.value | |
} | |
} | |
extension BoxObject: Comparable where Value: Comparable { | |
public static func < (lhs: BoxObject, rhs: BoxObject) -> Bool { | |
lhs.value < rhs.value | |
} | |
} | |
extension BoxObject: Hashable where Value: Hashable { | |
public func hash(into hasher: inout Hasher) { | |
hasher.combine(self.value) | |
} | |
} | |
extension BoxObject: Error where Value: Error {} | |
extension BoxObject: Encodable where Value: Encodable { | |
public func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(self.value) | |
} | |
} | |
extension BoxObject: Decodable where Value: Decodable { | |
public convenience init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
self.init(try container.decode(Value.self)) | |
} | |
} | |
extension BoxObject: CustomStringConvertible where Value: CustomStringConvertible { | |
public var description: String { self.value.description } | |
} | |
extension BoxObject: CustomDebugStringConvertible where Value: CustomDebugStringConvertible { | |
public var debugDescription: String { self.value.debugDescription } | |
} |
This file contains hidden or 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
struct Piyo { | |
@Box var a: Int | |
var b: Box<Int> | |
var c: BoxObject<Int> | |
} | |
var piyo = Piyo(a: 3, b: .init(4), c: .init(9)) | |
print(piyo) | |
var a = piyo | |
a.a = 10 | |
a.b.value = 5 | |
a.c.value = 99 | |
print(piyo) | |
print(a) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment