#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <climits>
#include <type_traits>
#include <cstdint>
// -----
// First option, with `<< "0x"`.
namespace ZeroX {
namespace detail {
constexpr int HEX_DIGIT_BITS = 4;
template<typename T> struct is_char
: std::integral_constant<bool,
std::is_same<T, char>::value ||
std::is_same<T, signed char>::value ||
std::is_same<T, unsigned char>::value> {};
}
template<typename T>
std::string hex_out_s(T val) {
using namespace detail;
std::stringstream sformatter;
sformatter << std::hex
<< std::internal
<< "0x"
<< std::setfill('0')
<< std::setw(sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS)
<< (is_char<T>::value ? static_cast<int>(val) : val);
return sformatter.str();
}
} // ZeroX
// -----
// Second option, with `<< std::showbase`.
namespace ShowBase {
namespace detail {
constexpr int HEX_DIGIT_BITS = 4;
constexpr int HEX_BASE_CHARS = 2;
template<typename T> struct is_char
: std::integral_constant<bool,
std::is_same<T, char>::value ||
std::is_same<T, signed char>::value ||
std::is_same<T, unsigned char>::value> {};
}
template<typename T>
std::string hex_out_s(T val) {
using namespace detail;
std::stringstream sformatter;
sformatter << std::hex
<< std::internal
<< std::showbase
<< std::setfill('0')
<< std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
<< (is_char<T>::value ? static_cast<int>(val) : val);
return sformatter.str();
}
} // ShowBase
// -----
int main() {
uint32_t hexU32 = 0x0f;
int hexI = 0x3c;
unsigned short hexUS = 0x12;
char hexC = 0xf;
unsigned char hexUC = 0xa;
signed char hexSC = 0x3;
std::cout << std::left
<< std::setw(22) << "uint32_t:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(hexU32)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(hexU32)
<< std::setw(24) << "\n\nint:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(hexI)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(hexI)
<< std::setw(24) << "\n\nunsigned short:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(hexUS)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(hexUS)
<< std::setw(24) << "\n\nchar:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(hexC)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(hexC)
<< std::setw(24) << "\n\nunsigned char:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(hexUC)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(hexUC)
<< std::setw(24) << "\n\nsigned char:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(hexSC)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(hexSC)
<< std::setw(24) << "\n\nDecimal rvalues, too:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(29)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(29)
<< std::setw(24) << "\n\nA long long:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(LLONG_MAX)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(LLONG_MAX)
<< std::setw(24) << "\n\nAnd zero:"
<< std::setw(18) << "0x version: " << ZeroX::hex_out_s(0)
<< std::setw(23) << '\n'
<< std::setw(18) << "showbase version: " << ShowBase::hex_out_s(0)
<< "\n\n" << std::endl;
}