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