22 #ifndef GEARS_IO_PRETTYPRINT_HPP
23 #define GEARS_IO_PRETTYPRINT_HPP
25 #include "../meta/indices.hpp"
26 #include "../meta/alias.hpp"
27 #include "../meta/expand.hpp"
28 #include "../adl/get.hpp"
29 #include "../adl/iterator.hpp"
35 struct has_begin_end_impl {
36 template<
typename T,
typename B = decltype(std::declval<T&>().begin()),
37 typename E = decltype(std::declval<T&>().end())>
38 static std::true_type test(
int);
40 static std::false_type test(...);
44 struct has_begin_end : decltype(has_begin_end_impl::test<T>(0)) {};
48 static auto test(
int) -> decltype(adl::get<0>(std::declval<T>()), std::true_type{}) {}
50 static std::false_type test(...);
54 struct has_get : decltype(has_get_impl::test<T>(0)) {};
56 template<
typename Elem,
typename Traits,
typename Tuple,
size_t... Indices>
57 void print_expander(std::basic_ostream<Elem, Traits>& out,
const Tuple& t, meta::indices<Indices...>) noexcept {
58 GEARS_EXPAND(out << (!Indices ?
"" :
", ") << adl::get<Indices>(t));
63 template<
typename Elem,
typename Traits,
typename Tuple,
64 meta::EnableIf<detail::has_get<Tuple>, meta::Not<detail::has_begin_end<Tuple>>> = meta::_>
65 inline auto operator<<(std::basic_ostream<Elem, Traits>& out,
const Tuple& t) -> decltype(out) {
67 detail::print_expander(out, t, meta::build_indices<std::tuple_size<Tuple>::value>{});
72 template<
typename Elem,
typename Traits,
typename Cont, meta::EnableIf<detail::has_begin_end<Cont>> = meta::_>
73 inline auto operator<<(std::basic_ostream<Elem, Traits>& out,
const Cont& cont) -> decltype(out) {
82 out <<
'[' << *first++;
84 while(first != last) {
85 out <<
", " << *first++;
95 #endif // GEARS_IO_PRETTYPRINT_HPP