#pragma once #include #include template std::ostream & operator<<(std::ostream & stream, const std::pair & what) { stream << "pair{" << what.first << ", " << what.second << "}"; return stream; } template void dumpContainer(std::ostream & stream, const T & container) { stream << "{"; bool first = true; for (const auto & elem : container) { if (!first) stream << ", "; first = false; stream << elem; } stream << "}"; } #include template std::ostream & operator<<(std::ostream & stream, const std::vector & what) { stream << "vector(size = " << what.size() << ", capacity = " << what.capacity() << ")"; dumpContainer(stream, what); return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::array & what) { stream << "array<" << what.size() << ">"; dumpContainer(stream, what); return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::map & what) { stream << "map(size = " << what.size() << ")"; dumpContainer(stream, what); return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::unordered_map & what) { stream << "unordered_map(size = " << what.size() << ")"; dumpContainer(stream, what); return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::set & what) { stream << "set(size = " << what.size() << ")"; dumpContainer(stream, what); return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::unordered_set & what) { stream << "unordered_set(size = " << what.size() << ")"; dumpContainer(stream, what); return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::list & what) { stream << "list(size = " << what.size() << ")"; dumpContainer(stream, what); return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::ratio & what) { stream << "ratio"; return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::chrono::duration & what) { stream << "chrono::duration{" << what.count() << "}"; return stream; } template std::ostream & operator<<(std::ostream & stream, const std::chrono::time_point & what) { stream << "chrono::time_point{" << what.time_since_epoch() << "}"; return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::shared_ptr & what) { stream << "shared_ptr(use_count = " << what.use_count() << ") {"; if (what) stream << *what; else stream << "nullptr"; stream << "}"; return stream; } #include template std::ostream & operator<<(std::ostream & stream, const std::experimental::optional & what) { stream << "optional{"; if (what) stream << *what; else stream << "empty"; stream << "}"; return stream; } namespace std { class exception; } std::ostream & operator<<(std::ostream & stream, const std::exception & what); // TODO: add more types