Merge topic 'cleanup-cmAlgorithms'

47c2da6a cmAlgorithms: Cache the end iterators in algorithms.
a5b10ae6 cmAlgorithms: Remove needless assignment.
7fd8557f cmAlgorithms: Maintain the pivot iterator in cmRemoveIndices.
1f796791 cmAlgorithms: Relax iterator requirement for cmRemoveIndices.
ba959934 cmAlgorithms: Make cmRemoveDuplicates work with more containers.
cae45df7 cmAlgorithms: Rename template argument to RemoveN.
b917f4c0 cmAlgorithms: Relax cmRemoveN requirement to FwdIter.
bbc1a978 cmAlgorithms: Add a size() to cmRange.
47a3e22e cmAlgorithms: Rename template type in cmDeleteAll algorithm.
cb75eec0 cmAlgorithms: Add const to const objects.
This commit is contained in:
Brad King 2015-02-24 09:16:53 -05:00 committed by CMake Topic Stage
commit ac80f0f95f

View File

@ -84,7 +84,7 @@ private:
template<typename FwdIt> template<typename FwdIt>
FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last) FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
{ {
typename std::iterator_traits<FwdIt>::difference_type dist = const typename std::iterator_traits<FwdIt>::difference_type dist =
std::distance(middle, last); std::distance(middle, last);
std::rotate(first, middle, last); std::rotate(first, middle, last);
std::advance(first, dist); std::advance(first, dist);
@ -105,19 +105,19 @@ struct cmIsPair<std::pair<K, V> >
enum { value = true }; enum { value = true };
}; };
template<typename Container, template<typename Range,
bool valueTypeIsPair = cmIsPair<typename Container::value_type>::value> bool valueTypeIsPair = cmIsPair<typename Range::value_type>::value>
struct DefaultDeleter struct DefaultDeleter
{ {
void operator()(typename Container::value_type value) const { void operator()(typename Range::value_type value) const {
delete value; delete value;
} }
}; };
template<typename Container> template<typename Range>
struct DefaultDeleter<Container, /* valueTypeIsPair = */ true> struct DefaultDeleter<Range, /* valueTypeIsPair = */ true>
{ {
void operator()(typename Container::value_type value) const { void operator()(typename Range::value_type value) const {
delete value.second; delete value.second;
} }
}; };
@ -127,11 +127,14 @@ struct Range
{ {
typedef const_iterator_ const_iterator; typedef const_iterator_ const_iterator;
typedef typename std::iterator_traits<const_iterator>::value_type value_type; typedef typename std::iterator_traits<const_iterator>::value_type value_type;
typedef typename std::iterator_traits<const_iterator>::difference_type
difference_type;
Range(const_iterator begin_, const_iterator end_) Range(const_iterator begin_, const_iterator end_)
: Begin(begin_), End(end_) {} : Begin(begin_), End(end_) {}
const_iterator begin() const { return Begin; } const_iterator begin() const { return Begin; }
const_iterator end() const { return End; } const_iterator end() const { return End; }
bool empty() const { return std::distance(Begin, End) == 0; } bool empty() const { return std::distance(Begin, End) == 0; }
difference_type size() const { return std::distance(Begin, End); }
Range& advance(cmIML_INT_intptr_t amount) Range& advance(cmIML_INT_intptr_t amount)
{ {
std::advance(Begin, amount); std::advance(Begin, amount);
@ -148,10 +151,12 @@ private:
const_iterator End; const_iterator End;
}; };
template<typename Iter> template<typename FwdIt>
Iter RemoveN(Iter i1, Iter i2, size_t n) FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
{ {
return cmRotate(i1, i1 + n, i2); FwdIt m = i1;
std::advance(m, n);
return cmRotate(i1, m, i2);
} }
template<typename Range> template<typename Range>
@ -187,11 +192,11 @@ cmRange(Range const& range)
range.begin(), range.end()); range.begin(), range.end());
} }
template<typename Container> template<typename Range>
void cmDeleteAll(Container const& c) void cmDeleteAll(Range const& r)
{ {
std::for_each(c.begin(), c.end(), std::for_each(r.begin(), r.end(),
ContainerAlgorithms::DefaultDeleter<Container>()); ContainerAlgorithms::DefaultDeleter<Range>());
} }
template<typename Range> template<typename Range>
@ -204,7 +209,7 @@ std::string cmJoin(Range const& r, const char* delimiter)
std::ostringstream os; std::ostringstream os;
typedef typename Range::value_type ValueType; typedef typename Range::value_type ValueType;
typedef typename Range::const_iterator InputIt; typedef typename Range::const_iterator InputIt;
InputIt first = r.begin(); const InputIt first = r.begin();
InputIt last = r.end(); InputIt last = r.end();
--last; --last;
std::copy(first, last, std::copy(first, last,
@ -231,16 +236,22 @@ template<typename Range, typename InputRange>
typename Range::const_iterator cmRemoveIndices(Range& r, InputRange const& rem) typename Range::const_iterator cmRemoveIndices(Range& r, InputRange const& rem)
{ {
typename InputRange::const_iterator remIt = rem.begin(); typename InputRange::const_iterator remIt = rem.begin();
typename InputRange::const_iterator remEnd = rem.end();
typename Range::iterator writer = r.begin() + *remIt; typename Range::iterator writer = r.begin();
std::advance(writer, *remIt);
typename Range::iterator pivot = writer;
typename InputRange::value_type prevRem = *remIt;
++remIt; ++remIt;
size_t count = 1; size_t count = 1;
for ( ; writer != r.end() && remIt != rem.end(); ++count, ++remIt) const typename Range::iterator rangeEnd = r.end();
for ( ; writer != rangeEnd && remIt != remEnd; ++count, ++remIt)
{ {
writer = ContainerAlgorithms::RemoveN(writer, r.begin() + *remIt, count); std::advance(pivot, *remIt - prevRem);
prevRem = *remIt;
writer = ContainerAlgorithms::RemoveN(writer, pivot, count);
} }
writer = ContainerAlgorithms::RemoveN(writer, r.end(), count); return ContainerAlgorithms::RemoveN(writer, rangeEnd, count);
return writer;
} }
template<typename Range, typename MatchRange> template<typename Range, typename MatchRange>
@ -253,14 +264,16 @@ typename Range::const_iterator cmRemoveMatching(Range &r, MatchRange const& m)
template<typename Range> template<typename Range>
typename Range::const_iterator cmRemoveDuplicates(Range& r) typename Range::const_iterator cmRemoveDuplicates(Range& r)
{ {
std::vector<typename Range::value_type> unique; typedef std::vector<typename Range::value_type> UniqueVector;
UniqueVector unique;
unique.reserve(r.size()); unique.reserve(r.size());
std::vector<size_t> indices; std::vector<size_t> indices;
size_t count = 0; size_t count = 0;
const typename Range::iterator end = r.end();
for(typename Range::const_iterator it = r.begin(); for(typename Range::const_iterator it = r.begin();
it != r.end(); ++it, ++count) it != end; ++it, ++count)
{ {
typename Range::iterator low = const typename UniqueVector::iterator low =
std::lower_bound(unique.begin(), unique.end(), *it); std::lower_bound(unique.begin(), unique.end(), *it);
if (low == unique.end() || *low != *it) if (low == unique.end() || *low != *it)
{ {
@ -273,7 +286,7 @@ typename Range::const_iterator cmRemoveDuplicates(Range& r)
} }
if (indices.empty()) if (indices.empty())
{ {
return r.end(); return end;
} }
return cmRemoveIndices(r, indices); return cmRemoveIndices(r, indices);
} }