Add analysis function apply ufunc and class IFunc

Added a new function apply_ufunc, which applies numpy universal functions to cubes, and class IFunc, which contains functions to apply to the data and units of cubes. Both provide interfaces to iris.analysis.maths._binary_op_common or iris.analysis.maths._math_op_common.
This is an updated version of the branch submitted in #1071, after lots of useful suggestions from @rhattersley and @cpelley.
Minor stylistic point here: you can write `if self.nin not in [1, 2]:` which makes the intent of the statement slightly more obvious.