All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
prettyprint.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_IO_PRETTYPRINT_HPP
23 #define GEARS_IO_PRETTYPRINT_HPP
24 
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"
30 #include <iosfwd>
31 
32 namespace gears {
33 namespace io {
34 namespace detail {
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);
39  template<typename...>
40  static std::false_type test(...);
41 };
42 
43 template<typename T>
44 struct has_begin_end : decltype(has_begin_end_impl::test<T>(0)) {};
45 
46 struct has_get_impl {
47  template<typename T>
48  static auto test(int) -> decltype(adl::get<0>(std::declval<T>()), std::true_type{}) {}
49  template<typename...>
50  static std::false_type test(...);
51 };
52 
53 template<typename T>
54 struct has_get : decltype(has_get_impl::test<T>(0)) {};
55 
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));
59 }
60 } // detail
61 
62 namespace operators {
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) {
66  out << "(";
67  detail::print_expander(out, t, meta::build_indices<std::tuple_size<Tuple>::value>{});
68  out << ")";
69  return out;
70 }
71 
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) {
74  auto first = adl::begin(cont);
75  auto last = adl::end(cont);
76 
77  if(first == last) {
78  out << "[]";
79  return out;
80  }
81  else {
82  out << '[' << *first++;
83  }
84  while(first != last) {
85  out << ", " << *first++;
86  }
87 
88  out << ']';
89  return out;
90 }
91 } // operators
92 } // io
93 } // gears
94 
95 #endif // GEARS_IO_PRETTYPRINT_HPP