title: Is there a way to specify a generic function which only accepts one of two specific types?
body: <p>I have a few functions that are identical except for the fact that they handle two different types. I wish to keep my code more DRY so I would like to turn them into one function for two types. But how do I do that?</p>
  
  <p>I know how to create a generic function: <code>func doSomething&lt;T&gt;(arg: T) { ... }</code></p>
  
  <p>I also know how to create a generic function that only accepts objects of a certain protocol:</p>
  
  <p><code>func doSomething&lt;T: Event&gt;(arg: T) { ... }</code></p>
  
  <p>Now I've solved this little problem before when I wanted a function that would accept both Strings and objects that conform to the Event protocol. In that case I solved it quite easily by just making String conform to the Event protocol like so: <code>extension String: Event {}</code>. (Event is an empty protocol anyway)</p>
  
  <p>But this time the two types I'm dealing with are <code>String</code> and <code>Event.Type</code>. And in that case I can't use the same trick, because meta-types cannot be extended or be used to extend other types with.</p>
  
  <p>Is there a way to write something like this?</p>
  
  <p><code>func doSomething&lt;T where T == Event.Type || T == String&gt;(arg: T) { ... }</code></p>
  
  <h2>Edit, I'll explain more why I'm doing this:</h2>
  
  <p>I'm writing an event-dispatcher. Events can either be a string like "user.birthday" accompanied with a payload or an object that conforms to the Event protocol. I want to support both, because different developers have different preferences. So I can define events and listeners like so:</p>
  
  <pre><code>struct UserWonAward: Event {
      let user: User
  }
  
  events.listenTo("user.birthday") {
      (user: User) in
      print("Happy birthday \(user.name)!")
  }
  
  events.listenTo {
      (event: UserWonAward) in
      print("Congratulations \(event.user.name)!")
  }
  </code></pre>
  
  <p>And now here comes the thing I want help with. Sometimes I'll line up a few events in a queue and then later flush the queue of a specific type, like so:</p>
  
  <pre><code>let user1 = User(name: "John Doe")
  let user2 = User(name: "Jane Doe")
  
  events.queue("user.birthday", payload: user1)
  events.queue("user.birthday", payload: user2)
  
  events.queue(UserWonAward(user: user1))
  events.queue(UserWonAward(user: user2))
  
  // Some time later
  
  events.flushQueueOf("user.birthday")
  events.flushQueueOf(UserWonAward)
  </code></pre>
  
  <p>As you can see, in that <code>flushQueueOf()</code> method I can input either a <code>String</code> or an <code>Event.Type</code>. Right now I have written two separate methods for that, but the code in those two methods are nearly identical so I really want to merge them into one method.</p>