Vc  1.3.2-dev
SIMD Vector Classes for C++
IO
1 /* This file is part of the Vc library. {{{
2 Copyright © 2009-2015 Matthias Kretz <kretz@kde.org>
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6  * Redistributions of source code must retain the above copyright
7  notice, this list of conditions and the following disclaimer.
8  * Redistributions in binary form must reproduce the above copyright
9  notice, this list of conditions and the following disclaimer in the
10  documentation and/or other materials provided with the distribution.
11  * Neither the names of contributing organizations nor the
12  names of its contributors may be used to endorse or promote products
13  derived from this software without specific prior written permission.
14 
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 }}}*/
27 
28 #ifndef VC_IO_
29 #define VC_IO_
30 
31 #include "common/types.h"
32 #include "common/simdarrayfwd.h"
33 #include "common/memoryfwd.h"
34 #include <iostream>
35 
36 #if defined(__GNUC__) && !defined(_WIN32) && defined(_GLIBCXX_OSTREAM)
37 #define Vc_HACK_OSTREAM_FOR_TTY 1
38 #endif
39 
40 #ifdef Vc_HACK_OSTREAM_FOR_TTY
41 #include <unistd.h>
42 #include <ext/stdio_sync_filebuf.h>
43 #endif
44 
45 namespace Vc_VERSIONED_NAMESPACE
46 {
47 namespace
48 {
49 #ifdef Vc_HACK_OSTREAM_FOR_TTY
50 class hacked_ostream : public std::ostream
51 {
52 public:
53  using std::ostream::_M_streambuf;
54 };
55 bool mayUseColor(const std::ostream &os) __attribute__((__const__));
56 bool mayUseColor(const std::ostream &os)
57 {
58  std::basic_streambuf<char> *hack1 =
59  const_cast<std::basic_streambuf<char> *>(os.*(&hacked_ostream::_M_streambuf));
60  __gnu_cxx::stdio_sync_filebuf<char> *hack =
61  dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char> *>(hack1);
62  if (!hack) {
63  return false;
64  }
65  FILE *file = hack->file();
66  return 1 == isatty(fileno(file));
67 }
68 #else
69 bool mayUseColor(const std::ostream &) { return false; }
70 #endif
71 } // anonymous namespace
72 
73 namespace AnsiColor
74 {
75 struct Type
76 {
77  const char *data;
78 };
79 static const Type green = {"\033[1;40;32m"};
80 static const Type yellow = {"\033[1;40;33m"};
81 static const Type blue = {"\033[1;40;34m"};
82 static const Type normal = {"\033[0m"};
83 
84 inline std::ostream &operator<<(std::ostream &out, const Type &c)
85 {
86  if (mayUseColor(out)) {
87  out << c.data;
88  }
89  return out;
90 }
91 } // namespace AnsiColor
92 
93 /**
94  * \ingroup Vectors
95  * \headerfile IO <Vc/IO>
96  *
97  * Prints the contents of a vector into a stream object.
98  *
99  * \code
100  * const Vc::int_v v(Vc::IndexesFromZero);
101  * std::cout << v << std::endl;
102  * \endcode
103  * will output (with SSE):
104 \verbatim
105 [0, 1, 2, 3]
106 \endverbatim
107  *
108  * \param out Any standard C++ ostream object. For example std::cout or a
109  * std::stringstream object.
110  * \param v Any Vc::Vector object.
111  * \return The ostream object: to chain multiple stream operations.
112  *
113  * \note With the GNU standard library this function will check whether the
114  * output stream is a tty in which case it colorizes the output.
115  */
116 template <typename T, typename Abi>
117 inline std::ostream &operator<<(std::ostream &out, const Vc::Vector<T, Abi> &v)
118 {
119  using TT = typename std::conditional<std::is_same<T, char>::value ||
120  std::is_same<T, unsigned char>::value ||
121  std::is_same<T, signed char>::value,
122  int,
123  T>::type;
124  out << AnsiColor::green << '[';
125  out << TT(v[0]);
126  for (size_t i = 1; i < v.Size; ++i) {
127  out << ", " << TT(v[i]);
128  }
129  out << ']' << AnsiColor::normal;
130  return out;
131 }
132 
133 /**
134  * \ingroup Masks
135  * \headerfile IO <Vc/IO>
136  *
137  * Prints the contents of a mask into a stream object.
138  *
139  * \code
140  * const Vc::short_m m = Vc::short_v::IndexesFromZero() < 3;
141  * std::cout << m << std::endl;
142  * \endcode
143  * will output (with SSE):
144 \verbatim
145 m[1110 0000]
146 \endverbatim
147  *
148  * \param out Any standard C++ ostream object. For example std::cout or a
149  * std::stringstream object.
150  * \param m Any Vc::Mask object.
151  * \return The ostream object: to chain multiple stream operations.
152  *
153  * \note With the GNU standard library this function will check whether the
154  * output stream is a tty in which case it colorizes the output.
155  */
156 template <typename T, typename Abi>
157 inline std::ostream &operator<<(std::ostream &out, const Vc::Mask<T, Abi> &m)
158 {
159  out << AnsiColor::blue << "m[";
160  for (unsigned int i = 0; i < m.Size; ++i) {
161  if (i > 0 && (i % 4) == 0) {
162  out << ' ';
163  }
164  if (m[i]) {
165  out << AnsiColor::yellow << '1';
166  } else {
167  out << AnsiColor::blue << '0';
168  }
169  }
170  out << AnsiColor::blue << ']' << AnsiColor::normal;
171  return out;
172 }
173 
174 namespace Common
175 {
176 #ifdef DOXYGEN
177 /**
178  * \ingroup Utilities
179  * \headerfile dox.h <Vc/IO>
180  *
181  * Prints the contents of a Memory object into a stream object.
182  *
183  * \code
184  * Vc::Memory<int_v, 10> m;
185  * for (int i = 0; i < m.entriesCount(); ++i) {
186  * m[i] = i;
187  * }
188  * std::cout << m << std::endl;
189  * \endcode
190  * will output (with SSE):
191 \verbatim
192 {[0, 1, 2, 3] [4, 5, 6, 7] [8, 9, 0, 0]}
193 \endverbatim
194  *
195  * \param s Any standard C++ ostream object. For example std::cout or a std::stringstream object.
196  * \param m Any Vc::Memory object.
197  * \return The ostream object: to chain multiple stream operations.
198  *
199  * \note With the GNU standard library this function will check whether the
200  * output stream is a tty in which case it colorizes the output.
201  *
202  * \warning Please do not forget that printing a large memory object can take a long time.
203  */
204 template<typename V, typename Parent, typename Dimension, typename RM>
205 inline std::ostream &operator<<(std::ostream &s, const Vc::MemoryBase<V, Parent, Dimension, RM> &m);
206 #endif
207 
208 template<typename V, typename Parent, typename RM>
209 inline std::ostream &operator<<(std::ostream &out, const MemoryBase<V, Parent, 1, RM> &m )
210 {
211  out << AnsiColor::blue << '{' << AnsiColor::normal;
212  for (unsigned int i = 0; i < m.vectorsCount(); ++i) {
213  out << V(m.vector(i));
214  }
215  out << AnsiColor::blue << '}' << AnsiColor::normal;
216  return out;
217 }
218 
219 template<typename V, typename Parent, typename RM>
220 inline std::ostream &operator<<(std::ostream &out, const MemoryBase<V, Parent, 2, RM> &m )
221 {
222  out << AnsiColor::blue << '{' << AnsiColor::normal;
223  for (size_t i = 0; i < m.rowsCount(); ++i) {
224  if (i > 0) {
225  out << "\n ";
226  }
227  const size_t vcount = m[i].vectorsCount();
228  for (size_t j = 0; j < vcount; ++j) {
229  out << V(m[i].vector(j));
230  }
231  }
232  out << AnsiColor::blue << '}' << AnsiColor::normal;
233  return out;
234 }
235 } // namespace Common
236 
237 template<typename T, std::size_t N>
238 inline std::ostream &operator<<(std::ostream &out, const SimdArray<T, N> &v)
239 {
240  out << AnsiColor::green << '<' << v[0];
241  for (size_t i = 1; i < N; ++i) {
242  if (i % 4 == 0) out << " |";
243  out << ' ' << v[i];
244  }
245  return out << '>' << AnsiColor::normal;
246 }
247 
248 template<typename T, std::size_t N>
249 inline std::ostream &operator<<(std::ostream &out, const SimdMaskArray<T, N> &m)
250 {
251  out << AnsiColor::blue << "«";
252  for (size_t i = 0; i < N; ++i) {
253  if (i > 0 && (i % 4) == 0) {
254  out << ' ';
255  }
256  if ( m[i] ) {
257  out << AnsiColor::yellow << '1';
258  } else {
259  out << AnsiColor::blue << '0';
260  }
261  }
262  return out << AnsiColor::blue << "»" << AnsiColor::normal;
263 }
264 }
265 
266 #endif // VC_IO_
267 
268 // vim: ft=cpp foldmethod=marker