00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef OLN_UTILS_QSORT_HH
00028 # define OLN_UTILS_QSORT_HH
00029 # include <vector>
00030 # include <oln/core/abstract/image.hh>
00031 # include <oln/core/abstract/image_with_type_with_dim.hh>
00032
00033 # include <algorithm>
00034 # include <iostream>
00035
00036 namespace oln
00037 {
00038 namespace utils
00039 {
00040 namespace internal
00041 {
00047 template <typename I>
00048 struct cmp_pt_value
00049 {
00050 typedef oln::abstract::non_vectorial_image<I> im_type;
00051 typedef oln_point_type(I) point_type;
00052
00058 cmp_pt_value(const im_type &im): im_(im)
00059 {
00060 }
00061
00072 bool operator()(const point_type &i, const point_type &j)
00073 {
00074 if (im_[i] == im_[j])
00075 for (unsigned t(0); t < point_type::dim; ++t)
00076 if (i.nth(t) != j.nth(t))
00077 return i.nth(t) < j.nth(t);
00078 return im_[j] > im_[i];
00079 }
00080
00081 protected:
00082 const im_type &im_;
00083 };
00084
00090 template <typename I>
00091 struct cmp_pt_value_inv
00092 {
00093 typedef oln::abstract::non_vectorial_image<I> im_type;
00094 typedef oln_point_type(I) point_type;
00095
00101 cmp_pt_value_inv(const im_type &im): im_(im)
00102 {
00103 }
00104
00115 bool operator()(const point_type &i, const point_type &j)
00116 {
00117 if (im_[i] == im_[j])
00118 for (unsigned t(0); t < point_type::dim; ++t)
00119 if (i.nth(t) != j.nth(t))
00120 return i.nth(t) < j.nth(t);
00121 return im_[i] > im_[j];
00122 }
00123
00124 protected:
00125 const im_type &im_;
00126 };
00127 }
00128
00137 template<class I>
00138 void
00139 qsort(const oln::abstract::non_vectorial_image<I>& im,
00140 std::vector<oln_point_type(I)> &v)
00141 {
00142 oln_iter_type(I) it(im);
00143
00144 for_all(it)
00145 v.push_back(oln_point_type(I)(it));
00146 internal::cmp_pt_value<I> c(im);
00147
00148 std::sort(v.begin(), v.end(), c);
00149 }
00150
00159 template<class I>
00160 void
00161 qsort_inv(const oln::abstract::non_vectorial_image<I>& im,
00162 std::vector<oln_point_type(I)> &v)
00163 {
00164 oln_iter_type(I) it(im);
00165
00166 for_all(it)
00167 v.push_back(oln_point_type(I)(it));
00168
00169 internal::cmp_pt_value_inv<I> c(im);
00170
00171 std::sort(v.begin(), v.end(), c);
00172 }
00173
00178 template <bool reverse>
00179 struct select_q_sort
00180 {
00181 template <class I>
00182 void
00183 operator ()(const oln::abstract::non_vectorial_image<I>& im,
00184 std::vector<oln_point_type(I)> &v)
00185 {
00186 qsort_inv(im, v);
00187 }
00188 };
00189
00194 template <>
00195 struct select_q_sort<true>
00196 {
00197 template <class I>
00198 void
00199 operator ()(const oln::abstract::non_vectorial_image<I>& im,
00200 std::vector<oln_point_type(I)> &v)
00201 {
00202 qsort(im, v);
00203 }
00204 };
00205 }
00206 }
00207
00208 #endif // !QSORT