<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CSort.h,v $
   $Revision: 1.2 $
   $Name:  $
   $Author: shoops $ 
   $Date: 2005/09/26 21:03:33 $
   End CVS Header */

#ifndef COPASI_CSort
 #define COPASI_CSort

#include <algorithm>

#include "CVector.h"

template <typename RandomAccessIterator>
bool sortDefault(const std::pair<RandomAccessIterator, unsigned C_INT32> & lhs,
                 const std::pair<RandomAccessIterator, unsigned C_INT32> & rhs)
{return *lhs.first < *rhs.first;}

template <typename RandomAccessIterator>
void sortWithPivot(RandomAccessIterator first,
                   RandomAccessIterator last,
                   CVector<unsigned C_INT32> & pivot)
{
  assert(first < last);

  // Initialize the two column array to be sorted
  CVector<std::pair<RandomAccessIterator, unsigned C_INT32> > ToBeSorted;
  ToBeSorted.resize(last - first);

  RandomAccessIterator it;
  unsigned C_INT32 i;

  typename CVector<std::pair<RandomAccessIterator, unsigned C_INT32> >::elementType * itToBeSorted;

  for (it = first, i = 0, itToBeSorted = ToBeSorted.array();
       it != last;
       ++it, ++i, ++itToBeSorted)
    {
      itToBeSorted->first = it;
      itToBeSorted->second = i;
    }

  itToBeSorted = ToBeSorted.array();

  std::sort(itToBeSorted,
            itToBeSorted + (last - first),
            &sortDefault<RandomAccessIterator>);

  // Copy the resulting pivots to the pivot vector.
  pivot.resize(last - first);
  CVector<unsigned C_INT32>::elementType *itPivot = pivot.array();
  CVector<unsigned C_INT32>::elementType *endPivot = itPivot + (last - first);

  for (; itPivot != endPivot; ++itToBeSorted, ++itPivot)
    *itPivot = itToBeSorted->second;

  return;
}

template <typename RandomAccessIterator>
void partialSortWithPivot(RandomAccessIterator first,
                          RandomAccessIterator middle,
                          RandomAccessIterator last,
                          CVector<unsigned C_INT32> & pivot)
{
  assert(first < middle && middle <= last);

  // Initialize the two column array to be sorted
  CVector<std::pair<RandomAccessIterator, unsigned C_INT32> > ToBeSorted;
  ToBeSorted.resize(last - first);

  RandomAccessIterator it;
  unsigned C_INT32 i;

  typename CVector<std::pair<RandomAccessIterator, unsigned C_INT32> >::elementType * itToBeSorted;

  for (it = first, i = 0, itToBeSorted = ToBeSorted.array();
       it != last;
       ++it, ++i, ++itToBeSorted)
    {
      itToBeSorted->first = it;
      itToBeSorted->second = i;
    }

  itToBeSorted = ToBeSorted.array();

  std::partial_sort(itToBeSorted,
                    itToBeSorted + (middle - first),
                    itToBeSorted + (last - first),
                    &sortDefault<RandomAccessIterator>);

  // Copy the resulting pivots to the pivot vector.
  pivot.resize(last - first);
  CVector<unsigned C_INT32>::elementType *itPivot = pivot.array();
  CVector<unsigned C_INT32>::elementType *endPivot = itPivot + (last - first);

  for (; itPivot != endPivot; ++itToBeSorted, ++itPivot)
    *itPivot = itToBeSorted->second;

  return;
}

template <typename RandomAccessIterator, typename LessThanCompare>
bool sortSpecified(const std::pair<RandomAccessIterator, unsigned C_INT32> & lhs,
                   const std::pair<RandomAccessIterator, unsigned C_INT32> & rhs,
                   LessThanCompare pCompare)
{return (*pCompare)(*lhs.first, *rhs.first);}

