noparama  v0.0.1
Nonparametric Bayesian models
pretty_print.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <iterator>
5 #include <type_traits>
6 #include <vector>
7 #include <algorithm>
8 
9 // Using syslog severity levels: https://en.wikipedia.org/wiki/Syslog#Severity_level
10 // Emergency: system is unusable
11 // Alert: action must be taken immediately
12 // Critical: critical conditions
13 // Error: error conditions
14 // Warning: warning conditions
15 // Notice: normal but significant condition
16 // Informational: informational messages
17 // Debug: debug-level messages
18 
20 
21 static std::vector<std::string> levels_str { "Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Information", "Debug"};
22 
24 
25 static std::vector<std::string> levels_clr { "\033[0;30m", "\033[0;31m", "\033[0;32m", "\033[0;33m", "\033[0;34m", "\033[0;35m", "\033[0;36m", "\033[0;37m" };
26 
27 static std::vector<int> levels_clr_map { Red, Red, Red, Red, Yellow, Yellow, Green, White };
28 
29 static std::string fblue = "\033[1;34m";
30 static std::string fpurple = "\033[1;35m";
31 
32 #define __SHORT_FORM_OF_FILE__ \
33  (strrchr(__FILE__,'/') \
34  ? strrchr(__FILE__,'/')+1 \
35  : __FILE__ \
36  )
37 
38 /*
39  * Assume there is a local variable "_verbosity" that can be used!
40  */
41 #define foutvar(var) \
42  if (_verbosity >= var) std::cout << levels_clr[ levels_clr_map[var] ] << '[' << levels_str[var] << "] " << levels_clr[Purple] << __SHORT_FORM_OF_FILE__ << '[' << __LINE__ << "]\033[0m " << levels_clr[Blue] << __func__ << "(): \033[0m"
43 
44 /*
45  * Set default fout level at Information
46  */
47 #define fout \
48  foutvar(Information)
49 
50 // This works similar to ostream_iterator, but doesn't print a delimiter after the final item
51 template<typename T, typename TChar = char, typename TCharTraits = std::char_traits<TChar> >
52 class pretty_ostream_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
53 {
54 public:
55  typedef TChar char_type;
56  typedef TCharTraits traits_type;
57  typedef std::basic_ostream<TChar, TCharTraits> ostream_type;
58 
59  pretty_ostream_iterator(ostream_type &stream, const char_type *delim = NULL)
60  : _stream(&stream), _delim(delim), _insertDelim(false)
61  {
62  }
63 
65  {
66  if( _delim != NULL )
67  {
68  // Don't insert a delimiter if this is the first time the function is called
69  if( _insertDelim )
70  (*_stream) << _delim;
71  else
72  _insertDelim = true;
73  }
74  (*_stream) << value;
75  return *this;
76  }
77 
79  {
80  return *this;
81  }
82 
84  {
85  return *this;
86  }
87 
89  {
90  return *this;
91  }
92 private:
93  ostream_type *_stream;
94  const char_type *_delim;
95  bool _insertDelim;
96 };
97 
98 #if _MSC_VER >= 1400
99 
100 // Declare pretty_ostream_iterator as checked
101 template<typename T, typename TChar, typename TCharTraits>
102 struct std::_Is_checked_helper<pretty_ostream_iterator<T, TChar, TCharTraits> > : public std::tr1::true_type
103 {
104 };
105 
106 #endif // _MSC_VER >= 1400
107 
108 namespace std
109 {
110  // Pre-declarations of container types so we don't actually have to include the relevant headers if not needed, speeding up compilation time.
111  // These aren't necessary if you do actually include the headers.
112  template<typename T, typename TAllocator> class vector;
113  template<typename T, typename TAllocator> class list;
114  template<typename T, typename TTraits, typename TAllocator> class set;
115  template<typename TKey, typename TValue, typename TTraits, typename TAllocator> class map;
116 }
117 
118 // Basic is_container template; specialize to derive from std::true_type for all desired container types
119 template<typename T> struct is_container : public std::false_type { };
120 
121 // Mark vector as a container
122 template<typename T, typename TAllocator> struct is_container<std::vector<T, TAllocator> > : public std::true_type { };
123 
124 // Mark list as a container
125 template<typename T, typename TAllocator> struct is_container<std::list<T, TAllocator> > : public std::true_type { };
126 
127 // Mark set as a container
128 template<typename T, typename TTraits, typename TAllocator> struct is_container<std::set<T, TTraits, TAllocator> > : public std::true_type { };
129 
130 // Mark map as a container
131 template<typename TKey, typename TValue, typename TTraits, typename TAllocator> struct is_container<std::map<TKey, TValue, TTraits, TAllocator> > : public std::true_type { };
132 
133 // Holds the delimiter values for a specific character type
134 template<typename TChar>
136 {
137  typedef TChar char_type;
138  const TChar *prefix;
139  const TChar *delimiter;
140  const TChar *postfix;
141 };
142 
143 // Defines the delimiter values for a specific container and character type
144 template<typename T, typename TChar>
146 {
148 };
149 
150 // Default delimiters
151 template<typename T> struct delimiters<T, char> { static const delimiters_values<char> values; };
152 template<typename T> const delimiters_values<char> delimiters<T, char>::values = { "{ ", ", ", " }" };
153 template<typename T> struct delimiters<T, wchar_t> { static const delimiters_values<wchar_t> values; };
154 template<typename T> const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = { L"{ ", L", ", L" }" };
155 
156 // Delimiters for set
157 template<typename T, typename TTraits, typename TAllocator> struct delimiters<std::set<T, TTraits, TAllocator>, char> { static const delimiters_values<char> values; };
158 template<typename T, typename TTraits, typename TAllocator> const delimiters_values<char> delimiters<std::set<T, TTraits, TAllocator>, char>::values = { "[ ", ", ", " ]" };
159 template<typename T, typename TTraits, typename TAllocator> struct delimiters<std::set<T, TTraits, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
160 template<typename T, typename TTraits, typename TAllocator> const delimiters_values<wchar_t> delimiters<std::set<T, TTraits, TAllocator>, wchar_t>::values = { L"[ ", L", ", L" ]" };
161 
162 // Delimiters for pair
163 template<typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> { static const delimiters_values<char> values; };
164 template<typename T1, typename T2> const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = { "(", ", ", ")" };
165 template<typename T1, typename T2> struct delimiters<std::pair<T1, T2>, wchar_t> { static const delimiters_values<wchar_t> values; };
166 template<typename T1, typename T2> const delimiters_values<wchar_t> delimiters<std::pair<T1, T2>, wchar_t>::values = { L"(", L", ", L")" };
167 
168 // Functor to print containers. You can use this directly if you want to specificy a non-default delimiters type.
169 template<typename T, typename TChar = char, typename TCharTraits = std::char_traits<TChar>, typename TDelimiters = delimiters<T, TChar> >
171 {
172  typedef TChar char_type;
173  typedef TDelimiters delimiters_type;
174  typedef std::basic_ostream<TChar, TCharTraits>& ostream_type;
175 
176  print_container_helper(const T &container)
177  : _container(&container)
178  {
179  }
180 
181  void operator()(ostream_type &stream) const
182  {
183  if( delimiters_type::values.prefix != NULL )
184  stream << delimiters_type::values.prefix;
185  std::copy(_container->begin(), _container->end(), pretty_ostream_iterator<typename T::value_type, TChar, TCharTraits>(stream, delimiters_type::values.delimiter));
186  if( delimiters_type::values.postfix != NULL )
187  stream << delimiters_type::values.postfix;
188  }
189 private:
190  const T *_container;
191 };
192 
193 // Prints a print_container_helper to the specified stream.
194 template<typename T, typename TChar, typename TCharTraits, typename TDelimiters>
195 std::basic_ostream<TChar, TCharTraits>& operator<<(std::basic_ostream<TChar, TCharTraits> &stream, const print_container_helper<T, TChar, TDelimiters> &helper)
196 {
197  helper(stream);
198  return stream;
199 }
200 
201 // Prints a container to the stream using default delimiters
202 template<typename T, typename TChar, typename TCharTraits>
203 typename std::enable_if<is_container<T>::value, std::basic_ostream<TChar, TCharTraits>&>::type
204  operator<<(std::basic_ostream<TChar, TCharTraits> &stream, const T &container)
205 {
206  stream << print_container_helper<T, TChar, TCharTraits>(container);
207  return stream;
208 }
209 
210 // Prints a pair to the stream using delimiters from delimiters<std::pair<T1, T2>>.
211 template<typename T1, typename T2, typename TChar, typename TCharTraits>
212 std::basic_ostream<TChar, TCharTraits>& operator<<(std::basic_ostream<TChar, TCharTraits> &stream, const std::pair<T1, T2> &value)
213 {
214  if( delimiters<std::pair<T1, T2>, TChar>::values.prefix != NULL )
215  stream << delimiters<std::pair<T1, T2>, TChar>::values.prefix;
216 
217  stream << value.first;
218 
219  if( delimiters<std::pair<T1, T2>, TChar>::values.delimiter != NULL )
220  stream << delimiters<std::pair<T1, T2>, TChar>::values.delimiter;
221 
222  stream << value.second;
223 
224  if( delimiters<std::pair<T1, T2>, TChar>::values.postfix != NULL )
225  stream << delimiters<std::pair<T1, T2>, TChar>::values.postfix;
226  return stream;
227 }
228 
static const delimiters_values< wchar_t > values
Definition: pretty_print.hpp:159
Definition: pretty_print.hpp:19
static const delimiters_values< char > values
Definition: pretty_print.hpp:157
Definition: pretty_print.hpp:23
Definition: pretty_print.hpp:19
Definition: pretty_print.hpp:115
Definition: pretty_print.hpp:145
void operator()(ostream_type &stream) const
Definition: pretty_print.hpp:181
static const delimiters_values< char > values
Definition: pretty_print.hpp:163
TChar char_type
Definition: pretty_print.hpp:55
static const delimiters_values< char > values
Definition: pretty_print.hpp:151
Definition: pretty_print.hpp:108
Definition: pretty_print.hpp:23
TDelimiters delimiters_type
Definition: pretty_print.hpp:173
Definition: pretty_print.hpp:112
Definition: pretty_print.hpp:23
pretty_ostream_iterator< T, TChar, TCharTraits > & operator++(int)
Definition: pretty_print.hpp:88
TChar char_type
Definition: pretty_print.hpp:137
Definition: pretty_print.hpp:19
TCharTraits traits_type
Definition: pretty_print.hpp:56
Definition: pretty_print.hpp:19
Definition: pretty_print.hpp:135
Definition: pretty_print.hpp:52
Definition: pretty_print.hpp:23
static const delimiters_values< wchar_t > values
Definition: pretty_print.hpp:153
static const delimiters_values< wchar_t > values
Definition: pretty_print.hpp:165
Definition: pretty_print.hpp:19
pretty_ostream_iterator< T, TChar, TCharTraits > & operator++()
Definition: pretty_print.hpp:83
Definition: pretty_print.hpp:113
Definition: pretty_print.hpp:19
pretty_ostream_iterator< T, TChar, TCharTraits > & operator*()
Definition: pretty_print.hpp:78
Definition: pretty_print.hpp:19
pretty_ostream_iterator(ostream_type &stream, const char_type *delim=NULL)
Definition: pretty_print.hpp:59
const TChar * postfix
Definition: pretty_print.hpp:140
Definition: pretty_print.hpp:23
Definition: pretty_print.hpp:23
print_container_helper(const T &container)
Definition: pretty_print.hpp:176
const TChar * delimiter
Definition: pretty_print.hpp:139
Definition: pretty_print.hpp:119
Definition: pretty_print.hpp:114
Definition: pretty_print.hpp:19
std::basic_ostream< TChar, TCharTraits > ostream_type
Definition: pretty_print.hpp:57
std::basic_ostream< TChar, TCharTraits > & ostream_type
Definition: pretty_print.hpp:174
pretty_ostream_iterator< T, TChar, TCharTraits > & operator=(const T &value)
Definition: pretty_print.hpp:64
TChar char_type
Definition: pretty_print.hpp:172
static const delimiters_values< TChar > values
Definition: pretty_print.hpp:147
const TChar * prefix
Definition: pretty_print.hpp:138
Definition: pretty_print.hpp:170
Definition: pretty_print.hpp:23
Definition: pretty_print.hpp:23