1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
5 #include "cmConfigure.h" // IWYU pragma: keep
11 #include <unordered_set>
15 #include <cmext/algorithm>
19 template <typename FwdIt>
20 FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
22 const typename std::iterator_traits<FwdIt>::difference_type dist =
23 std::distance(middle, last);
24 std::rotate(first, middle, last);
25 std::advance(first, dist);
29 namespace ContainerAlgorithms {
31 template <typename FwdIt>
32 FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
36 return cmRotate(i1, m, i2);
39 template <typename Range>
42 using argument_type = typename Range::value_type;
43 BinarySearcher(Range const& r)
48 bool operator()(argument_type const& item) const
50 return std::binary_search(this->m_range.begin(), this->m_range.end(),
59 class cmListFileBacktrace;
60 using cmBacktraceRange =
61 cmRange<std::vector<cmListFileBacktrace>::const_iterator>;
65 using cmBTStringRange = cmRange<std::vector<BT<std::string>>::const_iterator>;
67 template <typename Range>
68 typename Range::const_iterator cmRemoveN(Range& r, size_t n)
70 return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n);
73 template <typename Range, typename InputRange>
74 typename Range::const_iterator cmRemoveIndices(Range& r, InputRange const& rem)
76 typename InputRange::const_iterator remIt = rem.begin();
77 typename InputRange::const_iterator remEnd = rem.end();
78 const auto rangeEnd = r.end();
79 if (remIt == remEnd) {
83 auto writer = r.begin();
84 std::advance(writer, *remIt);
86 typename InputRange::value_type prevRem = *remIt;
89 for (; writer != rangeEnd && remIt != remEnd; ++count, ++remIt) {
90 std::advance(pivot, *remIt - prevRem);
92 writer = ContainerAlgorithms::RemoveN(writer, pivot, count);
94 return ContainerAlgorithms::RemoveN(writer, rangeEnd, count);
97 template <typename Range, typename MatchRange>
98 typename Range::const_iterator cmRemoveMatching(Range& r, MatchRange const& m)
100 return std::remove_if(r.begin(), r.end(),
101 ContainerAlgorithms::BinarySearcher<MatchRange>(m));
104 template <typename ForwardIterator>
105 ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
107 using Value = typename std::iterator_traits<ForwardIterator>::value_type;
110 std::size_t operator()(ForwardIterator it) const
112 return std::hash<Value>{}(*it);
118 bool operator()(ForwardIterator it1, ForwardIterator it2) const
123 std::unordered_set<ForwardIterator, Hash, Equal> uniq;
125 ForwardIterator result = first;
126 while (first != last) {
127 if (!cm::contains(uniq, first)) {
128 if (result != first) {
129 *result = std::move(*first);
139 template <typename Range>
140 typename Range::iterator cmRemoveDuplicates(Range& r)
142 return cmRemoveDuplicates(r.begin(), r.end());
145 template <typename Range>
146 typename Range::const_iterator cmRemoveDuplicates(Range const& r)
148 return cmRemoveDuplicates(r.begin(), r.end());
151 template <typename Range, typename T>
152 typename Range::const_iterator cmFindNot(Range const& r, T const& t)
154 return std::find_if(r.begin(), r.end(), [&t](T const& i) { return i != t; });