1/*
2 Copyright (c) Marshall Clow 2008-2012.
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8/// \file copy_if.hpp
9/// \brief Copy a subset of a sequence to a new sequence
10/// \author Marshall Clow
11
12#ifndef BOOST_ALGORITHM_COPY_IF_HPP
13#define BOOST_ALGORITHM_COPY_IF_HPP
14
15#include <algorithm> // for std::copy_if, if available
16#include <boost/range/begin.hpp>
17#include <boost/range/end.hpp>
18
19namespace boost { namespace algorithm {
20
21/// \fn copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
22/// \brief Copies all the elements from the input range that satisfy the
23/// predicate to the output range.
24/// \return The updated output iterator
25///
26/// \param first The start of the input sequence
27/// \param last One past the end of the input sequence
28/// \param result An output iterator to write the results into
29/// \param p A predicate for testing the elements of the range
30/// \note This function is part of the C++2011 standard library.
31/// We will use the standard one if it is available,
32/// otherwise we have our own implementation.
33template<typename InputIterator, typename OutputIterator, typename Predicate>
34OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
35{
36 for ( ; first != last; ++first )
37 if (p(*first))
38 *result++ = *first;
39 return result;
40}
41
42/// \fn copy_if ( const Range &r, OutputIterator result, Predicate p )
43/// \brief Copies all the elements from the input range that satisfy the
44/// predicate to the output range.
45/// \return The updated output iterator
46///
47/// \param r The input range
48/// \param result An output iterator to write the results into
49/// \param p A predicate for testing the elements of the range
50///
51template<typename Range, typename OutputIterator, typename Predicate>
52OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
53{
54 return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p);
55}
56
57
58/// \fn copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
59/// \brief Copies all the elements at the start of the input range that
60/// satisfy the predicate to the output range.
61/// \return The updated input and output iterators
62///
63/// \param first The start of the input sequence
64/// \param last One past the end of the input sequence
65/// \param result An output iterator to write the results into
66/// \param p A predicate for testing the elements of the range
67///
68template<typename InputIterator, typename OutputIterator, typename Predicate>
69std::pair<InputIterator, OutputIterator>
70copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
71{
72 for ( ; first != last && p(*first); ++first )
73 *result++ = *first;
74 return std::make_pair(first, result);
75}
76
77/// \fn copy_while ( const Range &r, OutputIterator result, Predicate p )
78/// \brief Copies all the elements at the start of the input range that
79/// satisfy the predicate to the output range.
80/// \return The updated input and output iterators
81///
82/// \param r The input range
83/// \param result An output iterator to write the results into
84/// \param p A predicate for testing the elements of the range
85///
86template<typename Range, typename OutputIterator, typename Predicate>
87std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
88copy_while ( const Range &r, OutputIterator result, Predicate p )
89{
90 return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p);
91}
92
93
94/// \fn copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
95/// \brief Copies all the elements at the start of the input range that do not
96/// satisfy the predicate to the output range.
97/// \return The updated output iterator
98///
99/// \param first The start of the input sequence
100/// \param last One past the end of the input sequence
101/// \param result An output iterator to write the results into
102/// \param p A predicate for testing the elements of the range
103///
104template<typename InputIterator, typename OutputIterator, typename Predicate>
105std::pair<InputIterator, OutputIterator>
106copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
107{
108 for ( ; first != last && !p(*first); ++first )
109 *result++ = *first;
110 return std::make_pair(first, result);
111}
112
113/// \fn copy_until ( const Range &r, OutputIterator result, Predicate p )
114/// \brief Copies all the elements at the start of the input range that do not
115/// satisfy the predicate to the output range.
116/// \return The updated output iterator
117///
118/// \param r The input range
119/// \param result An output iterator to write the results into
120/// \param p A predicate for testing the elements of the range
121///
122template<typename Range, typename OutputIterator, typename Predicate>
123std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
124copy_until ( const Range &r, OutputIterator result, Predicate p )
125{
126 return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);
127}
128
129}} // namespace boost and algorithm
130
131#endif // BOOST_ALGORITHM_COPY_IF_HPP
132