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.
Why is this called `ws_data_func` and not just `data_func`?