Vc 1.4.3
SIMD Vector Classes for C++
 
Loading...
Searching...
No Matches
IO
1/* This file is part of the Vc library. {{{
2Copyright © 2009-2015 Matthias Kretz <kretz@kde.org>
3
4Redistribution and use in source and binary forms, with or without
5modification, 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
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22ON 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
24SOFTWARE, 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
45namespace Vc_VERSIONED_NAMESPACE
46{
47namespace
48{
49#ifdef Vc_HACK_OSTREAM_FOR_TTY
50class hacked_ostream : public std::ostream
51{
52public:
53 using std::ostream::_M_streambuf;
54};
55bool mayUseColor(const std::ostream &os) __attribute__((__const__));
56bool 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
69bool mayUseColor(const std::ostream &) { return false; }
70#endif
71} // anonymous namespace
72
73namespace AnsiColor
74{
75struct Type
76{
77 const char *data;
78};
79static const Type green = {"\033[1;40;32m"};
80static const Type yellow = {"\033[1;40;33m"};
81static const Type blue = {"\033[1;40;34m"};
82static const Type normal = {"\033[0m"};
83
84inline 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 */
116template <typename T, typename Abi>
117inline 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
145m[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 */
156template <typename T, typename Abi>
157inline 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
174namespace 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 */
204template<typename V, typename Parent, typename Dimension, typename RM>
205inline std::ostream &operator<<(std::ostream &s, const Vc::MemoryBase<V, Parent, Dimension, RM> &m);
206#endif
207
208template<typename V, typename Parent, typename RM>
209inline 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
219template<typename V, typename Parent, typename RM>
220inline 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
237template<typename T, std::size_t N>
238inline 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
248template<typename T, std::size_t N>
249inline 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