(root)/
gcc-13.2.0/
libstdc++-v3/
include/
pstl/
parallel_backend_utils.h
       1  // -*- C++ -*-
       2  //===-- parallel_backend_utils.h ------------------------------------------===//
       3  //
       4  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       5  // See https://llvm.org/LICENSE.txt for license information.
       6  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       7  //
       8  //===----------------------------------------------------------------------===//
       9  
      10  #ifndef _PSTL_PARALLEL_BACKEND_UTILS_H
      11  #define _PSTL_PARALLEL_BACKEND_UTILS_H
      12  
      13  #include <iterator>
      14  #include <utility>
      15  #include "utils.h"
      16  
      17  namespace __pstl
      18  {
      19  
      20  namespace __utils
      21  {
      22  
      23  //! Destroy sequence [xs,xe)
      24  struct __serial_destroy
      25  {
      26      template <typename _RandomAccessIterator>
      27      void
      28      operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
      29      {
      30          typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
      31          while (__zs != __ze)
      32          {
      33              --__ze;
      34              (*__ze).~_ValueType();
      35          }
      36      }
      37  };
      38  
      39  //! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
      40  struct __serial_move_merge
      41  {
      42      const std::size_t _M_nmerge;
      43  
      44      explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {}
      45      template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare,
      46                class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY>
      47      void
      48      operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
      49                 _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x,
      50                 _MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y)
      51      {
      52          constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value;
      53          constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value;
      54  
      55          auto __n = _M_nmerge;
      56          _PSTL_ASSERT(__n > 0);
      57  
      58          auto __nx = __xe - __xs;
      59          //auto __ny = __ye - __ys;
      60          _RandomAccessIterator3 __zs_beg = __zs;
      61  
      62          if (__xs != __xe)
      63          {
      64              if (__ys != __ye)
      65              {
      66                  for (;;)
      67                  {
      68                      if (__comp(*__ys, *__xs))
      69                      {
      70                          const auto __i = __zs - __zs_beg;
      71                          if (__i < __nx)
      72                              __move_value_x(__ys, __zs);
      73                          else
      74                              __move_value_y(__ys, __zs);
      75                          ++__zs, --__n;
      76                          if (++__ys == __ye)
      77                          {
      78                              break;
      79                          }
      80                          else if (__n == 0)
      81                          {
      82                              const auto __j = __zs - __zs_beg;
      83                              if (__same_move_seq || __j < __nx)
      84                                  __zs = __move_sequence_x(__ys, __ye, __zs);
      85                              else
      86                                  __zs = __move_sequence_y(__ys, __ye, __zs);
      87                              break;
      88                          }
      89                      }
      90                      else
      91                      {
      92                          const auto __i = __zs - __zs_beg;
      93                          if (__same_move_val || __i < __nx)
      94                              __move_value_x(__xs, __zs);
      95                          else
      96                              __move_value_y(__xs, __zs);
      97                          ++__zs, --__n;
      98                          if (++__xs == __xe)
      99                          {
     100                              const auto __j = __zs - __zs_beg;
     101                              if (__same_move_seq || __j < __nx)
     102                                  __move_sequence_x(__ys, __ye, __zs);
     103                              else
     104                                  __move_sequence_y(__ys, __ye, __zs);
     105                              return;
     106                          }
     107                          else if (__n == 0)
     108                          {
     109                              const auto __j = __zs - __zs_beg;
     110                              if (__same_move_seq || __j < __nx)
     111                              {
     112                                  __zs = __move_sequence_x(__xs, __xe, __zs);
     113                                  __move_sequence_x(__ys, __ye, __zs);
     114                              }
     115                              else
     116                              {
     117                                  __zs = __move_sequence_y(__xs, __xe, __zs);
     118                                  __move_sequence_y(__ys, __ye, __zs);
     119                              }
     120                              return;
     121                          }
     122                      }
     123                  }
     124              }
     125              __ys = __xs;
     126              __ye = __xe;
     127          }
     128          const auto __i = __zs - __zs_beg;
     129          if (__same_move_seq || __i < __nx)
     130              __move_sequence_x(__ys, __ye, __zs);
     131          else
     132              __move_sequence_y(__ys, __ye, __zs);
     133      }
     134  };
     135  
     136  template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
     137            typename _CopyConstructRange>
     138  _OutputIterator
     139  __set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
     140                        _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
     141                        _CopyConstructRange __cc_range)
     142  {
     143      using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
     144  
     145      for (; __first1 != __last1; ++__result)
     146      {
     147          if (__first2 == __last2)
     148              return __cc_range(__first1, __last1, __result);
     149          if (__comp(*__first2, *__first1))
     150          {
     151              ::new (std::addressof(*__result)) _Tp(*__first2);
     152              ++__first2;
     153          }
     154          else
     155          {
     156              ::new (std::addressof(*__result)) _Tp(*__first1);
     157              if (!__comp(*__first1, *__first2))
     158                  ++__first2;
     159              ++__first1;
     160          }
     161      }
     162      return __cc_range(__first2, __last2, __result);
     163  }
     164  
     165  template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare>
     166  _OutputIterator
     167  __set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
     168                               _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp)
     169  {
     170      using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
     171  
     172      for (; __first1 != __last1 && __first2 != __last2;)
     173      {
     174          if (__comp(*__first1, *__first2))
     175              ++__first1;
     176          else
     177          {
     178              if (!__comp(*__first2, *__first1))
     179              {
     180                  ::new (std::addressof(*__result)) _Tp(*__first1);
     181                  ++__result;
     182                  ++__first1;
     183              }
     184              ++__first2;
     185          }
     186      }
     187      return __result;
     188  }
     189  
     190  template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
     191            typename _CopyConstructRange>
     192  _OutputIterator
     193  __set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
     194                             _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
     195                             _CopyConstructRange __cc_range)
     196  {
     197      using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
     198  
     199      for (; __first1 != __last1;)
     200      {
     201          if (__first2 == __last2)
     202              return __cc_range(__first1, __last1, __result);
     203  
     204          if (__comp(*__first1, *__first2))
     205          {
     206              ::new (std::addressof(*__result)) _Tp(*__first1);
     207              ++__result;
     208              ++__first1;
     209          }
     210          else
     211          {
     212              if (!__comp(*__first2, *__first1))
     213                  ++__first1;
     214              ++__first2;
     215          }
     216      }
     217      return __result;
     218  }
     219  template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
     220            typename _CopyConstructRange>
     221  _OutputIterator
     222  __set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
     223                                       _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
     224                                       _CopyConstructRange __cc_range)
     225  {
     226      using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
     227  
     228      for (; __first1 != __last1;)
     229      {
     230          if (__first2 == __last2)
     231              return __cc_range(__first1, __last1, __result);
     232  
     233          if (__comp(*__first1, *__first2))
     234          {
     235              ::new (std::addressof(*__result)) _Tp(*__first1);
     236              ++__result;
     237              ++__first1;
     238          }
     239          else
     240          {
     241              if (__comp(*__first2, *__first1))
     242              {
     243                  ::new (std::addressof(*__result)) _Tp(*__first2);
     244                  ++__result;
     245              }
     246              else
     247                  ++__first1;
     248              ++__first2;
     249          }
     250      }
     251      return __cc_range(__first2, __last2, __result);
     252  }
     253  
     254  } // namespace __utils
     255  } // namespace __pstl
     256  
     257  #endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */