-
-
Save dducws/c1aef58e6390e8b72a94ae0feeaddb9e to your computer and use it in GitHub Desktop.
A useful debugging template for C++.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <vector> | |
| #include <deque> | |
| #include <map> | |
| #include <unordered_map> | |
| #include <set> | |
| #include <unordered_set> | |
| #include <array> | |
| #define all(x) begin(x), end(x) | |
| #define sz(x) (int) (x).size() | |
| template <typename T, std::size_t N> | |
| std::ostream& operator<<(std::ostream& out, const std::array<T, N>& arr) { | |
| if (arr.empty()) { | |
| out << "[]"; | |
| return out; | |
| } | |
| out << '['; | |
| for (std::size_t i = 0; i < sz(arr) - 1; i++) { | |
| out << arr[i] << ", "; | |
| } | |
| return out << arr.back() << ']'; | |
| } | |
| template <typename T> | |
| std::ostream& operator<<(std::ostream& out, const std::vector<T>& vec) { | |
| if (vec.empty()) { | |
| out << "[]"; | |
| return out; | |
| } | |
| out << '['; | |
| for (int i = 0; i < sz(vec) - 1; i++) { | |
| out << vec[i] << ", "; | |
| } | |
| return out << vec.back() << ']'; | |
| } | |
| template <typename T1, typename T2> | |
| std::ostream& operator<<(std::ostream& out, const std::pair<T1, T2>& pair) { | |
| return out << '(' << pair.first << ", " << pair.second << ')'; | |
| } | |
| template <typename T> | |
| std::ostream& operator<<(std::ostream& out, const std::deque<T>& deq) { | |
| if (deq.empty()) { | |
| out << "[]"; | |
| return out; | |
| } | |
| out << '['; | |
| for (int i = 0; i < sz(deq) - 1; i++) { | |
| out << deq[i] << ", "; | |
| } | |
| return out << deq.back() << ']'; | |
| } | |
| template <typename T1, typename T2> | |
| std::ostream& operator<<(std::ostream& out, const std::unordered_map<T1, T2>& map) { | |
| out << '{'; | |
| for (auto it = map.begin(); it != map.end(); it++) { | |
| std::pair<T1, T2> element = *it; | |
| out << element.first << ": " << element.second; | |
| if (std::next(it) != map.end()) { | |
| out << ", "; | |
| } | |
| } | |
| return out << '}'; | |
| } | |
| template <typename T1, typename T2> | |
| std::ostream& operator<<(std::ostream& out, const std::map<T1, T2>& map) { | |
| out << '{'; | |
| for (auto it = map.begin(); it != map.end(); it++) { | |
| std::pair<T1, T2> element = *it; | |
| out << element.first << ": " << element.second; | |
| if (std::next(it) != map.end()) { | |
| out << ", "; | |
| } | |
| } | |
| return out << '}'; | |
| } | |
| template <typename T> | |
| std::ostream& operator<<(std::ostream& out, const std::unordered_set<T>& 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 <typename T> | |
| std::ostream& operator<<(std::ostream& out, const std::multiset<T>& 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 <typename T> | |
| std::ostream& operator<<(std::ostream& out, const std::unordered_multiset<T>& 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 <typename T> | |
| std::ostream& operator<<(std::ostream& out, const std::set<T>& 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<typename Type, unsigned N, unsigned Last> | |
| struct TuplePrinter { | |
| static void print(std::ostream& out, const Type& value) { | |
| out << std::get<N>(value) << ", "; | |
| TuplePrinter<Type, N + 1, Last>::print(out, value); | |
| } | |
| }; | |
| template<typename Type, unsigned N> | |
| struct TuplePrinter<Type, N, N> { | |
| static void print(std::ostream& out, const Type& value) { | |
| out << std::get<N>(value); | |
| } | |
| }; | |
| template<typename... Types> | |
| std::ostream& operator<<(std::ostream& out, const std::tuple<Types...>& value) { | |
| out << '('; | |
| TuplePrinter<std::tuple<Types...>, 0, sizeof...(Types) - 1>::print(out, value); | |
| return out << ')'; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment