mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Introduce a template for numeric coding.
This commit is contained in:
parent
bb6ceafe0e
commit
f6e601daff
64
Numeric/NumericCoder.hpp
Normal file
64
Numeric/NumericCoder.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// NumericCoder.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 17/01/2023.
|
||||
// Copyright © 2023 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef NumericCoder_hpp
|
||||
#define NumericCoder_hpp
|
||||
|
||||
namespace Numeric {
|
||||
|
||||
/// Stores and retrieves an arbitrary number of fields into an int with arbitrary modulos.
|
||||
///
|
||||
/// E.g. NumericEncoder<8, 3, 14> establishes an encoder and decoder for three fields,
|
||||
/// the first is modulo 8, the second is modulo 3, the third is modulo 14.
|
||||
///
|
||||
/// NumericEncoder<8, 3, 14>::encode<2>(v, 9) will mutate v so that the third field
|
||||
/// (i.e. field 2) has value 9.
|
||||
template <int... Sizes> class NumericCoder {
|
||||
public:
|
||||
/// Modifies @c target to hold @c value at @c index.
|
||||
template <int index> static void encode(int &target, int value) {
|
||||
static_assert(index < sizeof...(Sizes), "Index must be within range");
|
||||
NumericEncoderImp<Sizes...>::template encode<index, 0, 1>(target, value);
|
||||
}
|
||||
/// @returns The value from @c source at @c index.
|
||||
template <int index> static int decode(int source) {
|
||||
static_assert(index < sizeof...(Sizes), "Index must be within range");
|
||||
return NumericEncoderImp<Sizes...>::template decode<index, 0, 1>(source);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <int size, int... Tail>
|
||||
struct NumericEncoderImp {
|
||||
template <int index, int i, int divider> static void encode(int &target, int value) {
|
||||
if constexpr (i == index) {
|
||||
const int suffix = target % divider;
|
||||
target /= divider;
|
||||
target -= target % size;
|
||||
target += value % size;
|
||||
target *= divider;
|
||||
target += suffix;
|
||||
} else {
|
||||
NumericEncoderImp<Tail...>::template encode<index, i+1, divider*size>(target, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <int index, int i, int divider> static int decode(int source) {
|
||||
if constexpr (i == index) {
|
||||
return (source / divider) % size;
|
||||
} else {
|
||||
return NumericEncoderImp<Tail...>::template decode<index, i+1, divider*size>(source);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* NumericCoder_hpp */
|
@ -1430,6 +1430,7 @@
|
||||
4B643F3E1D77B88000D431D6 /* DocumentController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentController.swift; sourceTree = "<group>"; };
|
||||
4B644ED023F0FB55006C0CC5 /* ScanSynchroniser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanSynchroniser.hpp; sourceTree = "<group>"; };
|
||||
4B65085F22F4CF8D009C1100 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
|
||||
4B66E1A8297719270057ED0F /* NumericCoder.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = NumericCoder.hpp; sourceTree = "<group>"; };
|
||||
4B670A832401CB8400D4E002 /* z80memptr.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80memptr.tap; sourceTree = "<group>"; };
|
||||
4B670A852401CB8400D4E002 /* z80ccf.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80ccf.tap; sourceTree = "<group>"; };
|
||||
4B670A872401CB8400D4E002 /* z80flags.tap */ = {isa = PBXFileReference; lastKnownFileType = file; path = z80flags.tap; sourceTree = "<group>"; };
|
||||
@ -3304,6 +3305,7 @@
|
||||
4BD155312716362A00410C6E /* BitSpread.hpp */,
|
||||
4B7BA03E23D55E7900B98D9E /* CRC.hpp */,
|
||||
4B7BA03F23D55E7900B98D9E /* LFSR.hpp */,
|
||||
4B66E1A8297719270057ED0F /* NumericCoder.hpp */,
|
||||
4BB5B995281B1D3E00522DA9 /* RegisterSizes.hpp */,
|
||||
4BFEA2F12682A90200EBF94C /* Sizes.hpp */,
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user