template std::ostream& operator<<(std::ostream& out, const std::vector& vec) { if (vec.empty()) { out << "[]"; return out; } out << '['; for (int i = 0; i < vec.size() - 1; i++) { out << vec[i] << ", "; } return out << vec.back() << ']'; } template std::ostream& operator<<(std::ostream& out, const std::stack& stk) { std::stack t = stk; if (t.empty()) { out << "[]"; return out; } out << '['; while(!t.empty()) { out << t.top() << ", "; t.pop(); } return out << "\b\b]"; } template std::ostream& operator<<(std::ostream& out, const std::queue& que) { std::queue t = que; if (t.empty()) { out << "[]"; return out; } out << '['; while(!t.empty()) { out << t.front() << ", "; t.pop(); } return out << "\b\b]"; } template std::ostream& operator<<(std::ostream& out, const std::priority_queue& pque) { std::priority_queue t = pque; if (t.empty()) { out << "[]"; return out; } out << '['; while(!t.empty()) { out << t.top() << ", "; t.pop(); } return out << "\b\b]"; } template std::ostream& operator<<(std::ostream& out, const std::pair& pair) { return out << '(' << pair.first << ", " << pair.second << ')'; } template std::ostream& operator<<(std::ostream& out, const std::deque& deq) { if (deq.empty()) { out << "[]"; return out; } out << '['; for (int i = 0; i < deq.size() - 1; i++) { out << deq[i] << ", "; } return out << deq.back() << ']'; } template std::ostream& operator<<(std::ostream& out, const std::unordered_map& map) { out << '{'; for (auto it = map.begin(); it != map.end(); it++) { std::pair element = *it; out << element.first << ": " << element.second; if (std::next(it) != map.end()) { out << ", "; } } return out << '}'; } template std::ostream& operator<<(std::ostream& out, const std::map& map) { out << '{'; for (auto it = map.begin(); it != map.end(); it++) { std::pair element = *it; out << element.first << ": " << element.second; if (std::next(it) != map.end()) { out << ", "; } } return out << '}'; } template std::ostream& operator<<(std::ostream& out, const std::unordered_set& set) { out << '{'; for (auto it = set.begin(); it != set.end(); it++) { T element = *it; out << element; if (std::next(it) != set.end()) { out << ", "; } } return out << '}'; } template std::ostream& operator<<(std::ostream& out, const std::multiset& set) { out << '{'; for (auto it = set.begin(); it != set.end(); it++) { T element = *it; out << element; if (std::next(it) != set.end()) { out << ", "; } } return out << '}'; } template std::ostream& operator<<(std::ostream& out, const std::unordered_multiset& set) { out << '{'; for (auto it = set.begin(); it != set.end(); it++) { T element = *it; out << element; if (std::next(it) != set.end()) { out << ", "; } } return out << '}'; } template std::ostream& operator<<(std::ostream& out, const std::set& set) { out << '{'; for (auto it = set.begin(); it != set.end(); it++) { T element = *it; out << element; if (std::next(it) != set.end()) { out << ", "; } } return out << '}'; } // Source: https://stackoverflow.com/a/31116392/12128483 template struct TuplePrinter { static void print(std::ostream& out, const Type& value) { out << std::get(value) << ", "; TuplePrinter::print(out, value); } }; template struct TuplePrinter { static void print(std::ostream& out, const Type& value) { out << std::get(value); } }; template std::ostream& operator<<(std::ostream& out, const std::tuple& value) { out << '('; TuplePrinter, 0, sizeof...(Types) - 1>::print(out, value); return out << ')'; }