I suppose this is more of a design question. Forgive me if this is not in the right place. Say I have a class that represents the total RAM
of a system, separated into banks:
template <uint16_t bank_sz>
class Ram
{
constexpr static auto BANK_SIZE = bank_sz;
using Bank = std::array<uint8_t, BANK_SIZE>;
public:
uint8_t read(uint8_t bank, uint16_t adr) const;
void write(uint8_t b, uint8_t bank, uint16_t adr);
void dump(std::ostream &os) const;
private:
std::vector<Bank> data_ {};
};
The template is there so the user can specify the size of the banks, as the system in question can have varying sizes of RAM banks. But, I feel this may be confusing to the user and violates the Principle of Least Surprise, as one would expect the template argument to specify the size of total RAM, not the size of the RAM bank:
Ram<0x2000> work_ram; // 4 KB total of work RAM? (no, 4 KB per bank)
Total RAM is not known until runtime, only the size of the banks is known. What would be a solution to this?
You could make the Bank
typedef a freestanding template, and then have the Ram
template take a Bank
as its template parameter. i.e.:
template <uint16_t SIZE>
using RamBank = std::array<uint8_t, SIZE>;
template <typename Bank>
class Ram
{
public:
//...
private:
std::vector<Bank> data_;
};
And then use it as
Ram<RamBank<0x2000>> work_ram;
This makes it pretty clear to me that work_ram
is a collection of 2KB banks.