| 25 | /// the \p nth element would be in that position in a sorted sequence. |
| 26 | template<class Iterator, class Compare> |
| 27 | inline void nth_element(Iterator first, |
| 28 | Iterator nth, |
| 29 | Iterator last, |
| 30 | Compare compare, |
| 31 | command_queue &queue = system::default_queue()) |
| 32 | { |
| 33 | if(nth == last) return; |
| 34 | |
| 35 | typedef typename std::iterator_traits<Iterator>::value_type value_type; |
| 36 | |
| 37 | while(1) |
| 38 | { |
| 39 | value_type value = nth.read(queue); |
| 40 | |
| 41 | using boost::compute::placeholders::_1; |
| 42 | Iterator new_nth = partition( |
| 43 | first, last, ::boost::compute::bind(compare, _1, value), queue |
| 44 | ); |
| 45 | |
| 46 | Iterator old_nth = find(new_nth, last, value, queue); |
| 47 | |
| 48 | value_type new_value = new_nth.read(queue); |
| 49 | |
| 50 | fill_n(new_nth, 1, value, queue); |
| 51 | fill_n(old_nth, 1, new_value, queue); |
| 52 | |
| 53 | new_value = nth.read(queue); |
| 54 | |
| 55 | if(value == new_value) break; |
| 56 | |
| 57 | if(std::distance(first, nth) < std::distance(first, new_nth)) |
| 58 | { |
| 59 | last = new_nth; |
| 60 | } |
| 61 | else |
| 62 | { |
| 63 | first = new_nth; |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | /// \overload |
| 69 | template<class Iterator> |