Sometimes viewing the binary representation of an integer is nice.
The resulting small utility per my recent desire for such a thing is as follows:
#include <cstdint>
#include <iosfwd>
#include <limits>
#include <type_traits>
template <typename T>
class print_binary_helper
{
public:
static_assert(std::is_integral<T>::value,
"Cannot print non-integer in binary.");
template <typename U>
friend print_binary_helper<U> print_binary(const U value);
template <typename U>
friend std::ostream& operator<<(std::ostream& sink,
const print_binary_helper<U> source);
template <typename U>
friend std::wostream& operator<<(std::wostream& sink,
const print_binary_helper<U> source);
private:
explicit print_binary_helper(T value) :
mValue(value)
{}
template <typename Sink, typename Char>
Sink& do_print(Sink& sink, Char on, Char off) const
{
for (auto mask = T(1) << (std::numeric_limits<T>::digits - 1);
mask != 0; mask >>= 1)
{
const auto isOn = (mValue & mask) != 0;
sink << (isOn ? on : off);
}
return sink;
}
T mValue;
};
template <typename T>
std::ostream& operator<<(std::ostream& sink,
const print_binary_helper<T> source)
{
return source.do_print(sink, '1', '0');
}
template <typename T>
std::wostream& operator<<(std::wostream& sink,
const print_binary_helper<T> source)
{
return source.do_print(sink, L'1', L'0');
}
template <typename T>
print_binary_helper<T> print_binary(T value)
{
return print_binary_helper<T>(value);
}
And a small example:
#include <iostream>
int main()
{
std::cout << print_binary(0) << std::endl;
std::cout << print_binary(111605) << std::endl;
std::cout << print_binary(static_cast<unsigned long long>(-1) - 1) << std::endl;
}
Output:
0000000000000000000000000000000
0000000000000011011001111110101
1111111111111111111111111111111111111111111111111111111111111110