template <typename RandomAccessIterator, typename LessThanCompare>
void sortWithPivot(RandomAccessIterator first,
                   RandomAccessIterator last,
                   LessThanCompare comp,
                   CVector<unsigned C_INT32> & pivot)
{
  assert(first < last);

  // Initialize the two column array to be sorted
  CVector<std::pair<RandomAccessIterator, unsigned C_INT32> > ToBeSorted;
  ToBeSorted.resize(last - first);

  RandomAccessIterator it;
  unsigned C_INT32 i;

  typename CVector<std::pair<RandomAccessIterator, unsigned C_INT32> >::elementType * itToBeSorted;

  for (it = first, i = 0, itToBeSorted = ToBeSorted.array();
       it != last;
       ++it, ++i, ++itToBeSorted)
    {
      itToBeSorted->first = it;
      itToBeSorted->second = i;
    }

  itToBeSorted = ToBeSorted.array();

  std::sort(itToBeSorted,
            itToBeSorted + (last - first),
            &sortSpecified<RandomAccessIterator>);

  // Copy the resulting pivots to the pivot vector.
  pivot.resize(last - first);
  CVector<unsigned C_INT32>::elementType *itPivot = pivot.array();
  CVector<unsigned C_INT32>::elementType *endPivot = itPivot + (last - first);

  for (; itPivot != endPivot; ++itToBeSorted, ++itPivot)
    *itPivot = itToBeSorted->second;

  return;
}

/**
 * Reorder the elements according to the provided pivots<commit_msg>Reduced code duplication by introducing functors.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CSort.h,v $
   $Revision: 1.3 $
   $Name:  $
   $Author: shoops $ 
   $Date: 2005/09/27 02:39:40 $
   End CVS Header */

#ifndef COPASI_CSort
 #define COPASI_CSort

#include <algorithm>

#include "CVector.h"

template <typename RandomAccessIterator>
class CCompareFunctorBase
  {
  public:
    bool operator() (const std::pair<RandomAccessIterator, unsigned C_INT32> & lhs,
                     const std::pair<RandomAccessIterator, unsigned C_INT32> & rhs)
    {return *lhs.first < *rhs.first;}
  };

template <typename RandomAccessIterator>
class CCompareFunctor : CCompareFunctorBase<RandomAccessIterator>
  {
  private:
    CCompareFunctor();

  public:
    CCompareFunctor(bool (*method)(const std::pair<RandomAccessIterator, unsigned C_INT32> &,
                                   const std::pair<RandomAccessIterator, unsigned C_INT32> &)):
        mpCompare(method)
    {}

    bool operator() (const std::pair<RandomAccessIterator, unsigned C_INT32> & lhs,
                     const std::pair<RandomAccessIterator, unsigned C_INT32> & rhs)
    {return (*mpCompare)(*lhs.first, *rhs.first);}

  private:
    bool (*mpCompare)(const std::pair<RandomAccessIterator, unsigned C_INT32> &,
                      const std::pair<RandomAccessIterator, unsigned C_INT32> &);
  };

template <typename RandomAccessIterator>
void sortWithPivot(RandomAccessIterator first,
                   RandomAccessIterator last,
                   CVector<unsigned C_INT32> & pivot)
{
  CCompareFunctorBase<RandomAccessIterator> Compare;

  __sortWithPivot(first, last, Compare, pivot);

  return;
}

template <typename RandomAccessIterator, typename LessThanCompare>
void sortWithPivot(RandomAccessIterator first,
                   RandomAccessIterator last,
                   LessThanCompare comp,
                   CVector<unsigned C_INT32> & pivot)
{
  CCompareFunctor<RandomAccessIterator> Compare(comp);

  __sortWithPivot(first, middle, last, Compare, pivot);

  return;
}

template <typename RandomAccessIterator>
void __sortWithPivot(RandomAccessIterator first,
                     RandomAccessIterator last,
                     CCompareFunctorBase<RandomAccessIterator> & compare,
                     CVector<unsigned C_INT32> & pivot)
{
  assert(first < last);

  // Initialize the two column array to be sorted
  CVector<std::pair<RandomAccessIterator, unsigned C_INT32> > ToBeSorted;
  ToBeSorted.resize(last - first);

  RandomAccessIterator it;
  unsigned C_INT32 i;

  typename std::pair<RandomAccessIterator, unsigned C_INT32> * itToBeSorted;

  for (it = first, i = 0, itToBeSorted = ToBeSorted.array();
       it != last;
       ++it, ++i, ++itToBeSorted)
    {
      itToBeSorted->first = it;
      itToBeSorted->second = i;
    }

  itToBeSorted = ToBeSorted.array();

  std::sort(itToBeSorted,
            itToBeSorted + (last - first),
            compare);

  // Copy the resulting pivots to the pivot vector.
  pivot.resize(last - first);
  CVector<unsigned C_INT32>::elementType *itPivot = pivot.array();
  CVector<unsigned C_INT32>::elementType *endPivot = itPivot + (last - first);

  for (; itPivot != endPivot; ++itToBeSorted, ++itPivot)
    *itPivot = itToBeSorted->second;

  return;
}

template <typename RandomAccessIterator>
void partialSortWithPivot(RandomAccessIterator first,
                          RandomAccessIterator middle,
                          RandomAccessIterator last,
                          CVector<unsigned C_INT32> & pivot)
{
  CCompareFunctorBase<RandomAccessIterator> Compare;

  __partialSortWithPivot(first, middle, last, Compare, pivot);

  return;
}

template <typename RandomAccessIterator, typename LessThanCompare>
void partialSortWithPivot(RandomAccessIterator first,
                          RandomAccessIterator middle,
                          RandomAccessIterator last,
                          LessThanCompare comp,
                          CVector<unsigned C_INT32> & pivot)
{
  CCompareFunctor<RandomAccessIterator> Compare(comp);

  __partialSortWithPivot(first, middle, last, Compare, pivot);

  return;
}

template <typename RandomAccessIterator>
void __partialSortWithPivot(RandomAccessIterator first,
                            RandomAccessIterator middle,
                            RandomAccessIterator last,
                            CCompareFunctorBase<RandomAccessIterator> & compare,
                            CVector<unsigned C_INT32> & pivot)
{
  assert(first < middle && middle <= last);

  // Initialize the two column array to be sorted
  CVector<std::pair<RandomAccessIterator, unsigned C_INT32> > ToBeSorted;
  ToBeSorted.resize(last - first);

  RandomAccessIterator it;
  unsigned C_INT32 i;

  typename std::pair<RandomAccessIterator, unsigned C_INT32> * itToBeSorted;

  for (it = first, i = 0, itToBeSorted = ToBeSorted.array();
       it != last;
       ++it, ++i, ++itToBeSorted)
    {
      itToBeSorted->first = it;
      itToBeSorted->second = i;
    }

  itToBeSorted = ToBeSorted.array();

  std::partial_sort(itToBeSorted,
                    itToBeSorted + (middle - first),
                    itToBeSorted + (last - first),
                    compare);

  // Copy the resulting pivots to the pivot vector.
  pivot.resize(last - first);
  CVector<unsigned C_INT32>::elementType *itPivot = pivot.array();
  CVector<unsigned C_INT32>::elementType *endPivot = itPivot + (last - first);

  for (; itPivot != endPivot; ++itToBeSorted, ++itPivot)
    *itPivot = itToBeSorted->second;

  return;
}

/**
 * Reorder the elements according to the provided pivots
{'fraction_non_alphanumeric': 0.10360531309297913, 'fraction_numerical': 0.012239089184060721, 'mean_word_length': 3.0935922330097085, 'pattern_counts': {'":': 0, '<': 86, '<?xml version=': 0, '>': 92, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '737791', 'n_tokens_mistral': 3395, 'n_tokens_neox': 3182, 'n_words': 725}