(root)/
gcc-13.2.0/
libstdc++-v3/
testsuite/
experimental/
simd/
tests/
bits/
simd_view.h
       1  // Copyright (C) 2020-2023 Free Software Foundation, Inc.
       2  //
       3  // This file is part of the GNU ISO C++ Library.  This library is free
       4  // software; you can redistribute it and/or modify it under the
       5  // terms of the GNU General Public License as published by the
       6  // Free Software Foundation; either version 3, or (at your option)
       7  // any later version.
       8  //
       9  // This library is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  //
      14  // You should have received a copy of the GNU General Public License along
      15  // with this library; see the file COPYING3.  If not see
      16  // <http://www.gnu.org/licenses/>.
      17  
      18  #ifndef VC_TESTS_SIMD_VIEW_H_
      19  #define VC_TESTS_SIMD_VIEW_H_
      20  
      21  #include <experimental/simd>
      22  
      23  _GLIBCXX_SIMD_BEGIN_NAMESPACE
      24  
      25  namespace experimental
      26  {
      27    namespace imported_begin_end
      28    {
      29      using std::begin;
      30      using std::end;
      31  
      32      template <class T>
      33        using begin_type = decltype(begin(std::declval<T>()));
      34  
      35      template <class T>
      36        using end_type = decltype(end(std::declval<T>()));
      37    }  // namespace imported_begin_end
      38  
      39    template <class V, class It, class End>
      40      class viewer
      41      {
      42        It it;
      43        const End end;
      44  
      45        template <class F>
      46  	void
      47  	for_each_impl(F &&fun, std::index_sequence<0, 1, 2>)
      48  	{
      49  	  for (; it + V::size() <= end; it += V::size())
      50  	    {
      51  	      fun(V([&](auto i) { return std::get<0>(it[i].as_tuple()); }),
      52  		  V([&](auto i) { return std::get<1>(it[i].as_tuple()); }),
      53  		  V([&](auto i) { return std::get<2>(it[i].as_tuple()); }));
      54  	    }
      55  	  if (it != end)
      56  	    {
      57  	      fun(V([&](auto i)
      58  	      {
      59  		auto ii = it + i < end ? i + 0 : 0;
      60  		return std::get<0>(it[ii].as_tuple());
      61  	      }),
      62  		  V([&](auto i) {
      63  		    auto ii = it + i < end ? i + 0 : 0;
      64  		    return std::get<1>(it[ii].as_tuple());
      65  		  }),
      66  		  V([&](auto i) {
      67  		    auto ii = it + i < end ? i + 0 : 0;
      68  		    return std::get<2>(it[ii].as_tuple());
      69  		  }));
      70  	    }
      71  	}
      72  
      73        template <class F>
      74  	void
      75  	for_each_impl(F &&fun, std::index_sequence<0, 1>)
      76  	{
      77  	  for (; it + V::size() <= end; it += V::size())
      78  	    {
      79  	      fun(V([&](auto i) { return std::get<0>(it[i].as_tuple()); }),
      80  		  V([&](auto i) { return std::get<1>(it[i].as_tuple()); }));
      81  	    }
      82  	  if (it != end)
      83  	    {
      84  	      fun(V([&](auto i) {
      85  		auto ii = it + i < end ? i + 0 : 0;
      86  		return std::get<0>(it[ii].as_tuple());
      87  	      }),
      88  		  V([&](auto i) {
      89  		    auto ii = it + i < end ? i + 0 : 0;
      90  		    return std::get<1>(it[ii].as_tuple());
      91  		  }));
      92  	    }
      93  	}
      94  
      95      public:
      96        viewer(It _it, End _end)
      97        : it(_it), end(_end) {}
      98  
      99        template <class F>
     100  	void
     101  	for_each(F &&fun)
     102  	{
     103  	  constexpr size_t N
     104  	    = std::tuple_size<std::decay_t<decltype(it->as_tuple())>>::value;
     105  	  for_each_impl(std::forward<F>(fun), std::make_index_sequence<N>());
     106  	}
     107      };
     108  
     109    template <class V, class Cont>
     110      viewer<V, imported_begin_end::begin_type<const Cont &>,
     111  	   imported_begin_end::end_type<const Cont &>>
     112      simd_view(const Cont &data)
     113      {
     114        using std::begin;
     115        using std::end;
     116        return {begin(data), end(data)};
     117      }
     118  }  // namespace experimental
     119  _GLIBCXX_SIMD_END_NAMESPACE
     120  
     121  #endif  // VC_TESTS_SIMD_VIEW_H_