| 30 | /// Space complexity: \Omega(3n) |
| 31 | template<class Iterator, class Compare> |
| 32 | inline void nth_element(Iterator first, |
| 33 | Iterator nth, |
| 34 | Iterator last, |
| 35 | Compare compare, |
| 36 | command_queue &queue = system::default_queue()) |
| 37 | { |
| 38 | BOOST_STATIC_ASSERT(is_device_iterator<Iterator>::value); |
| 39 | if(nth == last) return; |
| 40 | |
| 41 | typedef typename std::iterator_traits<Iterator>::value_type value_type; |
| 42 | |
| 43 | while(1) |
| 44 | { |
| 45 | value_type value = nth.read(queue); |
| 46 | |
| 47 | using boost::compute::placeholders::_1; |
| 48 | Iterator new_nth = partition( |
| 49 | first, last, ::boost::compute::bind(compare, _1, value), queue |
| 50 | ); |
| 51 | |
| 52 | Iterator old_nth = find(new_nth, last, value, queue); |
| 53 | |
| 54 | value_type new_value = new_nth.read(queue); |
| 55 | |
| 56 | fill_n(new_nth, 1, value, queue); |
| 57 | fill_n(old_nth, 1, new_value, queue); |
| 58 | |
| 59 | new_value = nth.read(queue); |
| 60 | |
| 61 | if(value == new_value) break; |
| 62 | |
| 63 | if(std::distance(first, nth) < std::distance(first, new_nth)) |
| 64 | { |
| 65 | last = new_nth; |
| 66 | } |
| 67 | else |
| 68 | { |
| 69 | first = new_nth; |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | /// \overload |
| 75 | template<class Iterator> |