Viewing file: simd_view.h (3.17 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// Copyright (C) 2020-2022 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>.
#ifndef VC_TESTS_SIMD_VIEW_H_ #define VC_TESTS_SIMD_VIEW_H_
#include <experimental/simd>
_GLIBCXX_SIMD_BEGIN_NAMESPACE
namespace experimental { namespace imported_begin_end { using std::begin; using std::end;
template <class T> using begin_type = decltype(begin(std::declval<T>()));
template <class T> using end_type = decltype(end(std::declval<T>())); } // namespace imported_begin_end
template <class V, class It, class End> class viewer { It it; const End end;
template <class F> void for_each_impl(F &&fun, std::index_sequence<0, 1, 2>) { for (; it + V::size() <= end; it += V::size()) { fun(V([&](auto i) { return std::get<0>(it[i].as_tuple()); }), V([&](auto i) { return std::get<1>(it[i].as_tuple()); }), V([&](auto i) { return std::get<2>(it[i].as_tuple()); })); } if (it != end) { fun(V([&](auto i) { auto ii = it + i < end ? i + 0 : 0; return std::get<0>(it[ii].as_tuple()); }), V([&](auto i) { auto ii = it + i < end ? i + 0 : 0; return std::get<1>(it[ii].as_tuple()); }), V([&](auto i) { auto ii = it + i < end ? i + 0 : 0; return std::get<2>(it[ii].as_tuple()); })); } }
template <class F> void for_each_impl(F &&fun, std::index_sequence<0, 1>) { for (; it + V::size() <= end; it += V::size()) { fun(V([&](auto i) { return std::get<0>(it[i].as_tuple()); }), V([&](auto i) { return std::get<1>(it[i].as_tuple()); })); } if (it != end) { fun(V([&](auto i) { auto ii = it + i < end ? i + 0 : 0; return std::get<0>(it[ii].as_tuple()); }), V([&](auto i) { auto ii = it + i < end ? i + 0 : 0; return std::get<1>(it[ii].as_tuple()); })); } }
public: viewer(It _it, End _end) : it(_it), end(_end) {}
template <class F> void for_each(F &&fun) { constexpr size_t N = std::tuple_size<std::decay_t<decltype(it->as_tuple())>>::value; for_each_impl(std::forward<F>(fun), std::make_index_sequence<N>()); } };
template <class V, class Cont> viewer<V, imported_begin_end::begin_type<const Cont &>, imported_begin_end::end_type<const Cont &>> simd_view(const Cont &data) { using std::begin; using std::end; return {begin(data), end(data)}; } } // namespace experimental _GLIBCXX_SIMD_END_NAMESPACE
#endif // VC_TESTS_SIMD_VIEW_H_
|