Skip to content

Commit 1e7bb09

Browse files
authored
Add Metatype (#167)
1 parent 4ed133f commit 1e7bb09

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

Sources/DataStructures/Metatype.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// Metatype.swift
3+
// DataStructures
4+
//
5+
// Created by James Bean on 9/10/18.
6+
//
7+
8+
/// A wrapper around the metatype of any type.
9+
///
10+
/// This wrapper allows a metatype (`T.Type`, `String.self`, etc.) to conform to `Equatable` and
11+
/// `Hashable`. Therefore, a metatype can be used as a key in a dictionary.
12+
public struct Metatype {
13+
14+
/// The metatype wrapped-up herein.
15+
@usableFromInline
16+
let base: Any.Type
17+
18+
// MARK: - Initializers
19+
20+
/// Creates a `Metatype` with the given `base` metatype to wrap.
21+
@inlinable
22+
public init(_ base: Any.Type) {
23+
self.base = base
24+
}
25+
}
26+
27+
extension Metatype: Equatable {
28+
29+
// MARK: - Equatable
30+
31+
/// - Returns: `true` if the given metatypes wrapped up by the given `Metatype` values are
32+
/// equivalent. Otherwise, `false`.
33+
@inlinable
34+
public static func == (lhs: Metatype, rhs: Metatype) -> Bool {
35+
return lhs.base == rhs.base
36+
}
37+
}
38+
39+
extension Metatype: Hashable {
40+
41+
// MARK: - Hashable
42+
43+
/// - Returns: A unique hash value for the metatype wrapped-up herein.
44+
@inlinable
45+
public var hashValue: Int {
46+
return ObjectIdentifier(base).hashValue
47+
}
48+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// MetatypeTests.swift
3+
// DataStructuresTests
4+
//
5+
// Created by James Bean on 9/10/18.
6+
//
7+
8+
import XCTest
9+
import DataStructures
10+
11+
class MetatypeTests: XCTestCase {
12+
13+
func testInit() {
14+
let _ = Metatype(String.self)
15+
let _ = Metatype(Int.self)
16+
let _ = Metatype(type(of: 42.0))
17+
}
18+
19+
func testEquatable() {
20+
let a = Metatype(Int.self)
21+
let b = Metatype(type(of: 1))
22+
XCTAssertEqual(a,b)
23+
}
24+
25+
func testEquatableFalse() {
26+
let a = Metatype(String.self)
27+
let b = Metatype(type(of: 1))
28+
XCTAssertNotEqual(a,b)
29+
}
30+
31+
func testHashableEqual() {
32+
let a = Metatype(String.self)
33+
let b = Metatype(type(of: "test"))
34+
XCTAssertEqual(a.hashValue, b.hashValue)
35+
}
36+
37+
func testHashableNotEqual() {
38+
let a = Metatype(Int.self)
39+
let b = Metatype(type(of: "test"))
40+
XCTAssertNotEqual(a.hashValue, b.hashValue)
41+
}
42+
}

Tests/DataStructuresTests/XCTestManifests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,16 @@ extension MatrixTests {
202202
]
203203
}
204204

205+
extension MetatypeTests {
206+
static let __allTests = [
207+
("testEquatable", testEquatable),
208+
("testEquatableFalse", testEquatableFalse),
209+
("testHashableEqual", testHashableEqual),
210+
("testHashableNotEqual", testHashableNotEqual),
211+
("testInit", testInit),
212+
]
213+
}
214+
205215
extension MutableGraphTests {
206216
static let __allTests = [
207217
("testBidirectionalRelationshipIsTwoDirectedRelationships", testBidirectionalRelationshipIsTwoDirectedRelationships),
@@ -490,6 +500,7 @@ public func __allTests() -> [XCTestCaseEntry] {
490500
testCase(InvertibleEnumTests.__allTests),
491501
testCase(LinkedListTests.__allTests),
492502
testCase(MatrixTests.__allTests),
503+
testCase(MetatypeTests.__allTests),
493504
testCase(MutableGraphTests.__allTests),
494505
testCase(NewTypeTests.__allTests),
495506
testCase(OrderedDictionaryTests.__allTests),

0 commit comments

Comments
 (0)