re PR libstdc++/48760 (std::complex constructor buggy in the face of NaN's)
[gcc.git] / libstdc++-v3 / include / parallel / multiway_merge.h
index 4238a1c6923f3ddd392ea46a95dd5614e9afaba9..1c73ad0042db8b93acbc8c57483c9b25fad9bfa0 100644 (file)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 
-// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010, 2011 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
@@ -108,7 +108,7 @@ namespace __gnu_parallel
       /** @brief Compare two elements referenced by guarded iterators.
        *  @param __bi1 First iterator.
        *  @param __bi2 Second iterator.
-       *  @return @__c true if less. */
+       *  @return @c true if less. */
       friend bool
       operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
                _GuardedIterator<_RAIter, _Compare>& __bi2)
@@ -123,7 +123,7 @@ namespace __gnu_parallel
       /** @brief Compare two elements referenced by guarded iterators.
        *  @param __bi1 First iterator.
        *  @param __bi2 Second iterator.
-       *  @return @__c True if less equal. */
+       *  @return @c True if less equal. */
       friend bool
       operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
                 _GuardedIterator<_RAIter, _Compare>& __bi2)
@@ -143,7 +143,7 @@ namespace __gnu_parallel
       /** @brief Current iterator __position. */
       _RAIter _M_current;
       /** @brief _Compare. */
-      mutable _Compare& __comp;
+      _Compare& __comp;
 
     public:
       /** @brief Constructor. Sets iterator to beginning of sequence.
@@ -178,7 +178,7 @@ namespace __gnu_parallel
       /** @brief Compare two elements referenced by unguarded iterators.
        *  @param __bi1 First iterator.
        *  @param __bi2 Second iterator.
-       *  @return @__c true if less. */
+       *  @return @c true if less. */
       friend bool
       operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1,
                _UnguardedIterator<_RAIter, _Compare>& __bi2)
@@ -190,7 +190,7 @@ namespace __gnu_parallel
       /** @brief Compare two elements referenced by unguarded iterators.
        *  @param __bi1 First iterator.
        *  @param __bi2 Second iterator.
-       *  @return @__c True if less equal. */
+       *  @return @c True if less equal. */
       friend bool
       operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1,
                 _UnguardedIterator<_RAIter, _Compare>& __bi2)
@@ -210,7 +210,7 @@ namespace __gnu_parallel
    *
    * This works well for merging up to 4 sequences.
    *
-   * Note that making the merging stable does <em>not</em> come at a
+   * Note that making the merging stable does @a not come at a
    * performance hit.
    *
    * Whether the merging is done guarded or unguarded is selected by the
@@ -329,7 +329,7 @@ namespace __gnu_parallel
    *
    * This works well for merging up to 4 sequences.
    *
-   * Note that making the merging stable does <em>not</em> come at a
+   * Note that making the merging stable does @a not come at a
    * performance hit.
    *
    * Whether the merging is done guarded or unguarded is selected by the
@@ -489,27 +489,29 @@ namespace __gnu_parallel
       _GLIBCXX_CALL(__length)
 
       typedef _DifferenceTp _DifferenceType;
+      typedef typename std::iterator_traits<_RAIterIterator>
+       ::difference_type _SeqNumber;
       typedef typename std::iterator_traits<_RAIterIterator>
        ::value_type::first_type
        _RAIter1;
       typedef typename std::iterator_traits<_RAIter1>::value_type
        _ValueType;
 
-      int __k = static_cast<int>(__seqs_end - __seqs_begin);
+      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
 
       _LT __lt(__k, __comp);
 
       // Default value for potentially non-default-constructible types.
-      _ValueType* __arbitrary_element = NULL;
+      _ValueType* __arbitrary_element = 0;
 
