Skip to content
Snippets Groups Projects
Commit b7598f60 authored by Jö Fahlke's avatar Jö Fahlke
Browse files

[SIMD] Provide ostream inserters.

Apparently, output of Vc vectors does not work with libc++.  I suspect it has
to do with some hackery Vc does in relation to the standard output streams.

This introduces syntax like
```c++
  std::cout << Dune::Simd::io(simd_vec) << std::endl;
  std::cout << Dune::Simd::vio(simd_vec) << std::endl;
```
to produce output like
```
<1, 2, 3, 4>
```

The difference between the two versions is that `io()` will skip the angle
bracket for one-component vectors, while `vio()` will always print them.
parent 2d104413
Branches
Tags
1 merge request!551[SIMD] Provide ostream inserters.
Pipeline #10543 passed
......@@ -5,6 +5,7 @@ install(FILES
base.hh
defaults.hh
interface.hh
io.hh
loop.hh
simd.hh
standard.hh
......
#ifndef DUNE_COMMON_SIMD_IO_HH
#define DUNE_COMMON_SIMD_IO_HH
/** @file
* @brief IO interface of the SIMD abstraction
* @ingroup SIMDLib
*
* This file provides IO interface functions of the SIMD abstraction layer.
*
* This file is intended for direct inclusion by header making use of the IO
* interface.
*/
#include <ios>
#include <type_traits>
#include <dune/common/rangeutilities.hh>
#include <dune/common/simd/simd.hh>
#include <dune/common/typetraits.hh>
namespace Dune {
namespace SimdImpl {
template<class T>
class Inserter {
T value_;
public:
Inserter(T value) : value_(value) {}
template<class Stream,
class = std::enable_if_t<std::is_base_of<std::ios_base,
Stream>::value> >
friend Stream& operator<<(Stream &out, const Inserter &ins)
{
const char *sep = "<";
for(auto l : range(Simd::lanes(ins.value_)))
{
out << sep << autoCopy(Simd::lane(l, ins.value_));
sep = ", ";
}
out << '>';
return out;
}
};
template<class V, class = std::enable_if_t<Simd::lanes<V>() != 1> >
Inserter<V> io(const V &v)
{
return { v };
}
template<class V, class = std::enable_if_t<Simd::lanes<V>() == 1> >
Simd::Scalar<V> io(const V &v)
{
return Simd::lane(0, v);
}
}
namespace Simd {
/** @addtogroup SIMDLib
*
* @{
*
*/
/** @name IO interface
*
* Templates and functions in this group provide syntactic sugar for IO.
* They are implemented using the functionality from @ref
* SimdInterfaceBase, and are not customizable by implementations.
*
* @{
*/
//! construct a stream inserter
/**
* \tparam V The SIMD (mask or vector) type.
*
* Construct an object that can be inserted into an output stream.
* Insertion prints the vector values seperated by a comma and a space,
* and surrounded by angular brackets.
*/
template<class V>
auto vio(const V &v)
{
return SimdImpl::Inserter<V>{ v };
}
//! construct a stream inserter
/**
* \tparam V The SIMD (mask or vector) type.
*
* Construct an object that can be inserted into an output stream. For
* one-lane vectors, behaves the same as scalar insertion. For multi-lane
* vectors, behaves as the inserter returned by `vio()`: insertion prints
* the vector values seperated by a comma and a space, and surrounded by
* angular brackets.
*/
template<class V>
auto io(const V &v)
{
return SimdImpl::io(v);
}
//! @} group IO interface
//! @} Group SIMDLib
} // namespace Simd
} // namespace Dune
#endif // DUNE_COMMON_SIMD_IO_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment