#include <array>
#include <cstddef>
#include <iostream>
#include <stdexcept>
std::size_t translate(std::size_t address) {
    constexpr std::size_t page=4096;
    constexpr std::array<std::size_t,3> frames{5,7,2};
    if(address/page>=frames.size()) throw std::out_of_range("unmapped");
    return frames[address/page]*page+address%page;
}
int main() {
    if(translate(0)!=20480 || translate(4095)!=24575 || translate(4099)!=28675)
        throw std::runtime_error("translation");
    bool rejected=false;
    try {
        const auto unexpected=translate(12288);
        std::cout<<"unexpected unmapped address="<<unexpected<<'\n';
        return 1;
    } catch(const std::out_of_range&) { rejected=true; }
    if(!rejected) throw std::runtime_error("missing bounds");
    std::cout<<"4099->"<<translate(4099)<<" / 8192->"<<translate(8192)<<'\n';
}
