CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/Utilities/General/interface/precomputed_value_sort.h

Go to the documentation of this file.
00001 #ifndef precomputed_value_sort_H
00002 #define precomputed_value_sort_H
00003 
00015 #include <utility>
00016 #include <vector>
00017 #include <algorithm>
00018 
00019 namespace {
00020   template<class T, class Scalar>
00021   struct LessPair {
00022     typedef std::pair<T,Scalar> SortPair;
00023     bool operator()( const SortPair& a, const SortPair& b) {
00024       return a.second < b.second;
00025     }
00026   };
00027 
00028   template <class T, class Scalar, class BinaryPredicate>
00029   struct ComparePair {
00030     ComparePair( const BinaryPredicate& cmp) : cmp_(cmp) {}
00031     typedef std::pair<T,Scalar> SortPair;
00032     bool operator()( const SortPair& a, const SortPair& b) {
00033       return cmp_(a.second, b.second);
00034     }
00035     BinaryPredicate cmp_;
00036   };
00037 }
00038 
00039 
00040 template<class RandomAccessIterator, class Extractor>
00041 void precomputed_value_sort(RandomAccessIterator begin,
00042                             RandomAccessIterator end,
00043                             const Extractor& extr) {
00044 
00045   typedef typename Extractor::result_type        Scalar;
00046   typedef std::pair<RandomAccessIterator,Scalar> SortPair;
00047 
00048   std::vector<SortPair> tmpvec; 
00049   tmpvec.reserve(end-begin);
00050 
00051   // tmpvec holds iterators - does not copy the real objects
00052   for (RandomAccessIterator i=begin; i!=end; i++) {
00053     tmpvec.push_back(SortPair(i,extr(*i)));
00054   }
00055   
00056   std::sort(tmpvec.begin(), tmpvec.end(),
00057             LessPair<RandomAccessIterator,Scalar>());    
00058 
00059   // overwrite the input range with the sorted values
00060   // copy of input container not necessary, but tricky to avoid
00061   std::vector<typename std::iterator_traits<RandomAccessIterator>::value_type> tmpcopy(begin,end);
00062   for (unsigned int i=0; i<tmpvec.size(); i++) {
00063     *(begin+i) = tmpcopy[tmpvec[i].first - begin];
00064   }
00065 }
00066 
00067 
00069 
00070 template<class RandomAccessIterator, class Extractor, class BinaryPredicate>
00071 void precomputed_value_sort( RandomAccessIterator begin,
00072                              RandomAccessIterator end,
00073                              const Extractor& extr,
00074                              const BinaryPredicate& pred) {
00075 
00076   typedef typename Extractor::result_type        Scalar;
00077   typedef std::pair<RandomAccessIterator,Scalar> SortPair;
00078 
00079   std::vector<SortPair> tmpvec; 
00080   tmpvec.reserve(end-begin);
00081 
00082   // tmpvec holds iterators - does not copy the real objects
00083   for (RandomAccessIterator i=begin; i!=end; i++) {
00084     tmpvec.push_back(SortPair(i,extr(*i)));
00085   }
00086   
00087   std::sort(tmpvec.begin(), tmpvec.end(),
00088             ComparePair< RandomAccessIterator,Scalar,BinaryPredicate>(pred));
00089 
00090   // overwrite the input range with the sorted values
00091   // copy of input container not necessary, but tricky to avoid
00092   std::vector<typename std::iterator_traits<RandomAccessIterator>::value_type> tmpcopy(begin,end);
00093   for (unsigned int i=0; i<tmpvec.size(); i++) {
00094     *(begin+i) = tmpcopy[tmpvec[i].first - begin];
00095   }
00096 
00097 }
00098 
00099 #endif