23 template<
typename CharT,
typename Traits,
typename T>
33 template<
typename T,
typename CharT =
char,
typename Traits = std::
char_traits<CharT>>
34 std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)>
debug(
const T& s) {
45 template<
typename CharT,
typename Traits>
47 std::basic_ostream<CharT, Traits>& os,
48 const std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)>& f
58 template<
typename CharT,
typename Traits,
typename T>
65 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const T& s) {
74 template<
typename CharT,
typename Traits>
75 struct Debug<CharT, Traits, std::string> {
81 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::string& s) {
82 return os <<
"\"" << s <<
"\"";
90 template<
typename CharT,
typename Traits>
91 struct Debug<CharT, Traits, bool> {
97 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const bool& b) {
98 using std::operator
""s;
99 return os << (b ?
"true"s :
"false"s);
108 template<
typename CharT,
typename Traits,
typename T,
typename Alloc>
109 struct Debug<CharT, Traits, std::vector<T, Alloc>> {
115 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::vector<T, Alloc>& vector) {
118 for(
const T& item : vector) {
125 os << debug<T, CharT, Traits>(item);
139 template<
typename CharT,
typename Traits,
typename Key,
typename Value,
typename Comp,
typename Alloc>
140 struct Debug<CharT, Traits, std::map<Key, Value, Comp, Alloc>> {
146 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::map<Key, Value, Comp, Alloc>& map) {
149 for(
auto& [key, value] : map) {
156 os << debug<Key, CharT, Traits>(key) <<
": " << debug<Value, CharT, Traits>(value);
169 template<
typename CharT,
typename Traits,
typename T,
typename Comp,
typename Alloc>
170 struct Debug<CharT, Traits, std::set<T, Comp, Alloc>> {
176 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::set<T, Comp, Alloc>& set) {
179 for(
const T& item : set) {
186 os << debug<T, CharT, Traits>(item);
198 template<
typename CharT,
typename Traits,
typename T1,
typename T2>
199 struct Debug<CharT, Traits, std::pair<T1, T2>> {
205 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::pair<T1, T2>& p) {
206 return os <<
"(" << debug<T1, CharT, Traits>(p.first) <<
": " << debug<T2, CharT, Traits>(p.second) <<
")";
215 template<
typename CharT,
typename Traits,
typename ...TT>
216 struct Debug<CharT, Traits, std::tuple<TT...>> {
222 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::tuple<TT...>& tuple) {
224 print(os, tuple, std::index_sequence_for<TT...>{});
228 template<std::size_t... Is>
229 static void print(std::basic_ostream<CharT, Traits>& os,
const std::tuple<TT...>& t, std::index_sequence<Is...>) {
230 ((os << (Is == 0 ?
"" :
", ") << debug<TT, CharT, Traits>(std::get<Is>(t))), ...);
240 template<
typename CharT,
typename Traits,
typename T,
size_t N>
241 struct Debug<CharT, Traits, std::array<T, N>> {
247 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::array<T, N>& array) {
250 for(
const T& item : array) {
257 os << debug<T, CharT, Traits>(item);
268 template<
typename CharT,
typename Traits,
typename T>
269 struct Debug<CharT, Traits, std::optional<T>> {
275 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::optional<T>& opt) {
277 return os << debug<T, CharT, Traits>(*opt);
288 template<
typename CharT,
typename Traits,
typename T>
289 struct Debug<CharT, Traits, std::shared_ptr<T>> {
295 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::shared_ptr<T>& ptr) {
297 return os << ptr <<
"(" << debug<T, CharT, Traits>(*ptr) <<
")";
299 return os << ptr <<
"(empty)";
308 template<
typename CharT,
typename Traits,
typename T>
309 struct Debug<CharT, Traits, std::weak_ptr<T>> {
315 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::weak_ptr<T>& ptr) {
316 if(
auto s_ptr = ptr.lock()) {
317 return os << debug<std::shared_ptr<T>, CharT, Traits>(s_ptr);
319 return os <<
"(expired)";
327 template<
typename CharT,
typename Traits>
328 struct Debug<CharT, Traits, std::monostate> {
329 #pragma clang diagnostic push
330 #pragma clang diagnostic ignored "-Wunused-parameter"
336 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::monostate& m) {
339 #pragma clang diagnostic pop
348 template<
typename CharT,
typename Traits,
typename T,
typename C>
349 struct Debug<CharT, Traits, std::queue<T, C>> {
355 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::queue<T, C>& q) {
356 std::queue<T, C> qq = q;
366 os << debug<T, CharT, Traits>(qq.front());
379 template<
typename CharT,
typename Traits,
typename T,
typename Alloc>
380 struct Debug<CharT, Traits, std::deque<T, Alloc>> {
386 static std::basic_ostream<CharT, Traits>&
print(std::basic_ostream<CharT, Traits>& os,
const std::deque<T, Alloc>& d) {
389 for(
const T& item : d) {
396 os << debug<T, CharT, Traits>(item);
410 template<
typename T,
typename CharT =
char,
typename Trait = std::
char_traits<CharT>,
typename Alloc = std::allocator<CharT>>
411 std::basic_string<CharT, Trait, Alloc>
toString(
const T& s) {
412 std::basic_ostringstream<CharT, Trait, Alloc> ss;
424 template<
typename T,
typename CharT =
char,
typename Traits = std::
char_traits<CharT>>
425 std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)>
spaceNumber(
const T& k) {
426 return [k](std::basic_ostream<CharT, Traits>& os) -> std::basic_ostream<CharT, Traits>& {
434 v.push_back(n % 1000);
438 for(
size_t i = 0; i < v.size(); i++) {
443 os <<
" " << std::setfill(
'0') << std::setw(3);
445 os << v[v.size() - 1 - i];