print.h
Go to the documentation of this file.
1 #ifndef TTG_PRINT_H
2 #define TTG_PRINT_H
3 
4 #include <iostream>
5 #include <mutex>
6 #include <complex>
7 #include <vector>
8 #include <array>
9 #include <utility>
10 
11 namespace ttg {
12  constexpr char print_separator = ' ';
13  constexpr char print_seq_separator = ',';
14  constexpr char print_seq_begin = '{';
15  constexpr char print_seq_end = '}';
16 
17  namespace iostream {
18 
21 
23 
28  template <typename T>
29  std::ostream &operator<<(std::ostream &s, const std::complex<T> &c) {
30  s << c.real() << (c.imag() >= 0 ? "+" : "") << c.imag() << "j";
31  return s;
32  }
33 
35 
41  template <typename T, typename U>
42  std::ostream &operator<<(std::ostream &s, const std::pair<T, U> &p) {
43  s << print_seq_begin << p.first << print_seq_separator << p.second << print_seq_end;
44  return s;
45  }
46 
48 
53  template <typename T>
54  std::ostream &operator<<(std::ostream &s, const std::vector<T> &c) {
55  s << print_seq_begin;
56  typename std::vector<T>::const_iterator it = c.begin();
57  while (it != c.end()) {
58  s << *it;
59  ++it;
60  if (it != c.end())
62  };
63  s << print_seq_end;
64  return s;
65  }
66 
68 
75  template <typename T, std::size_t N>
76  typename std::enable_if<!std::is_same<T, char>::value, std::ostream &>::type
77  operator<<(std::ostream &s, const std::array<T,N>& v) {
78  s << print_seq_begin;
79  for (std::size_t i = 0; i < N; ++i) {
80  s << v[i];
81  if (i != (N - 1))
83  }
84  s << print_seq_end;
85  return s;
86  }
87 
89 
96  template <typename T, std::size_t N>
97  typename std::enable_if<!std::is_same<T, char>::value, std::ostream &>::type
98  operator<<(std::ostream &s, const T (&v)[N]) {
99  s << print_seq_begin;
100  for (std::size_t i = 0; i < N; ++i) {
101  s << v[i];
102  if (i != (N - 1))
103  s << print_seq_separator;
104  }
105  s << print_seq_end;
106  return s;
107  }
108 
109  } // namespace operators
110 
111  namespace detail {
112  inline std::ostream &print_helper(std::ostream &out) { return out; }
113  template <typename T, typename... Ts>
114  inline std::ostream &print_helper(std::ostream &out, const T &t, const Ts &... ts) {
115  using ttg::iostream::operator<<;
116  out << print_separator << t;
117  return print_helper(out, ts...);
118  }
119  //
120  enum class StdOstreamTag { Cout, Cerr };
121  template <StdOstreamTag>
122  inline std::mutex &print_mutex_accessor() {
123  static std::mutex mutex;
124  return mutex;
125  }
126  } // namespace detail
127 
129  template <typename T, typename... Ts>
130  void print(const T &t, const Ts &... ts) {
131  std::lock_guard<std::mutex> lock(detail::print_mutex_accessor<detail::StdOstreamTag::Cout>());
132  std::cout << t;
133  detail::print_helper(std::cout, ts...) << std::endl;
134  }
135 
137  template <typename T, typename... Ts>
138  void print_error(const T &t, const Ts &... ts) {
139  std::lock_guard<std::mutex> lock(detail::print_mutex_accessor<detail::StdOstreamTag::Cout>());
140  std::cerr << t;
141  detail::print_helper(std::cerr, ts...) << std::endl;
142  }
143 
145  template <typename T, typename... Ts>
146  void log(const T &t, const Ts &... ts) {
147  std::lock_guard<std::mutex> lock(detail::print_mutex_accessor<detail::StdOstreamTag::Cout>());
148  std::clog << t;
149  detail::print_helper(std::clog, ts...) << std::endl;
150  }
151 } // namespace ttg
152 
153 #endif // TTG_PRINT_H
std::ostream & print_helper(std::ostream &out)
Definition: print.h:112
std::mutex & print_mutex_accessor()
Definition: print.h:122
StdOstreamTag
Definition: print.h:120
std::ostream & operator<<(std::ostream &s, const std::complex< T > &c)
default printing of std::complex
Definition: print.h:29
top-level TTG namespace contains runtime-neutral functionality
Definition: keymap.h:8
constexpr char print_seq_separator
Definition: print.h:13
void print(const T &t, const Ts &... ts)
atomically prints to std::cout a sequence of items (separated by ttg::print_separator) followed by st...
Definition: print.h:130
constexpr char print_separator
Definition: print.h:12
void log(const T &t, const Ts &... ts)
atomically prints to std::clog a sequence of items (separated by ttg::print_separator) followed by st...
Definition: print.h:146
void print_error(const T &t, const Ts &... ts)
atomically prints to std::cerr a sequence of items (separated by ttg::print_separator) followed by st...
Definition: print.h:138
constexpr char print_seq_end
Definition: print.h:15
constexpr char print_seq_begin
Definition: print.h:14