#pragma once
#include <iomanip>
#include <iostream>
#include "cpp-pair.hpp"

template<typename T> void print(std::ostream& out, const T& x) { out << x; }

template<> void print<bool>(std::ostream& out, const bool& x) { out << (x ? "true" : "false"); }

template<> void print<char>(std::ostream& out, const char& x ) {
	if ( 0x20 <= x && x <= 0x7E ) { out << "'" << x << "'"; }
	else { out << "'\\" << std::hex << (unsigned int)x << std::setbase(0) << "'"; }
}

template<typename R, typename S> 
std::ostream& operator<< (std::ostream& out, const pair<R, S>& x) {
	out << "[";
	print(out, x.first);
	out << ", ";
	print(out, x.second);
	return out << "]";
}

template<typename T, typename... Args> 
void print(std::ostream& out, const T& arg, const Args&... rest) {
	out << arg;
	print(out, rest...);
}
