Generate methods for flattening the results of many joins

Here's what the code-gen based solution to #1096 looks like (I'm fine with using a macro instead, but I just wanted to see how hard this would be and it was pretty straightforward).

works for both the result of left/right joins:
```
scala> ((("hi", 12.8), Seq(1,2,3)), 17).flatten
res1: (String, Double, Seq[Int], Int) = (hi,12.8,List(1, 2, 3),17)
```

And for the result of outer joins:
```
scala> type crazy = (Option[(Option[(Option[(Option[Int], Option[String])], Option[Long])], Option[Double])], Option[Seq[Int]])
defined type alias crazy

scala> val x: crazy = (Some(Some(Some(Some(7), Some("hello")), Some(1000L)), Some(12.3)), Some(Seq(1,2,3)))
x: (Option[(Option[(Option[(Option[Int], Option[String])], Option[Long])], Option[Double])], Option[Seq[Int]]) = (Some((Some((Some((Some(7),Some(hello))),Some(1000))),Some(12.3))),Some(List(1, 2, 3)))

scala> x.flatten
res0: (Option[Int], Option[String], Option[Long], Option[Double], Option[Seq[Int]]) = (Some(7),Some(hello),Some(1000),Some(12.3),Some(List(1, 2, 3)))

scala> val y: crazy = (None, Some(Seq(1,2,3)))
y: (Option[(Option[(Option[(Option[Int], Option[String])], Option[Long])], Option[Double])], Option[Seq[Int]]) = (None,Some(List(1, 2, 3)))

scala> y.flatten
res1: (Option[Int], Option[String], Option[Long], Option[Double], Option[Seq[Int]]) = (None,None,None,None,Some(List(1, 2, 3)))

scala> val z: crazy = (Some(None, Some(12.3)), Some(Seq(1,2,3)))
z: (Option[(Option[(Option[(Option[Int], Option[String])], Option[Long])], Option[Double])], Option[Seq[Int]]) = (Some((None,Some(12.3))),Some(List(1, 2, 3)))

scala> z.flatten
res2: (Option[Int], Option[String], Option[Long], Option[Double], Option[Seq[Int]]) = (None,None,None,Some(12.3),Some(List(1, 2, 3)))
```

Doesn't have any tests yet, and the generator is a bit long.
I thought about that. 
It would work, though now you're making nested function calls, so it seems like it would be slightly more expensive.

The other option would be to short circuit after the first `.getOrElse` is triggered, but to do that is tricky.