public static ValueGetter <VBuffer <Single> > GetLabelGetter(SlotCursor cursor)
        {
            var type = cursor.GetSlotType().ItemType;

            if (type == NumberType.R4)
            {
                return(cursor.GetGetter <Single>());
            }
            if (type == NumberType.R8 || type.IsBool)
            {
                return(GetVecGetterAs <Single>(NumberType.R4, cursor));
            }
            Contracts.Check(type.IsKey, "Only floating point number, boolean, and key type values can be used as label.");
            Contracts.Assert(TestGetLabelGetter(type) == null);
            ulong keyMax = (ulong)type.KeyCount;

            if (keyMax == 0)
            {
                keyMax = ulong.MaxValue;
            }
            var             getSrc = RowCursorUtils.GetVecGetterAs <ulong>(NumberType.U8, cursor);
            VBuffer <ulong> src    = default(VBuffer <ulong>);

            return
                ((ref VBuffer <Single> dst) =>
            {
                getSrc(ref src);
                // Unfortunately defaults in one to not translate to defaults of the other,
                // so this will not be sparsity preserving. Assume a dense output.
                var editor = VBufferEditor.Create(ref dst, src.Length);
                foreach (var kv in src.Items(all: true))
                {
                    if (0 < kv.Value && kv.Value <= keyMax)
                    {
                        editor.Values[kv.Key] = kv.Value - 1;
                    }
                    else
                    {
                        editor.Values[kv.Key] = Single.NaN;
                    }
                }
                dst = editor.Commit();
            });
        }