Advertisement
Radfler

::operator<<(tuple-like)

May 8th, 2016
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.39 KB | None | 0 0
  1. #include <array>
  2. #include <ostream>
  3. #include <tuple>
  4. #include <type_traits>
  5. #include <utility>
  6.  
  7. namespace details {
  8.  
  9.   template<typename>
  10.   struct is_tuple_like : std::false_type { };
  11.  
  12.   template<typename... Types>
  13.   struct is_tuple_like<std::tuple<Types...>> : std::true_type { };
  14.  
  15.   template<typename ValueType, std::size_t Size>
  16.   struct is_tuple_like<std::array<ValueType, Size>> : std::true_type { };
  17.  
  18.   template<typename T1, typename T2>
  19.   struct is_tuple_like<std::pair<T1, T2>> : std::true_type { };
  20.  
  21.   template<std::size_t Value>
  22.   using index_t = std::integral_constant<std::size_t, Value>;
  23.  
  24.   template<std::size_t Index, typename CharT, typename Traits, typename Type>
  25.   void print_tuple_element(index_t<Index>, std::basic_ostream<CharT, Traits>& stream, Type&& object) {
  26.     stream << ", " << std::forward<Type>(object);
  27.   }
  28.  
  29.   template<typename CharT, typename Traits, typename Type>
  30.   void print_tuple_element(index_t<0>, std::basic_ostream<CharT, Traits>& stream, Type&& object) {
  31.     stream << std::forward<Type>(object);
  32.   }
  33.  
  34.   template<typename CharT, typename Traits, typename Tuple, std::size_t... Indexes>
  35.   void print_tuple(std::basic_ostream<CharT, Traits>& ostream,
  36.                             Tuple&& tuple, std::index_sequence<Indexes...>) {
  37.    
  38.     using Swallow = bool[];
  39.    
  40.     ostream << '(';
  41.     Swallow{(print_tuple_element(index_t<Indexes>{}, ostream,
  42.                                  std::get<Indexes>(std::forward<Tuple>(tuple))), false)...};
  43.     ostream << ')';
  44.    
  45.   }
  46.    
  47.   // overload for empty tuple-like types
  48.   template<typename CharT, typename Traits, typename Tuple>
  49.   void print_tuple(std::basic_ostream<CharT, Traits>& ostream, Tuple&&, std::index_sequence<>) {
  50.     ostream << "()";
  51.   }
  52.  
  53.   template<typename T>
  54.   using enable_if_is_tuple = std::enable_if_t<is_tuple_like<std::decay_t<T>>::value>;
  55.  
  56.   template<typename Tuple>
  57.   using index_sequence_for_tuple = std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>;
  58.  
  59. }
  60.  
  61. template<typename CharT, typename Traits, typename Tuple, typename = details::enable_if_is_tuple<Tuple>>
  62. std::basic_ostream<CharT, Traits>&
  63. operator<<(std::basic_ostream<CharT, Traits>& ostream, Tuple&& tuple) {
  64.   using index_sequence = details::index_sequence_for_tuple<Tuple>;
  65.   details::print_tuple(ostream, std::forward<Tuple>(tuple), index_sequence{});
  66.   return ostream;
  67. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement