LIPH's C++ Codes
print.h
Go to the documentation of this file.
1#ifndef LIPH_PRINT_H_
2#define LIPH_PRINT_H_
3
4#include <cstring>
5#include <iostream>
6#include <list>
7#include <map>
8#include <set>
9#include <sstream>
10#include <string>
11#include <string_view>
12#include <unordered_map>
13#include <utility>
14#include <vector>
15
16#include "liph/format.h"
17
18namespace liph {
19
20template <class T1, class T2>
21std::ostream& operator<<(std::ostream& o, const std::pair<T1, T2>& p) {
22 return o << "(" << p.first << ", " << p.second << ")";
23}
24
25inline std::ostream& operator<<(std::ostream& o, const std::vector<bool>& vb) {
26 for (size_t i = 0; i < vb.size(); i++) o << vb[i];
27 return o;
28}
29
30inline std::ostream& operator<<(std::ostream& o, const char *s) { return std::operator<<(o, s); }
31inline std::ostream& operator<<(std::ostream& o, const std::string& s) { return std::operator<<(o, s); }
32inline std::ostream& operator<<(std::ostream& o, std::string_view s) { return std::operator<<(o, s); }
33
34template <std::ranges::input_range Range>
35std::ostream& operator<<(std::ostream& o, const Range& range) {
36 o << "[";
37 bool first = true;
38 for (const auto& value : range) {
39 if (!first) o << ", ";
40 first = false;
41 o << value;
42 }
43 return o << "]";
44}
45
46template <class K, class V>
47std::ostream& operator<<(std::ostream& o, const std::map<K, V>& map) {
48 o << "{";
49 bool first = true;
50 for (const auto& value : map) {
51 if (!first) o << ", ";
52 first = false;
53 o << value;
54 }
55 return o << "}";
56}
57
58template <class K, class V>
59std::ostream& operator<<(std::ostream& o, const std::unordered_map<K, V>& map) {
60 o << "{";
61 bool first = true;
62 for (const auto& value : map) {
63 if (!first) o << ", ";
64 first = false;
65 o << value;
66 }
67 return o << "}";
68}
69
70inline void println() { std::cout << std::endl; }
71
72inline void print(bool b) { std::cout << (b ? "true" : "false") << std::endl; }
73
74template <class T>
75concept Printable = requires(T t) { std::cout << t; };
76
77template <Printable T>
78void print(T&& t) {
79 std::cout << t << std::endl;
80}
81
82template <Printable T, Printable... Args>
83void print(T&& head, Args&&...args) {
84 std::cout << head << ' ';
85 print(args...);
86}
87
88template <Printable... Args>
89void print(bool head, Args&&...args) {
90 std::cout << (head ? "true" : "false") << ' ';
91 print(args...);
92}
93
94} // namespace liph
95
96#ifndef __FILENAME__
97#define __FILENAME__ ((strrchr(__FILE__, '/') ?: __FILE__ - 1) + 1)
98#endif
99
100#define SOURCE_LOCATION_FORMAT liph::format("[{}:{}]", __FILENAME__, __LINE__)
101#define PRINT(...) liph::print(SOURCE_LOCATION_FORMAT, __VA_ARGS__)
102#define DEBUG(x) liph::print(SOURCE_LOCATION_FORMAT, #x, "=", x)
103#define TRACE(x) \
104 liph::print(SOURCE_LOCATION_FORMAT, #x); \
105 x
106
107#endif // LIPH_PRINT_H_
Definition: print.h:75
Definition: algorithm.h:10
std::ostream & operator<<(std::ostream &o, const std::unordered_map< K, V > &map)
Definition: print.h:59
std::ostream & operator<<(std::ostream &o, const std::pair< T1, T2 > &p)
Definition: print.h:21
void print(bool b)
Definition: print.h:72
void println()
Definition: print.h:70