-      for (int __t = 0; __t < __k; ++__t)
+      for (_SeqNumber __t = 0; __t < __k; ++__t)
        {
-          if(__arbitrary_element == NULL
+          if(!__arbitrary_element
             && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0)
             __arbitrary_element = &(*__seqs_begin[__t].first);
        }
 
-      for (int __t = 0; __t < __k; ++__t)
+      for (_SeqNumber __t = 0; __t < __k; ++__t)
        {
           if (__seqs_begin[__t].first == __seqs_begin[__t].second)
             __lt.__insert_start(*__arbitrary_element, __t, true);
@@ -519,7 +521,7 @@ namespace __gnu_parallel
 
       __lt.__init();
 
-      int __source;
+      _SeqNumber __source;
 
       for (_DifferenceType __i = 0; __i < __length; ++__i)
        {
@@ -574,17 +576,19 @@ namespace __gnu_parallel
       _GLIBCXX_CALL(__length)
       typedef _DifferenceTp _DifferenceType;
 
+      typedef typename std::iterator_traits<_RAIterIterator>
+       ::difference_type _SeqNumber;
       typedef typename std::iterator_traits<_RAIterIterator>
        ::value_type::first_type
        _RAIter1;
       typedef typename std::iterator_traits<_RAIter1>::value_type
        _ValueType;
 
-      int __k = __seqs_end - __seqs_begin;
+      _SeqNumber __k = __seqs_end - __seqs_begin;
 
       _LT __lt(__k, __sentinel, __comp);
 
-      for (int __t = 0; __t < __k; ++__t)
+      for (_SeqNumber __t = 0; __t < __k; ++__t)
        {
 #if _GLIBCXX_ASSERTIONS
           _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
@@ -595,7 +599,7 @@ namespace __gnu_parallel
 
       __lt.__init();
 
-      int __source;
+      _SeqNumber __source;
 
 #if _GLIBCXX_ASSERTIONS
       _DifferenceType __i = 0;
@@ -862,8 +866,9 @@ namespace __gnu_parallel
           typename _DifferenceTp,
           typename _Compare>
     struct __multiway_merge_k_variant_sentinel_switch<false, __stable,
-                                                     _RAIterIterator, _RAIter3,
-                                                     _DifferenceTp, _Compare>
+                                                     _RAIterIterator,
+                                                     _RAIter3, _DifferenceTp,
+                                                     _Compare>
     {
       _RAIter3
       operator()(_RAIterIterator __seqs_begin,
@@ -920,6 +925,8 @@ namespace __gnu_parallel
       _GLIBCXX_CALL(__length)
 
       typedef _DifferenceTp _DifferenceType;
+      typedef typename std::iterator_traits<_RAIterIterator>
+       ::difference_type _SeqNumber;
       typedef typename std::iterator_traits<_RAIterIterator>
        ::value_type::first_type
        _RAIter1;
@@ -944,7 +951,7 @@ namespace __gnu_parallel
        return __target;
 
       _RAIter3 __return_target = __target;
-      int __k = static_cast<int>(__seqs_end - __seqs_begin);
+      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
 
       switch (__k)
        {
@@ -1029,6 +1036,8 @@ namespace __gnu_parallel
                                      _Compare __comp,
      std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
     {
+      typedef typename std::iterator_traits<_RAIterIterator>
+       ::difference_type _SeqNumber;
       typedef typename std::iterator_traits<_RAIterIterator>
        ::value_type::first_type
        _RAIter1;
@@ -1036,17 +1045,18 @@ namespace __gnu_parallel
        _ValueType;
 
       // __k sequences.
-      int __k = static_cast<int>(__seqs_end - __seqs_begin);
+      const _SeqNumber __k
+       = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);
 
-      int __num_threads = omp_get_num_threads();
+      const _ThreadIndex __num_threads = omp_get_num_threads();
 
-      _DifferenceType __num_samples =
+      const _DifferenceType __num_samples =
        __gnu_parallel::_Settings::get().merge_oversampling * __num_threads;
 
       _ValueType* __samples = static_cast<_ValueType*>
        (::operator new(sizeof(_ValueType) * __k * __num_samples));
       // Sample.
-      for (int __s = 0; __s < __k; ++__s)
+      for (_SeqNumber __s = 0; __s < __k; ++__s)
        for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
          {
            _DifferenceType sample_index = static_cast<_DifferenceType>
@@ -1062,9 +1072,9 @@ namespace __gnu_parallel
       _SamplingSorter<__stable, _ValueType*, _Compare>()
        (__samples, __samples + (__num_samples * __k), __comp);
 
-      for (int __slab = 0; __slab < __num_threads; ++__slab)
+      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
        // For each slab / processor.
-       for (int __seq = 0; __seq < __k; ++__seq)
+       for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
          {
            // For each sequence.
            if (__slab > 0)
@@ -1087,6 +1097,10 @@ namespace __gnu_parallel
              __pieces[__slab][__seq].second =
                _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
          }
+
+      for (_SeqNumber __s = 0; __s < __k; ++__s)
+       for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
+         __samples[__s * __num_samples + __i].~_ValueType();
       ::operator delete(__samples);
     }
 
@@ -1107,6 +1121,8 @@ namespace __gnu_parallel
                                   _Compare __comp,
        std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
     {
+      typedef typename std::iterator_traits<_RAIterIterator>
+       ::difference_type _SeqNumber;
       typedef typename std::iterator_traits<_RAIterIterator>
        ::value_type::first_type
        _RAIter1;
@@ -1114,9 +1130,9 @@ namespace __gnu_parallel
       const bool __tight = (__total_length == __length);
 
       // __k sequences.
-      const int __k = static_cast<int>(__seqs_end - __seqs_begin);
+      const _SeqNumber __k = __seqs_end - __seqs_begin;
 
-      const int __num_threads = omp_get_num_threads();
+      const _ThreadIndex __num_threads = omp_get_num_threads();
 
       // (Settings::multiway_merge_splitting
       //  == __gnu_parallel::_Settings::EXACT).
@@ -1128,9 +1144,9 @@ namespace __gnu_parallel
 
       _DifferenceType* __borders =
        new _DifferenceType[__num_threads + 1];
-      equally_split(__length, __num_threads, __borders);
+      __equally_split(__length, __num_threads, __borders);
 
-      for (int __s = 0; __s < (__num_threads - 1); ++__s)
+      for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s)
        {
          __offsets[__s].resize(__k);
          multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1],
@@ -1148,10 +1164,10 @@ namespace __gnu_parallel
        }
       delete[] __borders;
 
-      for (int __slab = 0; __slab < __num_threads; ++__slab)
+      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
        {
          // For each slab / processor.
-         for (int __seq = 0; __seq < __k; ++__seq)
+         for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
            {
              // For each sequence.
              if (__slab == 0)
@@ -1218,6 +1234,8 @@ namespace __gnu_parallel
        _GLIBCXX_CALL(__length)
 
        typedef _DifferenceTp _DifferenceType;
+        typedef typename std::iterator_traits<_RAIterIterator>
+         ::difference_type _SeqNumber;
        typedef typename std::iterator_traits<_RAIterIterator>
           ::value_type::first_type
           _RAIter1;
@@ -1227,7 +1245,7 @@ namespace __gnu_parallel
        // Leave only non-empty sequences.
        typedef std::pair<_RAIter1, _RAIter1> seq_type;
        seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin];
-       int __k = 0;
+       _SeqNumber __k = 0;
        _DifferenceType __total_length = 0;
        for (_RAIterIterator __raii = __seqs_begin;
              __raii != __seqs_end; ++__raii)
@@ -1245,10 +1263,10 @@ namespace __gnu_parallel
        __length = std::min<_DifferenceTp>(__length, __total_length);
 
        if (__total_length == 0 || __k == 0)
-       {
-          delete[] __ne_seqs;
-          return __target;
-       }
+         {
+           delete[] __ne_seqs;
+           return __target;
+         }
 
        std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;
 
@@ -1263,7 +1281,7 @@ namespace __gnu_parallel
            // Thread __t will have to merge pieces[__iam][0..__k - 1]
            __pieces = new std::vector<
            std::pair<_DifferenceType, _DifferenceType> >[__num_threads];
-           for (int __s = 0; __s < __num_threads; ++__s)
+           for (_ThreadIndex __s = 0; __s < __num_threads; ++__s)
              __pieces[__s].resize(__k);
 
            _DifferenceType __num_samples =
@@ -1278,12 +1296,12 @@ namespace __gnu_parallel
 
          _DifferenceType __target_position = 0;
 
-         for (int __c = 0; __c < __k; ++__c)
+         for (_SeqNumber __c = 0; __c < __k; ++__c)
            __target_position += __pieces[__iam][__c].first;
 
          seq_type* __chunks = new seq_type[__k];
 
-         for (int __s = 0; __s < __k; ++__s)
+         for (_SeqNumber __s = 0; __s < __k; ++__s)
            __chunks[__s] = std::make_pair(__ne_seqs[__s].first
                                           + __pieces[__iam][__s].first,
                                           __ne_seqs[__s].first
@@ -1724,7 +1742,7 @@ namespace __gnu_parallel
    * @pre All input sequences must be sorted.
    * @pre Target must provide enough space to merge out length elements or
    *    the number of elements in all sequences, whichever is smaller.
-   * @pre For each @__c __i, @__c __seqs_begin[__i].second must be the end
+   * @pre For each @c __i, @c __seqs_begin[__i].second must be the end
    *    marker of the sequence, but also reference the one more __sentinel
    *    element.
    *