[1642] | 1 | /// @file |
---|
| 2 | /// |
---|
| 3 | /// @brief A binary predicate to compare two numbers referred by indices |
---|
| 4 | /// @details While sorting a vector, it is often necessary to track |
---|
| 5 | /// permutations. One way of doing this is to write a std::pair-like class |
---|
| 6 | /// with comparison operators using one element of the pair only and store |
---|
| 7 | /// both value and its index. This is done in the PairOrderedFirst class |
---|
| 8 | /// in AIPS++, which I wrote some time ago. However, there exists a more elegant |
---|
| 9 | /// solution using a version of std::sort with a user-suppled binary predicate. |
---|
| 10 | /// This file defines such binary predicate class comparing two values |
---|
| 11 | /// stored in a container defined by its random access iterator of the origin |
---|
| 12 | /// each time it is asked to compare two indicies. Each instance of the class |
---|
| 13 | /// holds a copy of the rangom access iterator. |
---|
| 14 | /// |
---|
| 15 | /// @copyright (c) 2007 CSIRO |
---|
| 16 | /// Australia Telescope National Facility (ATNF) |
---|
| 17 | /// Commonwealth Scientific and Industrial Research Organisation (CSIRO) |
---|
| 18 | /// PO Box 76, Epping NSW 1710, Australia |
---|
| 19 | /// atnf-enquiries@csiro.au |
---|
| 20 | /// |
---|
| 21 | /// This file was originally written as a part of the ASKAP software |
---|
| 22 | /// distribution and then adapted and reused in the ASAP project. |
---|
| 23 | /// |
---|
| 24 | /// The ASKAP software distribution is free software: you can redistribute it |
---|
| 25 | /// and/or modify it under the terms of the GNU General Public License as |
---|
| 26 | /// published by the Free Software Foundation; either version 2 of the License, |
---|
| 27 | /// or (at your option) any later version. |
---|
| 28 | /// |
---|
| 29 | /// This program is distributed in the hope that it will be useful, |
---|
| 30 | /// but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 31 | /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 32 | /// GNU General Public License for more details. |
---|
| 33 | /// |
---|
| 34 | /// You should have received a copy of the GNU General Public License |
---|
| 35 | /// along with this program; if not, write to the Free Software |
---|
| 36 | /// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
| 37 | /// |
---|
| 38 | /// @author Max Voronkov <maxim.voronkov@csiro.au> |
---|
| 39 | |
---|
| 40 | #ifndef INDEXED_COMPARE_H |
---|
| 41 | #define INDEXED_COMPARE_H |
---|
| 42 | |
---|
| 43 | #include <functional> |
---|
| 44 | |
---|
| 45 | namespace asap { |
---|
| 46 | |
---|
| 47 | /// @brief A binary predicate to compare two numbers referred by indices |
---|
| 48 | /// @details While sorting a vector, it is often necessary to track |
---|
| 49 | /// permutations. One way of doing this is to write a std::pair-like class |
---|
| 50 | /// with comparison operators using one element of the pair only and store |
---|
| 51 | /// both value and its index. This is done in the PairOrderedFirst class |
---|
| 52 | /// in AIPS++, which I wrote some time ago. However, there exists a more elegant |
---|
| 53 | /// solution using a version of std::sort with a user-suppled binary predicate. |
---|
| 54 | /// This is such binary predicate class comparing two values |
---|
| 55 | /// stored in a container defined by its random access iterator of the origin |
---|
| 56 | /// each time it is asked to compare two indicies. Each instance of the class |
---|
| 57 | /// holds a copy of the rangom access iterator. |
---|
| 58 | template<typename IndexType, typename Iter, |
---|
| 59 | typename Cmp = std::less<typename Iter::value_type> > |
---|
| 60 | struct IndexedCompare : public std::binary_function<IndexType,IndexType,bool> { |
---|
| 61 | /// @brief constructor with a default comparator initialization |
---|
| 62 | /// @details |
---|
| 63 | /// A comparator (which type is a template parameter) is set up with its |
---|
| 64 | /// default constructor. |
---|
| 65 | /// @param[in] iter random access iterator to work with |
---|
| 66 | IndexedCompare(const Iter &iter) : itsIter(iter) {} |
---|
| 67 | |
---|
| 68 | /// @brief constructor with a user-specified comparator initialization |
---|
| 69 | /// @details |
---|
| 70 | /// A comparator (which type is a template parameter) is set up using a |
---|
| 71 | /// a copy constructor |
---|
| 72 | /// @param[in] iter random access iterator to work with |
---|
| 73 | IndexedCompare(const Iter &iter, const Cmp &cmp) : itsIter(iter), |
---|
| 74 | itsComparator(cmp) {} |
---|
| 75 | |
---|
| 76 | |
---|
| 77 | /// @brief main operator of the predicate |
---|
| 78 | /// @details Returns result of comparison of the value referred to by the |
---|
| 79 | /// first and the second indices |
---|
| 80 | /// @param[in] index1 index of the first value |
---|
| 81 | /// @param[in] index2 index of the second value |
---|
| 82 | /// @return result of comparison |
---|
| 83 | bool operator()(const IndexType &index1, const IndexType &index2) const |
---|
| 84 | { |
---|
| 85 | return itsComparator(*(itsIter+index1), *(itsIter+index2)); |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | |
---|
| 89 | private: |
---|
| 90 | /// random access iterator to work with |
---|
| 91 | Iter itsIter; |
---|
| 92 | /// underlying binary predicate to do the comparison |
---|
| 93 | Cmp itsComparator; |
---|
| 94 | }; |
---|
| 95 | |
---|
| 96 | /// @brief helper function to construct IndexedCompare object |
---|
| 97 | /// @details It is handy to have a helper method to avoid |
---|
| 98 | /// writing type names all the time. This function can extract the |
---|
| 99 | /// template parameter from the argument type, i.e. automatically |
---|
| 100 | /// @param[in] iter random access iterator to work with |
---|
| 101 | /// @param[in] cmp an object which does the actual comparison |
---|
| 102 | template<typename IndexType, typename Iter, typename Cmp> |
---|
| 103 | IndexedCompare<IndexType,Iter,Cmp> indexedCompare(const Iter &iter, const Cmp &cmp = |
---|
| 104 | std::less<typename Iter::value_type>()) |
---|
| 105 | { |
---|
| 106 | return IndexedCompare<IndexType,Iter,Cmp>(iter,cmp); |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | template<typename IndexType, typename Iter> |
---|
| 110 | IndexedCompare<IndexType,Iter> indexedCompare(const Iter &iter) |
---|
| 111 | { |
---|
| 112 | return IndexedCompare<IndexType,Iter>(iter); |
---|
| 113 | } |
---|
| 114 | |
---|
| 115 | } // namespace asap |
---|
| 116 | |
---|
| 117 | #endif // #define INDEXED_COMPARE_H |
---|
| 118 | |
---|