| 313 | */ |
| 314 | template <typename T> |
| 315 | void print_consecutive_elements_impl( |
| 316 | std::ostream &s, const T *ptr, unsigned int n, int stream_width = 0, const std::string &element_delim = " ") |
| 317 | { |
| 318 | using print_type = typename std::conditional<std::is_floating_point<T>::value, T, int>::type; |
| 319 | std::ios stream_status(nullptr); |
| 320 | stream_status.copyfmt(s); |
| 321 | |
| 322 | for (unsigned int i = 0; i < n; ++i) |
| 323 | { |
| 324 | // Set stream width as it is not a "sticky" stream manipulator |
| 325 | if (stream_width != 0) |
| 326 | { |
| 327 | s.width(stream_width); |
| 328 | } |
| 329 | |
| 330 | if (std::is_same<typename std::decay<T>::type, half>::value) |
| 331 | { |
| 332 | // We use T instead of print_type here is because the std::is_floating_point<half> returns false and then the print_type becomes int. |
| 333 | s << std::right << static_cast<T>(ptr[i]) << element_delim; |
| 334 | } |
| 335 | else if (std::is_same<typename std::decay<T>::type, bfloat16>::value) |
| 336 | { |
| 337 | // We use T instead of print_type here is because the std::is_floating_point<bfloat16> returns false and then the print_type becomes int. |
| 338 | s << std::right << float(ptr[i]) << element_delim; |
| 339 | } |
| 340 | else |
| 341 | { |
| 342 | s << std::right << static_cast<print_type>(ptr[i]) << element_delim; |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | // Restore output stream flags |
| 347 | s.copyfmt(stream_status); |
| 348 | } |
| 349 | |
| 350 | /** Identify the maximum width of n consecutive elements. |
| 351 | * |