At compile time, I need to allocate memory by declaring up to three separate arrays, each allocated separately from three equally sized memory banks. Starting from the first bank, the array is declared up to the maximum bank size. The remainder memory is allocated from the next bank and so on. The banks are not adjacent in memory.
As an example, assume we need to allocate 2.5K of memory, each bank has a maximum size of 1K. We allocate 1K in Bank 1, another 1K in Bank 2, and with the remaining 500 bytes in Bank 3:
std::array<uint8_t, 1000> bank1; // 1K
std::array<uint8_t, 1000> bank2; // 1K
std::array<uint8_t, 500> bank3; // 500 bytes
If there's no memory left to allocate in the subsequent banks, it doesn't declare an array. If there is, it just fails.
So far, I am having difficulty generating the declarations and the branching.
// Define the maximum bank size (1K in this example)
constexpr std::size_t MaxBankSize = 1000;
// Helper function to calculate the remainder size
template <std::size_t MemSize, std::size_t BankSize>
constexpr std::size_t CalculateRemainder() {
return (MemSize > BankSize) ? (MemSize - BankSize) : 0;
}
// Bank1: Allocate up to MaxBankSize
template <std::size_t MemSize>
using Bank1 = std::enable_if_t<(MemSize <= MaxBankSize), std::array<uint8_t, MemSize>>;
// Bank2: Allocate from Bank1 and calculate remainder
template <std::size_t MemSize>
using Bank2 = std::conditional_t<(MemSize > MaxBankSize),
Bank1<MaxBankSize>,
Bank1<MemSize>>;
// Bank3: Allocate from Bank2 and calculate remainder
template <std::size_t MemSize>
using Bank3 = std::conditional_t<(MemSize > MaxBankSize * 2),
Bank2<MaxBankSize>,
Bank2<MemSize>>;
This answer gets the correct size for each bank, but does not cause an empty bank to vanish due to SFINAE. When a bank is empty, it is still declared, but with a size of zero.
All tests were made with
MaxBankSizeset to1000.Although the arrays can be declared with "global" (i.e., file-level or namespace) scope, for the tests here, they are given "local" (i.e., block) scope.
Note: when the arrays are local, you can use
N_Banks<MemSize>with constexpr-if to prevent the unwanted banks from being declared.Output: