Here are some std-syle generic utilities (standard c++98).
1. Extract elements at indices
/// Extract elements from vector at indices specified by range
template <typename ForwardIt, typename IndicesForwardIt>
inline std::vector<typename std::iterator_traits<ForwardIt>::value_type>
extract_at(
ForwardIt first,
IndicesForwardIt indices_first,
IndicesForwardIt indices_last)
{
typedef std::vector<typename std::iterator_traits<ForwardIt>::value_type>
vector_type;
vector_type extracted;
extracted.reserve(static_cast<typename vector_type::size_type>(
std::distance(indices_first, indices_last)));
for(; indices_first != indices_last; ++indices_first)
extracted.push_back(*(first + *indices_first));
return extracted;
}
/// Extract elements from collection specified by collection of indices
template <typename TVector, typename TIndicesVector>
inline TVector extract_at(const TVector& data, const TIndicesVector& indices)
{
return extract_at(data.begin(), indices.begin(), indices.end());
}
//! Remove one element with given index from the range [first; last)
template <typename ForwardIt>
inline ForwardIt remove_at(ForwardIt first, ForwardIt last, const size_t index)
{
std::advance(first, index);
for(ForwardIt it = first + 1; it != last; ++it, ++first)
*first = *it;
return first;
}
/*!
* Remove elements in the range [first; last) with indices from the sorted
* range [indices_first, indices_last)
*/
template <typename ForwardIt, typename SortedIndicesForwardIt>
inline ForwardIt remove_at(
ForwardIt first,
ForwardIt last,
SortedIndicesForwardIt indices_first,
SortedIndicesForwardIt indices_last)
{
typedef typename std::vector<bool> flags;
// flag elements to keep
flags is_keep(
static_cast<flags::size_type>(std::distance(first, last)), true);
for(; indices_first != indices_last; ++indices_first)
is_keep[static_cast<flags::size_type>(*indices_first)] = false;
// move kept elements to beginning
ForwardIt result = first;
for(flags::const_iterator it = is_keep.begin(); first != last; ++first, ++it)
if(*it) // keep element
*result++ = *first; //in c++11 and later use: *result++ = std::move(*first);
return result;
}
Usage (erase-remove idiom):
std::vector<int> vec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> ii{6, 3, 1};
std::sort(ii.begin(), ii.end());
vec.erase(remove_at(vec.begin(), vec.end(), ii.begin(), ii.end()), vec.end());