docs: def crossover(cross):
      """Return an inspyred crossover function based on the given function.
  
      This function generator takes a function that operates on only
      two parent candidates to produce an iterable sequence of offspring
      (typically two). The generator handles the pairing of selected
      parents and collecting of all offspring.
  
      The generated function chooses every odd candidate as a 'mom' and
      every even as a 'dad' (discounting the last candidate if there is
      an odd number). For each mom-dad pair, offspring are produced via
      the `cross` function.
  
      The given function ``cross`` must have the following signature::
  
          offspring = cross(random, mom, dad, args)
  
      This function is most commonly used as a function decorator with
      the following usage::
  
          @crossover
          def cross(random, mom, dad, args):
              # Implementation of paired crossing
              pass
  
      The generated function also contains an attribute named
      ``single_crossover`` which holds the original crossover function.
      In this way, the original single-set-of-parents function can be
      retrieved if necessary.
  
      """
      @functools.wraps(cross)
      def inspyred_crossover(random, candidates, args):
          if len(candidates) % 2 == 1:
              candidates = candidates[:-1]
          moms = candidates[::2]
          dads = candidates[1::2]
          children = []
          for i, (mom, dad) in enumerate(zip(moms, dads)):
              cross.index = i
              offspring = cross(random, mom, dad, args)
              for o in offspring:
                  children.append(o)
          return children
      inspyred_crossover.single_crossover = cross
      return inspyred_crossover