#include <iostream>
#include <cstdint>
// -----
/*
* Hexadecimal number formatting helper.
*/
//#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <climits>
#include <type_traits>
namespace hex_out_helper {
const int HEX_DIGIT_BITS = 4; // One hex digit = 4 bits.
const int HEX_BASE_CHARS = 2; // For the "0x".
template<typename T> struct CharCheck {
typedef T type;
};
template<> struct CharCheck<signed char> {
typedef char type;
};
template<> struct CharCheck<unsigned char> {
typedef char type;
};
template<typename T> using CharChecker = typename CharCheck<T>::type;
} // namespace hex_out_helper
// Output a number in hexadecimal, with proper formatting based on its type.
template<typename T> std::string hex_out_s(T val) {
using namespace hex_out_helper;
std::stringstream sformatter;
sformatter << std::hex
<< std::internal
<< "0x"
<< std::setfill('0')
<< std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS))
<< (std::is_same<CharChecker<T>, char>::value ? static_cast<int>(val) : val);
return sformatter.str();
}
// -----
struct Addr {
uint32_t offset : 6;
uint32_t index : 10;
uint32_t tag : 16;
Addr(uint32_t addr);
operator uint32_t();
void output();
};
Addr::Addr(uint32_t addr)
: offset(addr & 0x3F),
index((addr & 0xFFC0) >> 6),
tag((addr & 0xFFFF0000) >> 16)
{}
Addr::operator uint32_t() {
return ((offset) | (index << 6) | (tag << 16));
}
void Addr::output() {
std::cout << std::dec
<< "Offset: " << offset << "\t\t(" << hex_out_s(offset) << ")\n"
<< "Index: " << index << " \t(" << hex_out_s(index << 6) << ")\n"
<< "Tag: " << tag << (tag > 999 ? "\t(" : "\t\t(")
<< hex_out_s(tag << 16) << ")\n";
}
int main() {
Addr addr = 0xFFFFFFFF;
addr.output();
std::cout << std::hex << hex_out_s(static_cast<uint32_t>(addr)) << std::endl;
std::cout << "And now, a couple changes...\n";
addr.offset = 0x1A;
addr.index = 0x32F;
addr.output();
std::cout << std::hex << hex_out_s(static_cast<uint32_t>(addr)) << std::endl;
std::cout << "Once more...\n";
addr = 0x12345678;
addr.output();
std::cout << std::hex << hex_out_s(static_cast<uint32_t>(addr)) << std::endl;
std::cout << "And finally...\n";
addr = 0x00000001;
addr.output();
std::cout << std::hex << hex_out_s(static_cast<uint32_t>(addr)) << std::endl;
}