1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29 
30 #pragma once
31 
32 // appleseed.foundation headers.
33 #include "foundation/image/color.h"
34 #include "foundation/image/regularspectrum.h"
35 #include "foundation/math/aabb.h"
36 #include "foundation/math/matrix.h"
37 #include "foundation/math/quaternion.h"
38 #include "foundation/math/ray.h"
39 #include "foundation/math/transform.h"
40 #include "foundation/math/vector.h"
41 #include "foundation/utility/api/apistring.h"
42 #include "foundation/utility/api/specializedapiarrays.h"
43 #include "foundation/utility/string.h"
44 
45 // Standard headers.
46 #include <cstddef>
47 #include <iostream>
48 #include <string>
49 #include <vector>
50 
51 namespace std
52 {
53 
54 //
55 // I/O of common standard types from/to C++ streams.
56 //
57 
58 // std::vector.
59 template <typename Type, typename Allocator>
60 std::ostream& operator<<(std::ostream& s, const std::vector<Type, Allocator>& vector);
61 template <typename Allocator>
62 std::ostream& operator<<(std::ostream& s, const std::vector<std::string, Allocator>& vector);
63 template <typename Allocator>
64 std::ostream& operator<<(std::ostream& s, const std::vector<char*, Allocator>& vector);
65 template <typename Allocator>
66 std::ostream& operator<<(std::ostream& s, const std::vector<const char*, Allocator>& vector);
67 
68 }   // namespace std
69 
70 
71 //
72 // I/O of common appleseed types from/to C++ streams.
73 //
74 
75 namespace foundation
76 {
77 
78 // foundation::AABB.
79 template <typename T, size_t N>
80 std::ostream& operator<<(std::ostream& s, const AABBBase<T, N>& aabb);
81 template <typename T, size_t N>
82 std::istream& operator>>(std::istream& s, AABBBase<T, N>& aabb);
83 
84 // foundation::APIString.
85 std::ostream& operator<<(std::ostream& s, const APIString& string);
86 
87 // foundation::Array.
88 std::ostream& operator<<(std::ostream& s, const FloatArray& array);
89 std::istream& operator>>(std::istream& s, FloatArray& array);
90 std::ostream& operator<<(std::ostream& s, const DoubleArray& array);
91 std::istream& operator>>(std::istream& s, DoubleArray& array);
92 
93 // foundation::Color.
94 template <typename T, size_t N>
95 std::ostream& operator<<(std::ostream& s, const Color<T, N>& color);
96 template <typename T, size_t N>
97 std::istream& operator>>(std::istream& s, Color<T, N>& color);
98 
99 // foundation::Matrix.
100 template <typename T, size_t M, size_t N>
101 std::ostream& operator<<(std::ostream& s, const Matrix<T, M, N>& matrix);
102 template <typename T, size_t M, size_t N>
103 std::istream& operator>>(std::istream& s, Matrix<T, M, N>& matrix);
104 
105 // foundation::Quaternion.
106 template <typename T>
107 std::ostream& operator<<(std::ostream& s, const Quaternion<T>& quat);
108 template <typename T>
109 std::istream& operator>>(std::istream& s, Quaternion<T>& quat);
110 
111 // foundation::Ray.
112 template <typename T, size_t N>
113 std::ostream& operator<<(std::ostream& s, const Ray<T, N>& ray);
114 template <typename T, size_t N>
115 std::istream& operator>>(std::istream& s, Ray<T, N>& ray);
116 
117 // foundation::RegularSpectrum.
118 template <typename T, size_t N>
119 std::ostream& operator<<(std::ostream& s, const RegularSpectrum<T, N>& spectrum);
120 template <typename T, size_t N>
121 std::istream& operator>>(std::istream& s, RegularSpectrum<T, N>& spectrum);
122 
123 // foundation::Transform.
124 template <typename T>
125 std::ostream& operator<<(std::ostream& s, const Transform<T>& transform);
126 
127 // foundation::Vector.
128 template <typename T, size_t N>
129 std::ostream& operator<<(std::ostream& s, const Vector<T, N>& vector);
130 template <typename T, size_t N>
131 std::istream& operator>>(std::istream& s, Vector<T, N>& vector);
132 
133 }   // namespace foundation
134 
135 
136 //
137 // Helper functions.
138 //
139 
140 namespace foundation
141 {
142 namespace impl
143 {
144 
145     template <typename Sequence>
write_sequence(std::ostream & s,const Sequence & sequence,const size_t n)146     std::ostream& write_sequence(std::ostream& s, const Sequence& sequence, const size_t n)
147     {
148         if (n > 0)
149         {
150             for (size_t i = 0; i < n - 1; ++i)
151                 s << sequence[i] << ' ';
152             s << sequence[n - 1];
153         }
154 
155         return s;
156     }
157 
158     template <typename Sequence>
write_sequence_quotes(std::ostream & s,const Sequence & sequence,const size_t n)159     std::ostream& write_sequence_quotes(std::ostream& s, const Sequence& sequence, const size_t n)
160     {
161         if (n > 0)
162         {
163             for (size_t i = 0; i < n - 1; ++i)
164                 s << "\"" << sequence[i] << "\" ";
165             s << "\"" << sequence[n - 1] << "\"";
166         }
167 
168         return s;
169     }
170 
171     template <typename Sequence>
read_sequence(std::istream & s,Sequence & sequence,const size_t n)172     std::istream& read_sequence(std::istream& s, Sequence& sequence, const size_t n)
173     {
174         for (size_t i = 0; i < n; ++i)
175             s >> sequence[i];
176 
177         return s;
178     }
179 
180 }   // namespace impl
181 }   // namespace foundation
182 
183 
184 //
185 // std::vector.
186 //
187 
188 namespace std
189 {
190 
191 template <typename Type, typename Allocator>
192 std::ostream& operator<<(std::ostream& s, const std::vector<Type, Allocator>& vector)
193 {
194     return foundation::impl::write_sequence(s, vector, vector.size());
195 }
196 
197 template <typename Allocator>
198 std::ostream& operator<<(std::ostream& s, const std::vector<std::string, Allocator>& vector)
199 {
200     return foundation::impl::write_sequence_quotes(s, vector, vector.size());
201 }
202 
203 template <typename Allocator>
204 std::ostream& operator<<(std::ostream& s, const std::vector<char*, Allocator>& vector)
205 {
206     return foundation::impl::write_sequence_quotes(s, vector, vector.size());
207 }
208 
209 template <typename Allocator>
210 std::ostream& operator<<(std::ostream& s, const std::vector<const char*, Allocator>& vector)
211 {
212     return foundation::impl::write_sequence_quotes(s, vector, vector.size());
213 }
214 
215 }   // namespace std
216 
217 
218 namespace foundation
219 {
220 
221 //
222 // foundation::AABB.
223 //
224 
225 template <typename T, size_t N>
226 std::ostream& operator<<(std::ostream& s, const AABBBase<T, N>& aabb)
227 {
228     return s << aabb.min << ' ' << aabb.max;
229 }
230 
231 template <typename T, size_t N>
232 std::istream& operator>>(std::istream& s, AABBBase<T, N>& aabb)
233 {
234     s >> aabb.min;
235     s >> aabb.max;
236     return s;
237 }
238 
239 
240 //
241 // foundation::APIString.
242 //
243 
244 inline std::ostream& operator<<(std::ostream& s, const APIString& string)
245 {
246     return s << string.c_str();
247 }
248 
249 namespace impl
250 {
251     template <typename ArrayType>
read_array(std::istream & s,ArrayType & array)252     std::istream& read_array(std::istream& s, ArrayType& array)
253     {
254         std::string token;
255 
256         while (s >> token)
257             array.push_back(from_string<typename ArrayType::value_type>(token));
258 
259         // Clear the fail bit, reaching the end of the file is not an error.
260         if (s.eof())
261             s.clear(s.rdstate() & ~std::ios::failbit);
262 
263         return s;
264     }
265 }
266 
267 
268 //
269 // foundation::Array.
270 //
271 
272 inline std::ostream& operator<<(std::ostream& s, const FloatArray& array)
273 {
274     return impl::write_sequence(s, array, array.size());
275 }
276 
277 inline std::istream& operator>>(std::istream& s, FloatArray& array)
278 {
279     return impl::read_array(s, array);
280 }
281 
282 inline std::ostream& operator<<(std::ostream& s, const DoubleArray& array)
283 {
284     return impl::write_sequence(s, array, array.size());
285 }
286 
287 inline std::istream& operator>>(std::istream& s, DoubleArray& array)
288 {
289     return impl::read_array(s, array);
290 }
291 
292 
293 //
294 // foundation::Color.
295 //
296 
297 template <typename T, size_t N>
298 std::ostream& operator<<(std::ostream& s, const Color<T, N>& color)
299 {
300     return impl::write_sequence(s, color, N);
301 }
302 
303 template <typename T, size_t N>
304 std::istream& operator>>(std::istream& s, Color<T, N>& color)
305 {
306     return impl::read_sequence(s, color, N);
307 }
308 
309 
310 //
311 // foundation::Matrix.
312 //
313 
314 template <typename T, size_t M, size_t N>
315 std::ostream& operator<<(std::ostream& s, const Matrix<T, M, N>& matrix)
316 {
317     return impl::write_sequence(s, matrix, M * N);
318 }
319 
320 template <typename T, size_t M, size_t N>
321 std::istream& operator>>(std::istream& s, Matrix<T, M, N>& matrix)
322 {
323     return impl::read_sequence(s, matrix, M * N);
324 }
325 
326 
327 //
328 // foundation::Quaternion.
329 //
330 
331 template <typename T>
332 std::ostream& operator<<(std::ostream& s, const Quaternion<T>& quat)
333 {
334     s << quat.s << ' ';
335     s << quat.v;
336     return s;
337 }
338 
339 template <typename T>
340 std::istream& operator>>(std::istream& s, Quaternion<T>& quat)
341 {
342     s >> quat.s;
343     s >> quat.v;
344     return s;
345 }
346 
347 
348 //
349 // foundation::Ray.
350 //
351 
352 template <typename T, size_t N>
353 std::ostream& operator<<(std::ostream& s, const Ray<T, N>& ray)
354 {
355     s << ray.m_org  << ' ';
356     s << ray.m_dir  << ' ';
357     s << ray.m_tmin << ' ';
358     s << ray.m_tmax;
359     return s;
360 }
361 
362 template <typename T, size_t N>
363 std::istream& operator>>(std::istream& s, Ray<T, N>& ray)
364 {
365     s = impl::read_sequence(s, ray.m_org, N);
366     s = impl::read_sequence(s, ray.m_dir, N);
367     s >> ray.m_tmin;
368     s >> ray.m_tmax;
369     return s;
370 }
371 
372 
373 //
374 // foundation::RegularSpectrum.
375 //
376 
377 template <typename T, size_t N>
378 std::ostream& operator<<(std::ostream& s, const RegularSpectrum<T, N>& spectrum)
379 {
380     return impl::write_sequence(s, spectrum, N);
381 }
382 
383 template <typename T, size_t N>
384 std::istream& operator>>(std::istream& s, RegularSpectrum<T, N>& spectrum)
385 {
386     return impl::read_sequence(s, spectrum, N);
387 }
388 
389 
390 //
391 // foundation::Transform.
392 //
393 
394 template <typename T>
395 std::ostream& operator<<(std::ostream& s, const Transform<T>& transform)
396 {
397     return s << transform.get_local_to_parent();
398 }
399 
400 
401 //
402 // foundation::Vector.
403 //
404 
405 template <typename T, size_t N>
406 std::ostream& operator<<(std::ostream& s, const Vector<T, N>& vector)
407 {
408     return impl::write_sequence(s, vector, N);
409 }
410 
411 template <typename T, size_t N>
412 std::istream& operator>>(std::istream& s, Vector<T, N>& vector)
413 {
414     return impl::read_sequence(s, vector, N);
415 }
416 
417 }   // namespace foundation
418