Refactor of GWF I/O utility code
This PR introduces a re-factoring of a bunch of code, mainly moving functions from gwpy.timeseries.io.gwf.framecpp into gwpy.io.framecpp and the new gwpy.io._framecpp module.
In order to reduce duplication, there is a new gwpy.utils.enum module that provides a common parent class for enums that reference numpy types, and is now used by gwpy.io.nds2.Nds2DataType and gwpy.io._framecpp.FrVectType.
This change should present exactly zero functional changes to the code for 99.9% of cases, technically the API to TimeSeries{Dict}.write has changed when format='gwf' is given, but I suspect that nobody has ever attempted to use the (undocumented) keywords that have changed.