_NonPyObjectUniqueSorterIncer(PyObject * fast_seq) 
 {           
     if (fast_seq == Py_None)
         return;
 
     vals.reserve(PySequence_Fast_GET_SIZE(fast_seq));            
     for (size_t i = 0; i < static_cast<size_t>(PySequence_Fast_GET_SIZE(fast_seq)); ++i) {    
         PyObject * const val = PySequence_Fast_GET_ITEM(fast_seq, i);    
         DBG_ASSERT(PyTuple_Check(val));
         DBG_ASSERT(PyTuple_Size(val) == 2);
         PyObject * const key = PyTuple_GET_ITEM(val, 0);
         BANYAN_PYOBJECT_INCREF(key);
         vals.push_back(std::make_pair(
             std::make_pair(                    
                 _KeyFactory<Key_Type>::convert(key), 
                 key),
             PyTuple_GET_ITEM(val, 1)));
     }            
         
     _FirstLT<_FirstLT<std::less<Key_Type> > > lt;            
     std::sort(vals.begin(), vals.end(), lt);
     vals.erase(unique(vals.begin(), vals.end(), not2(lt)), vals.end());
     
     for (size_t i = 0; i < vals.size(); ++i)
         BANYAN_PYOBJECT_INCREF(vals[i].second);            
 }
Пример #2
0
inline OutputIterator unique_copy(InputIterator first,
                                  InputIterator last,
                                  OutputIterator result,
                                  BinaryPredicate op,
                                  command_queue &queue)
{
    if(first == last){
        return result;
    }

    const context &context = queue.get_context();
    size_t count = detail::iterator_range_size(first, last);

    // flags marking unique elements
    vector<uint_> flags(count, context);

    // find each unique element and mark it with a one
    transform(
        first, last - 1, first + 1, flags.begin() + 1, not2(op), queue
    );

    // first element is always unique
    fill_n(flags.begin(), 1, 1, queue);

    // storage for desination indices
    vector<uint_> indices(count, context);

    // copy indices for each unique element
    vector<uint_>::iterator last_index = detail::copy_index_if(
        flags.begin(), flags.end(), indices.begin(), lambda::_1 == 1, queue
    );

    // copy unique values from input to output using the computed indices
    gather(indices.begin(), last_index, first, result, queue);

    // return an iterator to the end of the unique output range
    return result + std::distance(indices.begin(), last_index);
}