25#include <unordered_set>
30 namespace pretty_print {
40 struct has_const_iterator :
private sfinae_base {
44 static yes& test(
typename C::const_iterator*);
50 static const bool value =
sizeof(test<T>(
nullptr)) ==
sizeof(yes);
55 struct has_begin_end :
private sfinae_base {
60 typename std::enable_if<
61 std::is_same<
decltype(
static_cast<typename C::const_iterator (C::*)() const
>(&C::begin)),
62 typename C::const_iterator (C::*)()
const>::value>::type*);
68 static yes& g(
typename std::enable_if<
69 std::is_same<
decltype(
static_cast<typename C::const_iterator (C::*)() const
>(&C::end)),
70 typename C::const_iterator (C::*)()
const>::value,
78 static const bool beg_value =
sizeof(f<T>(
nullptr)) ==
sizeof(yes);
79 static const bool end_value =
sizeof(g<T>(
nullptr)) ==
sizeof(yes);
87 template <
typename TChar>
88 struct delimiters_values {
89 using char_type = TChar;
90 const char_type* prefix;
91 const char_type* delimiter;
92 const char_type* postfix;
98 template <
typename T,
typename TChar>
100 using type = delimiters_values<TChar>;
101 static const type values;
109 template <
typename T,
110 typename TChar = char,
111 typename TCharTraits = ::std::char_traits<TChar>,
112 typename TDelimiters = delimiters<T, TChar>>
113 struct print_container_helper {
114 using delimiters_type = TDelimiters;
115 using ostream_type = std::basic_ostream<TChar, TCharTraits>;
117 template <
typename U>
119 static void print_body(
const U& c, ostream_type& stream) {
124 const auto the_end = end(c);
130 if (++it == the_end)
break;
132 if (delimiters_type::values.delimiter != NULL) stream << delimiters_type::values.delimiter;
138 print_container_helper(
const T& container)
139 : container_(container) { }
141 inline void operator()(ostream_type& stream)
const {
142 if (delimiters_type::values.prefix != NULL) stream << delimiters_type::values.prefix;
144 printer<T>::print_body(container_, stream);
146 if (delimiters_type::values.postfix != NULL) stream << delimiters_type::values.postfix;
156 template <
typename T,
typename TChar,
typename TCharTraits,
typename TDelimiters>
157 template <
typename T1,
typename T2>
158 struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::pair<T1, T2>> {
159 using ostream_type =
typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
161 static void print_body(
const std::pair<T1, T2>& c, ostream_type& stream) {
163 if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter
165 stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values
173 template <
typename T,
typename TChar,
typename TCharTraits,
typename TDelimiters>
174 template <
typename... Args>
175 struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::tuple<Args...>> {
176 using ostream_type =
typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
177 using element_type = std::tuple<Args...>;
179 template <std::
size_t I>
182 static void print_body(
const element_type& c, ostream_type& stream) {
183 tuple_print(c, stream, Int<0>());
186 static void tuple_print(
const element_type&, ostream_type&, Int<
sizeof...(Args)>) { }
188 static void tuple_print(
const element_type& c,
189 ostream_type& stream,
190 typename std::conditional<
sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type) {
191 stream << std::get<0>(c);
192 tuple_print(c, stream, Int<1>());
195 template <std::
size_t N>
196 static void tuple_print(
const element_type& c, ostream_type& stream, Int<N>) {
197 if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter
199 stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values
202 stream << std::get<N>(c);
204 tuple_print(c, stream, Int<N + 1>());
210 template <
typename T,
typename TChar,
typename TCharTraits,
typename TDelimiters>
211 inline std::basic_ostream<TChar, TCharTraits>&
operator<<(
212 std::basic_ostream<TChar, TCharTraits>& stream,
213 const print_container_helper<T, TChar, TCharTraits, TDelimiters>& helper) {
221 template <
typename T>
222 struct is_container :
public std::integral_constant<bool,
223 detail::has_const_iterator<T>::value
224 && detail::has_begin_end<T>::beg_value
225 && detail::has_begin_end<T>::end_value> { };
227 template <
typename T, std::
size_t N>
228 struct is_container<T[N]> : std::true_type { };
230 template <std::
size_t N>
231 struct is_container<char[N]> : std::false_type { };
233 template <
typename T>
234 struct is_container<std::valarray<T>> : std::true_type { };
236 template <
typename T1,
typename T2>
237 struct is_container<std::pair<T1, T2>> : std::true_type { };
239 template <
typename... Args>
240 struct is_container<std::tuple<Args...>> : std::true_type { };
245 template <
typename T>
246 struct delimiters<T, char> {
247 static const delimiters_values<char> values;
249 template <
typename T>
250 const delimiters_values<char> delimiters<T, char>::values = {
"[",
", ",
"]"};
251 template <
typename T>
252 struct delimiters<T, wchar_t> {
253 static const delimiters_values<wchar_t> values;
255 template <
typename T>
256 const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = {L
"[", L
", ", L
"]"};
261 template <
typename T,
typename TComp,
typename TAllocator>
262 struct delimiters<::std::set<T, TComp, TAllocator>, char> {
263 static const delimiters_values<char> values;
266 template <
typename T,
typename TComp,
typename TAllocator>
267 const delimiters_values<char> delimiters<::std::set<T, TComp, TAllocator>,
char>::values = {
"{",
", ",
270 template <
typename T,
typename TComp,
typename TAllocator>
271 struct delimiters<::std::set<T, TComp, TAllocator>, wchar_t> {
272 static const delimiters_values<wchar_t> values;
275 template <
typename T,
typename TComp,
typename TAllocator>
276 const delimiters_values<wchar_t> delimiters<::std::set<T, TComp, TAllocator>,
wchar_t>::values = {L
"{",
280 template <
typename T,
typename TComp,
typename TAllocator>
281 struct delimiters<::std::multiset<T, TComp, TAllocator>, char> {
282 static const delimiters_values<char> values;
285 template <
typename T,
typename TComp,
typename TAllocator>
286 const delimiters_values<char> delimiters<::std::multiset<T, TComp, TAllocator>,
char>::values = {
"{",
290 template <
typename T,
typename TComp,
typename TAllocator>
291 struct delimiters<::std::multiset<T, TComp, TAllocator>, wchar_t> {
292 static const delimiters_values<wchar_t> values;
295 template <
typename T,
typename TComp,
typename TAllocator>
296 const delimiters_values<wchar_t> delimiters<::std::multiset<T, TComp, TAllocator>,
wchar_t>::values = {
299 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
300 struct delimiters<::std::unordered_set<T, THash, TEqual, TAllocator>, char> {
301 static const delimiters_values<char> values;
304 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
305 const delimiters_values<char>
306 delimiters<::std::unordered_set<T, THash, TEqual, TAllocator>,
char>::values = {
"{",
", ",
"}"};
308 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
309 struct delimiters<::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> {
310 static const delimiters_values<wchar_t> values;
313 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
314 const delimiters_values<wchar_t>
315 delimiters<::std::unordered_set<T, THash, TEqual, TAllocator>,
wchar_t>::values = {L
"{", L
", ", L
"}"};
317 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
318 struct delimiters<::std::unordered_multiset<T, THash, TEqual, TAllocator>, char> {
319 static const delimiters_values<char> values;
322 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
323 const delimiters_values<char>
324 delimiters<::std::unordered_multiset<T, THash, TEqual, TAllocator>,
char>::values = {
"{",
", ",
"}"};
326 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
327 struct delimiters<::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t> {
328 static const delimiters_values<wchar_t> values;
331 template <
typename T,
typename THash,
typename TEqual,
typename TAllocator>
332 const delimiters_values<wchar_t>
333 delimiters<::std::unordered_multiset<T, THash, TEqual, TAllocator>,
wchar_t>::values = {L
"{", L
", ",
339 template <
typename T1,
typename T2>
340 struct delimiters<std::pair<T1, T2>, char> {
341 static const delimiters_values<char> values;
343 template <
typename T1,
typename T2>
344 const delimiters_values<char> delimiters<std::pair<T1, T2>,
char>::values = {
"(",
", ",
")"};
345 template <
typename T1,
typename T2>
346 struct delimiters<::std::pair<T1, T2>, wchar_t> {
347 static const delimiters_values<wchar_t> values;
349 template <
typename T1,
typename T2>
350 const delimiters_values<wchar_t> delimiters<::std::pair<T1, T2>,
wchar_t>::values = {L
"(", L
", ", L
")"};
352 template <
typename... Args>
353 struct delimiters<std::tuple<Args...>, char> {
354 static const delimiters_values<char> values;
356 template <
typename... Args>
357 const delimiters_values<char> delimiters<std::tuple<Args...>,
char>::values = {
"(",
", ",
")"};
358 template <
typename... Args>
359 struct delimiters<::std::tuple<Args...>, wchar_t> {
360 static const delimiters_values<wchar_t> values;
362 template <
typename... Args>
363 const delimiters_values<wchar_t> delimiters<::std::tuple<Args...>,
wchar_t>::values = {L
"(", L
", ", L
")"};
370 struct custom_delims_base {
371 virtual ~custom_delims_base() { }
372 virtual std::ostream& stream(::std::ostream&) = 0;
373 virtual std::wostream& stream(::std::wostream&) = 0;
376 template <
typename T,
typename Delims>
377 struct custom_delims_wrapper : custom_delims_base {
378 custom_delims_wrapper(
const T& t_)
381 std::ostream& stream(std::ostream& s) {
382 return s << print_container_helper<T, char, std::char_traits<char>, Delims>(t);
385 std::wostream& stream(std::wostream& s) {
386 return s << print_container_helper<T, wchar_t, std::char_traits<wchar_t>, Delims>(t);
394 template <
typename Delims>
395 struct custom_delims {
396 template <
typename Container>
397 custom_delims(
const Container& c)
398 : base(new custom_delims_wrapper<Container, Delims>(c)) { }
400 std::unique_ptr<custom_delims_base> base;
403 template <
typename TChar,
typename TCharTraits,
typename Delims>
404 inline std::basic_ostream<TChar, TCharTraits>&
operator<<(std::basic_ostream<TChar, TCharTraits>& s,
405 const custom_delims<Delims>& p) {
406 return p.base->stream(s);
413 template <
typename T>
414 struct array_wrapper_n {
415 typedef const T* const_iterator;
416 typedef T value_type;
418 array_wrapper_n(
const T*
const a,
size_t n)
419 : _array(a), _n(n) { }
420 inline const_iterator begin()
const {
423 inline const_iterator end()
const {
429 const T*
const _array;
437 template <
typename T>
438 struct bucket_print_wrapper {
439 typedef typename T::const_local_iterator const_iterator;
440 typedef typename T::size_type size_type;
442 const_iterator begin()
const {
443 return m_map.cbegin(n);
446 const_iterator end()
const {
447 return m_map.cend(n);
450 bucket_print_wrapper(
const T& m, size_type bucket)
451 : m_map(m), n(bucket) { }
464 template <
typename T>
465 inline pretty_print::array_wrapper_n<T> pretty_print_array(
const T*
const a,
size_t n) {
466 return pretty_print::array_wrapper_n<T>(a, n);
469 template <
typename T>
470 pretty_print::bucket_print_wrapper<T> bucket_print(
const T& m,
typename T::size_type n) {
471 return pretty_print::bucket_print_wrapper<T>(m, n);
484 template <
typename T,
typename TChar,
typename TCharTraits>
485 inline typename enable_if<::Rivet::pretty_print::is_container<T>::value,
486 basic_ostream<TChar, TCharTraits>&>::type
487 operator<<(std::basic_ostream<TChar, TCharTraits>& stream,
const T& container) {
488 return stream << ::Rivet::pretty_print::print_container_helper<T, TChar, TCharTraits>(container);
double p(const ParticleBase &p)
Unbound function access to p.
Definition ParticleBaseUtils.hh:819
Definition LHCbCommon.hh:9
std::ostream & operator<<(std::ostream &os, const AnalysisInfo &ai)
Stream an AnalysisInfo as a text description.
Definition AnalysisInfo.hh:463