Parametrize iterators based on applicable(length, it.xs)

* Some iterators wrap other iterators, and the wrapped iterable
  may or may not have a defined length.  This PR parametrizes
  the relevant iterator types based on whether or not length
  is defined for the wrapped iterable, and defines length(itr)
  only when the wrapped array also has a length.

  This is most useful for collect(itr), which preallocates an output
  array if length is defined, or grows the output array otherwise.