File indexing completed on 2025-01-18 09:51:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef __BOOST_SORT_PARALLEL_COMMON_INDIRECT_HPP
0014 #define __BOOST_SORT_PARALLEL_COMMON_INDIRECT_HPP
0015
0016
0017 #include <boost/sort/common/util/traits.hpp>
0018 #include <functional>
0019 #include <iterator>
0020 #include <type_traits>
0021 #include <vector>
0022
0023 namespace boost
0024 {
0025 namespace sort
0026 {
0027 namespace common
0028 {
0029
0030
0031
0032
0033
0034
0035
0036
0037 template<class Iter_t, class Compare = util::compare_iter<Iter_t> >
0038 struct less_ptr_no_null
0039 {
0040
0041 Compare comp;
0042
0043
0044
0045
0046
0047
0048 less_ptr_no_null(Compare C1 = Compare()): comp(C1) { };
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 bool operator( )(Iter_t T1, Iter_t T2) const
0060 {
0061 return comp(*T1, *T2);
0062 };
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 template<class Iter_t>
0075 void create_index(Iter_t first, Iter_t last, std::vector<Iter_t> &index)
0076 {
0077 auto nelem = last - first;
0078 assert(nelem >= 0);
0079 index.clear();
0080 index.reserve(nelem);
0081 for (; first != last; ++first) index.push_back(first);
0082 };
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 template<class Iter_t>
0093 void sort_index(Iter_t global_first, std::vector<Iter_t> &index)
0094 {
0095 typedef util::value_iter<Iter_t> value_t;
0096
0097 size_t pos_dest = 0;
0098 size_t pos_src = 0;
0099 size_t pos_in_vector = 0;
0100 size_t nelem = index.size();
0101 Iter_t it_dest, it_src;
0102
0103 while (pos_in_vector < nelem)
0104 {
0105 while (pos_in_vector < nelem and
0106 (size_t(index[pos_in_vector] - global_first)) == pos_in_vector)
0107 {
0108 ++pos_in_vector;
0109 };
0110
0111 if (pos_in_vector == nelem) return;
0112 pos_dest = pos_src = pos_in_vector;
0113 it_dest = global_first + pos_dest;
0114 value_t Aux = std::move(*it_dest);
0115
0116 while ((pos_src = (size_t(index[pos_dest] - global_first)))
0117 != pos_in_vector)
0118 {
0119 index[pos_dest] = it_dest;
0120 it_src = global_first + pos_src;
0121 *it_dest = std::move(*it_src);
0122 it_dest = it_src;
0123 pos_dest = pos_src;
0124 };
0125
0126 *it_dest = std::move(Aux);
0127 index[pos_dest] = it_dest;
0128 ++pos_in_vector;
0129 };
0130 };
0131
0132 template<class func, class Iter_t, class Compare = util::compare_iter<Iter_t> >
0133 void indirect_sort(func method, Iter_t first, Iter_t last, Compare comp)
0134 {
0135 auto nelem = (last - first);
0136 assert(nelem >= 0);
0137 if (nelem < 2) return;
0138 std::vector<Iter_t> index;
0139 index.reserve((size_t) nelem);
0140 create_index(first, last, index);
0141 less_ptr_no_null<Iter_t, Compare> index_comp(comp);
0142 method(index.begin(), index.end(), index_comp);
0143 sort_index(first, index);
0144 };
0145
0146
0147
0148 };
0149 };
0150 };
0151
0152
0153 #endif