Casey
Casey

Reputation: 6701

Disambiguate Protocol Composition

is it possible to determine if a composed Any.Type contains a specific Any.Type?

(A & B).self contains A.self => true

(B & C).self contains A.self => false

Code Example

protocol A {}
protocol B {}
typealias AB = A & B

func conformsToA(_ type: Any.Type) -> Bool {
    return type == A.self
}

print(conformsToA(A.self))       // true
print(conformsToA(AB.self))      // false (but should be true)

i could add a specific clause for type == (A & B).self inside of conformsToA(_:), but this quickly becomes unmanageable. imagine if protocols C-Z are introduced and i tried to check something like:

conformsToA((A & C & E & Z).self)

Another Attempt Using Alistra's 2nd Approach

protocol A {}
protocol B {}
typealias AB = A & B
func conformsToA<T>(_ t1: T.Type) -> Bool {
    return T.self is A
}

print(conformsToA(A.self))       // false (but should be true)
print(conformsToA(AB.self))      // false (but should be true)

Upvotes: 2

Views: 238

Answers (1)

Alistra
Alistra

Reputation: 5195

Edit: as @Hamish said in the comment this is impossible.

There was a swift evolution proposal here that would fix it https://github.com/apple/swift-evolution/blob/91725ee83fa34c81942a634dcdfa9d2441fbd853/proposals/0126-refactor-metatypes-repurpose-t-dot-self-and-mirror.md#known-issues-of-metatypes

It didn't get into Swift 4 Stage 2.

You can use generics and is

protocol A {}
protocol B {}
protocol C {}
typealias AB = A & B
typealias ABC = A & B & C

func conformsTo<T>(_ object: Any, t: T.Type) -> Bool {
    return object.self is T
}

class CL : AB {}

print(conformsTo(CL(), t: A.self)) // true
print(conformsTo(CL(), t: AB.self)) // true
print(conformsTo(CL(), t: ABC.self)) // false

Or without instances of classes

protocol A {}
protocol B {}
protocol C {}
typealias AB = A & B
typealias ABC = A & B & C

func conformsTo<T, U>(_ t1: T.Type, t2: U.Type) -> Bool {
    return T.self is U.Type
}


print(conformsTo(ABC.self, t2: A.self)) // false
print(conformsTo(ABC.self, t2: AB.self)) // false
print(conformsTo(ABC.self, t2: ABC.self)) // true
print(conformsTo(AB.self, t2: A.self)) // false
print(conformsTo(AB.self, t2: AB.self)) // true
print(conformsTo(AB.self, t2: ABC.self)) // false
print(conformsTo(A.self, t2: A.self)) // true
print(conformsTo(A.self, t2: AB.self)) // false
print(conformsTo(A.self, t2: ABC.self)) // false

Upvotes: 2

Related Questions