2017-04-26 02:50:03 +00:00
|
|
|
#pragma once
|
2017-02-14 19:14:34 +00:00
|
|
|
#include <iostream>
|
|
|
|
|
2017-12-20 16:42:18 +00:00
|
|
|
#include <array>
|
|
|
|
#include <chrono>
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include <memory>
|
|
|
|
#include <optional>
|
|
|
|
#include <ratio>
|
|
|
|
#include <set>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <unordered_set>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
2017-08-04 16:59:25 +00:00
|
|
|
// TODO: https://stackoverflow.com/questions/16464032/how-to-enhance-this-variable-dumping-debug-macro-to-be-variadic
|
|
|
|
#define DUMPS(VAR) #VAR " = " << VAR
|
|
|
|
#define DUMPHEAD std::cerr << __FILE__ << ":" << __LINE__ << " "
|
|
|
|
#define DUMP(V1) DUMPHEAD << DUMPS(V1) << "\n";
|
|
|
|
#define DUMP2(V1, V2) DUMPHEAD << DUMPS(V1) << ", " << DUMPS(V2) << "\n";
|
|
|
|
#define DUMP3(V1, V2, V3) DUMPHEAD << DUMPS(V1) << ", " << DUMPS(V2) << ", " << DUMPS(V3) << "\n";
|
|
|
|
#define DUMP4(V1, V2, V3, V4) DUMPHEAD << DUMPS(V1) << ", " << DUMPS(V2) << ", " << DUMPS(V3)<< ", " << DUMPS(V4) << "\n";
|
|
|
|
#define DUMP5(V1, V2, V3, V4, V5) DUMPHEAD << DUMPS(V1) << ", " << DUMPS(V2) << ", " << DUMPS(V3)<< ", " << DUMPS(V4) << ", " << DUMPS(V5) << "\n";
|
|
|
|
|
2017-03-23 19:38:17 +00:00
|
|
|
|
2017-12-20 16:42:18 +00:00
|
|
|
namespace std
|
|
|
|
{
|
2017-03-23 19:38:17 +00:00
|
|
|
|
|
|
|
template <typename K, typename V>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const pair<K, V> & what)
|
2017-03-23 19:38:17 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "pair{" << what.first << ", " << what.second << "}";
|
|
|
|
return stream;
|
2017-03-23 19:38:17 +00:00
|
|
|
}
|
|
|
|
|
2017-02-14 19:14:34 +00:00
|
|
|
template <typename T>
|
2017-12-20 16:42:18 +00:00
|
|
|
void dumpContainer(ostream & stream, const T & container)
|
2017-02-14 19:14:34 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "{";
|
|
|
|
bool first = true;
|
|
|
|
for (const auto & elem : container)
|
|
|
|
{
|
|
|
|
if (!first)
|
|
|
|
stream << ", ";
|
|
|
|
first = false;
|
|
|
|
stream << elem;
|
|
|
|
}
|
|
|
|
stream << "}";
|
2017-03-23 19:38:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const vector<T> & what)
|
2017-03-23 19:38:17 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "vector(size = " << what.size() << ", capacity = " << what.capacity() << ")";
|
|
|
|
dumpContainer(stream, what);
|
|
|
|
return stream;
|
2017-02-14 19:14:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, size_t N>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const array<T, N> & what)
|
2017-02-14 19:14:34 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "array<" << what.size() << ">";
|
|
|
|
dumpContainer(stream, what);
|
|
|
|
return stream;
|
2017-02-14 19:14:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename K, typename V>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const map<K, V> & what)
|
2017-02-14 19:14:34 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "map(size = " << what.size() << ")";
|
|
|
|
dumpContainer(stream, what);
|
|
|
|
return stream;
|
2017-02-14 19:14:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename K, typename V>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const unordered_map<K, V> & what)
|
2017-02-14 19:14:34 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "unordered_map(size = " << what.size() << ")";
|
|
|
|
dumpContainer(stream, what);
|
|
|
|
return stream;
|
2017-02-14 19:14:34 +00:00
|
|
|
}
|
|
|
|
|
2017-03-23 19:38:17 +00:00
|
|
|
template <typename K>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const set<K> & what)
|
2017-02-14 19:14:34 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "set(size = " << what.size() << ")";
|
|
|
|
dumpContainer(stream, what);
|
|
|
|
return stream;
|
2017-02-14 19:14:34 +00:00
|
|
|
}
|
|
|
|
|
2017-03-23 19:38:17 +00:00
|
|
|
template <typename K>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const unordered_set<K> & what)
|
2017-03-23 19:38:17 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "unordered_set(size = " << what.size() << ")";
|
|
|
|
dumpContainer(stream, what);
|
|
|
|
return stream;
|
2017-03-23 19:38:17 +00:00
|
|
|
}
|
|
|
|
|
2017-04-26 02:50:03 +00:00
|
|
|
template <typename K>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const list<K> & what)
|
2017-04-26 02:50:03 +00:00
|
|
|
{
|
|
|
|
stream << "list(size = " << what.size() << ")";
|
|
|
|
dumpContainer(stream, what);
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
2017-12-20 16:42:18 +00:00
|
|
|
template <intmax_t Num, intmax_t Denom>
|
|
|
|
ostream & operator<<(ostream & stream, [[maybe_unused]] const ratio<Num, Denom> & what)
|
2017-03-21 19:08:09 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "ratio<Num=" << Num << ", Denom=" << Denom << ">";
|
|
|
|
return stream;
|
2017-03-21 19:08:09 +00:00
|
|
|
}
|
|
|
|
|
2017-08-10 03:28:28 +00:00
|
|
|
template <typename clock, typename duration>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const chrono::duration<clock, duration> & what)
|
2017-03-21 19:08:09 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "chrono::duration<clock=" << clock() << ", duration=" << duration() << ">{" << what.count() << "}";
|
|
|
|
return stream;
|
2017-03-21 19:08:09 +00:00
|
|
|
}
|
|
|
|
|
2017-08-10 03:28:28 +00:00
|
|
|
template <typename clock, typename duration>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const chrono::time_point<clock, duration> & what)
|
2017-03-21 19:08:09 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
stream << "chrono::time_point{" << what.time_since_epoch() << "}";
|
|
|
|
return stream;
|
2017-03-21 19:08:09 +00:00
|
|
|
}
|
|
|
|
|
2017-08-10 03:28:28 +00:00
|
|
|
template <typename T>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const shared_ptr<T> & what)
|
2017-04-26 02:50:03 +00:00
|
|
|
{
|
2017-12-20 16:42:18 +00:00
|
|
|
stream << "shared_ptr(" << what.get() << ", use_count = " << what.use_count() << ") {";
|
2017-04-26 02:50:03 +00:00
|
|
|
if (what)
|
|
|
|
stream << *what;
|
|
|
|
else
|
|
|
|
stream << "nullptr";
|
|
|
|
stream << "}";
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:28:28 +00:00
|
|
|
template <typename T>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const unique_ptr<T> & what)
|
2017-08-04 16:59:25 +00:00
|
|
|
{
|
2017-12-20 16:42:18 +00:00
|
|
|
stream << "unique_ptr(" << what.get() << ") {";
|
2017-08-04 16:59:25 +00:00
|
|
|
if (what)
|
|
|
|
stream << *what;
|
|
|
|
else
|
|
|
|
stream << "nullptr";
|
|
|
|
stream << "}";
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:28:28 +00:00
|
|
|
template <typename T>
|
2017-12-20 16:42:18 +00:00
|
|
|
ostream & operator<<(ostream & stream, const optional<T> & what)
|
2017-04-28 18:57:26 +00:00
|
|
|
{
|
|
|
|
stream << "optional{";
|
|
|
|
if (what)
|
|
|
|
stream << *what;
|
|
|
|
else
|
|
|
|
stream << "empty";
|
|
|
|
stream << "}";
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
2017-12-20 16:42:18 +00:00
|
|
|
class exception;
|
|
|
|
ostream & operator<<(ostream & stream, const exception & what);
|
2017-06-22 15:57:37 +00:00
|
|
|
|
2017-02-14 19:14:34 +00:00
|
|
|
// TODO: add more types
|
2017-12-20 16:42:18 +00:00
|
|
|
|
|
|
|
}
|