Optimize conversion of result and parameter values and provide fast paths

- Pull JdbcType and ResultConverter out of the driver cake for better reusability. The profile-specific Reader, Writer and Updater for ResultConverter are encapsulated in the new ResultConverterDomain.

- Use Scala specialization for JdbcType and remove Option types from the JdbcType interface, exposing primitive values and nullability through separate methods to avoid boxing.

- Provide manually specialized ResultConverters. The implementations for JDBC are also specialized accordingly.

- Fuse GetOrElseResultConverter(OptionResultConverter) to a single, specialized DefaultingResultConverter.

- Optimize ProductResultConverter.

- Encapsulate bidirectional mappings in TypeMapping and MappedScalaType in a new Mapper class which also holds a function for constructing an optional fast path converter.

- Make fast path converters easy to use with JdbcProfile with the JdbcFastPath result converter.

- Instead of PositionedResult and PositionedParameters, converters now use ResultSet and PreparedStatement directly. This allows access to arbitrary converters without having to use them all in the given order.

UnboxedBenchmark shows the performance of the new converters. Before this patch, reading 10 million rows from a dummy ResultSet with the non-fast-path mapped query q1 takes around 2000 ms. With the optimizations, that time is down to 670 ms. The fast path converter in q2 eliminates boxing and brings the time down to 180 ms. Reusing a single row object like in q3 takes 140 ms and avoids allocations entirely.

Review by @cvogt