Skip to content

Commit eec00d8

Browse files
committed
Implement copy_if_while and copy_if_until
Problem: - There is no way to signal that a copy should proceed, selecting elements by a predicate until some condition is met. This is useful for patterns along the lines of "copy selected elements until there are n total elements in the output". Solution: - Introduce `copy_if_while()` and `copy_if_until()`.
1 parent da8ea58 commit eec00d8

File tree

3 files changed

+328
-7
lines changed

3 files changed

+328
-7
lines changed

doc/algorithm.qbk

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,24 @@ See below
206206

207207
[section:copy_until copy_until ]
208208
[*[^[link header.boost.algorithm.cxx11.copy_if_hpp copy_until] ] ]
209-
Copy all the elements at the start of the input range that do not satisfy the predicate to the output range
209+
Copy all the elements from the start of the input range to the output range until the predicate is satisfied
210210
[endsect:copy_until]
211211

212212
[section:copy_while copy_while ]
213213
[*[^[link header.boost.algorithm.cxx11.copy_if_hpp copy_while] ] ]
214-
Copy all the elements at the start of the input range that satisfy the predicate to the output range
214+
Copy all the elements from the start of the input range to the output range while the predicate is satisfied
215215
[endsect:copy_while]
216216

217+
[section:copy_if_until copy_if_until ]
218+
[*[^[link header.boost.algorithm.cxx11.copy_if_hpp copy_if_until ] ]
219+
Copy all elements that satisfy the element predicate from the start of the input range to the output range until the termination predicate is satisfied
220+
[endsect:copy_if_until]
221+
222+
[section:copy_if_while copy_if_while ]
223+
[*[^[link header.boost.algorithm.cxx11.copy_if_hpp copy_if_while ] ]
224+
Copy all elements that satisfy the element predicate from the start of the input range to the output range while the termination predicate is satisfied
225+
[endsect:copy_if_while]
226+
217227
[section:iota_n iota_n ]
218228
[*[^[link boost.algorithm.iota_n iota_n] ] ]
219229
Write a sequence of n increasing values to an output iterator

include/boost/algorithm/cxx11/copy_if.hpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,86 @@ copy_until ( const Range &r, OutputIterator result, Predicate p )
126126
return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);
127127
}
128128

129+
/// \fn copy_if_while ( InputIterator first, InputIterator last, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred )
130+
/// \brief Copies all the elements from the input range that satisfy the
131+
/// copy predicate to the output range while the termination predicate is
132+
/// satisfied.
133+
/// \return The updated output iterator
134+
///
135+
/// \param first The start of the input sequence
136+
/// \param last One past the end of the input sequence
137+
/// \param result An output iterator to write the results into
138+
/// \param copy_pred A predicate for testing whether to the current element
139+
/// \param term_pred A predicate for testing whether to end the copy operation
140+
template<typename InputIterator, typename OutputIterator, typename CopyPredicate, typename TerminatePred>
141+
BOOST_CXX14_CONSTEXPR std::pair<InputIterator, OutputIterator>
142+
copy_if_while ( InputIterator first, InputIterator last, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred)
143+
{
144+
for ( ; first != last && term_pred(*first); ++first ) {
145+
if (copy_pred(*first)) {
146+
*result++ = *first;
147+
}
148+
}
149+
return std::make_pair(first, result);
150+
}
151+
152+
/// \fn copy_if_while ( const Range& r, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred )
153+
/// \brief Copies all the elements from the input range that satisfy the
154+
/// copy predicate to the output range while the termination predicate is
155+
/// satisfied.
156+
/// \return The updated output iterator
157+
///
158+
/// \param r The input range
159+
/// \param result An output iterator to write the results into
160+
/// \param copy_pred A predicate for testing whether to the current element
161+
/// \param term_pred A predicate for testing whether to end the copy operation
162+
template<typename Range, typename OutputIterator, typename CopyPredicate, typename TerminatePred>
163+
BOOST_CXX14_CONSTEXPR std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
164+
copy_if_while ( const Range& r, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred)
165+
{
166+
return boost::algorithm::copy_if_while(boost::begin(r), boost::end(r), result, copy_pred, term_pred);
167+
}
168+
169+
/// \fn copy_if_until ( InputIterator first, InputIterator last, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred )
170+
/// \brief Copies all the elements from the input range that satisfy the
171+
/// copy predicate to the output range until the termination predicate is
172+
/// satisfied.
173+
/// \return The updated output iterator
174+
///
175+
/// \param first The start of the input sequence
176+
/// \param last One past the end of the input sequence
177+
/// \param result An output iterator to write the results into
178+
/// \param copy_pred A predicate for testing whether to the current element
179+
/// \param term_pred A predicate for testing whether to end the copy operation
180+
template<typename InputIterator, typename OutputIterator, typename CopyPredicate, typename TerminatePred>
181+
BOOST_CXX14_CONSTEXPR std::pair<InputIterator, OutputIterator>
182+
copy_if_until ( InputIterator first, InputIterator last, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred)
183+
{
184+
for ( ; first != last && !term_pred(*first); ++first ) {
185+
if (copy_pred(*first)) {
186+
*result++ = *first;
187+
}
188+
}
189+
return std::make_pair(first, result);
190+
}
191+
192+
/// \fn copy_if_until ( const Range& r, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred )
193+
/// \brief Copies all the elements from the input range that satisfy the
194+
/// copy predicate to the output range until the termination predicate is
195+
/// satisfied.
196+
/// \return The updated output iterator
197+
///
198+
/// \param r The input range
199+
/// \param result An output iterator to write the results into
200+
/// \param copy_pred A predicate for testing whether to the current element
201+
/// \param term_pred A predicate for testing whether to end the copy operation
202+
template<typename Range, typename OutputIterator, typename CopyPredicate, typename TerminatePred>
203+
BOOST_CXX14_CONSTEXPR std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
204+
copy_if_until ( const Range& r, OutputIterator result, CopyPredicate copy_pred, TerminatePred term_pred)
205+
{
206+
return boost::algorithm::copy_if_until(boost::begin(r), boost::end(r), result, copy_pred, term_pred);
207+
}
208+
129209
}} // namespace boost and algorithm
130210

131211
#endif // BOOST_ALGORITHM_COPY_IF_HPP

0 commit comments

Comments
 (0)